A Discrete-Event Network Simulator
API
epc-sgw-application.cc
Go to the documentation of this file.
1/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
2/*
3 * Copyright (c) 2017-2018 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: Manuel Requena <manuel.requena@cttc.es>
19 */
20
21#include "ns3/log.h"
22#include "ns3/epc-gtpu-header.h"
23#include "ns3/epc-sgw-application.h"
24
25namespace ns3 {
26
27NS_LOG_COMPONENT_DEFINE ("EpcSgwApplication");
28
29NS_OBJECT_ENSURE_REGISTERED (EpcSgwApplication);
30
32 const Ptr<Socket> s5uSocket, const Ptr<Socket> s5cSocket)
33 : m_s5Addr (s5Addr),
34 m_s5uSocket (s5uSocket),
35 m_s5cSocket (s5cSocket),
36 m_s1uSocket (s1uSocket),
37 m_gtpuUdpPort (2152), // fixed by the standard
38 m_gtpcUdpPort (2123), // fixed by the standard
39 m_teidCount (0)
40{
41 NS_LOG_FUNCTION (this << s1uSocket << s5Addr << s5uSocket << s5cSocket);
45}
46
48{
49 NS_LOG_FUNCTION (this);
50}
51
52void
54{
55 NS_LOG_FUNCTION (this);
57 m_s1uSocket = 0;
59 m_s5uSocket = 0;
61 m_s5cSocket = 0;
62}
63
66{
67 static TypeId tid = TypeId ("ns3::EpcSgwApplication")
68 .SetParent<Object> ()
69 .SetGroupName("Lte");
70 return tid;
71}
72
73
74void
76{
77 NS_LOG_FUNCTION (this << mmeS11Addr << s11Socket);
78 m_mmeS11Addr = mmeS11Addr;
79 m_s11Socket = s11Socket;
81}
82
83void
85{
86 NS_LOG_FUNCTION (this << pgwAddr);
87 m_pgwAddr = pgwAddr;
88}
89
90void
91EpcSgwApplication::AddEnb (uint16_t cellId, Ipv4Address enbAddr, Ipv4Address sgwAddr)
92{
93 NS_LOG_FUNCTION (this << cellId << enbAddr << sgwAddr);
94 EnbInfo enbInfo;
95 enbInfo.enbAddr = enbAddr;
96 enbInfo.sgwAddr = sgwAddr;
97 m_enbInfoByCellId[cellId] = enbInfo;
98}
99
100
101void
103{
104 NS_LOG_FUNCTION (this << socket);
105 NS_ASSERT (socket == m_s11Socket);
106 Ptr<Packet> packet = socket->Recv ();
107 GtpcHeader header;
108 packet->PeekHeader (header);
109 uint16_t msgType = header.GetMessageType ();
110
111 switch (msgType)
112 {
115 break;
116
119 break;
120
123 break;
124
127 break;
128
129 default:
130 NS_FATAL_ERROR ("GTP-C message not supported");
131 break;
132 }
133}
134
135
136void
138{
139 NS_LOG_FUNCTION (this << socket);
140 NS_ASSERT (socket == m_s5uSocket);
141 Ptr<Packet> packet = socket->Recv ();
142 GtpuHeader gtpu;
143 packet->RemoveHeader (gtpu);
144 uint32_t teid = gtpu.GetTeid ();
145
146 Ipv4Address enbAddr = m_enbByTeidMap[teid];
147 NS_LOG_DEBUG ("eNB " << enbAddr << " TEID " << teid);
148 SendToS1uSocket (packet, enbAddr, teid);
149}
150
151void
153{
154 NS_LOG_FUNCTION (this << socket);
155 NS_ASSERT (socket == m_s5cSocket);
156 Ptr<Packet> packet = socket->Recv ();
157 GtpcHeader header;
158 packet->PeekHeader (header);
159 uint16_t msgType = header.GetMessageType ();
160
161 switch (msgType)
162 {
165 break;
166
169 break;
170
173 break;
174
175 default:
176 NS_FATAL_ERROR ("GTP-C message not supported");
177 break;
178 }
179}
180
181void
183{
184 NS_LOG_FUNCTION (this << socket);
185 NS_ASSERT (socket == m_s1uSocket);
186 Ptr<Packet> packet = socket->Recv ();
187 GtpuHeader gtpu;
188 packet->RemoveHeader (gtpu);
189 uint32_t teid = gtpu.GetTeid ();
190
191 SendToS5uSocket (packet, m_pgwAddr, teid);
192}
193
194void
196{
197 NS_LOG_FUNCTION (this << packet << enbAddr << teid);
198
199 GtpuHeader gtpu;
200 gtpu.SetTeid (teid);
201 // From 3GPP TS 29.281 v10.0.0 Section 5.1
202 // Length of the payload + the non obligatory GTP-U header
203 gtpu.SetLength (packet->GetSize () + gtpu.GetSerializedSize () - 8);
204 packet->AddHeader (gtpu);
205 m_s1uSocket->SendTo (packet, 0, InetSocketAddress (enbAddr, m_gtpuUdpPort));
206}
207
208void
210{
211 NS_LOG_FUNCTION (this << packet << pgwAddr << teid);
212
213 GtpuHeader gtpu;
214 gtpu.SetTeid (teid);
215 // From 3GPP TS 29.281 v10.0.0 Section 5.1
216 // Length of the payload + the non obligatory GTP-U header
217 gtpu.SetLength (packet->GetSize () + gtpu.GetSerializedSize () - 8);
218 packet->AddHeader (gtpu);
219 m_s5uSocket->SendTo (packet, 0, InetSocketAddress (pgwAddr, m_gtpuUdpPort));
220}
221
222
224// Process messages from the MME
226
227void
229{
230 NS_LOG_FUNCTION (this);
231
233 packet->RemoveHeader (msg);
234 uint64_t imsi = msg.GetImsi ();
235 uint16_t cellId = msg.GetUliEcgi ();
236 NS_LOG_DEBUG ("cellId " << cellId << " IMSI " << imsi);
237
238 std::map<uint16_t, EnbInfo>::iterator enbit = m_enbInfoByCellId.find (cellId);
239 NS_ASSERT_MSG (enbit != m_enbInfoByCellId.end (), "unknown CellId " << cellId);
240 Ipv4Address enbAddr = enbit->second.enbAddr;
241 NS_LOG_DEBUG ("eNB " << enbAddr);
242
243 GtpcHeader::Fteid_t mmeS11Fteid = msg.GetSenderCpFteid ();
245 "wrong interface type");
246
248 msgOut.SetImsi (imsi);
249 msgOut.SetUliEcgi (cellId);
250
251 GtpcHeader::Fteid_t sgwS5cFteid;
253 sgwS5cFteid.teid = imsi;
254 m_mmeS11FteidBySgwS5cTeid[sgwS5cFteid.teid] = mmeS11Fteid;
255 sgwS5cFteid.addr = m_s5Addr;
256 msgOut.SetSenderCpFteid (sgwS5cFteid); // S5 SGW GTP-C TEID
257
258 std::list<GtpcCreateSessionRequestMessage::BearerContextToBeCreated> bearerContexts =
260 NS_LOG_DEBUG ("BearerContextToBeCreated size = " << bearerContexts.size ());
261 std::list<GtpcCreateSessionRequestMessage::BearerContextToBeCreated> bearerContextsOut;
262 for (auto &bearerContext : bearerContexts)
263 {
264 // simple sanity check. If you ever need more than 4M teids
265 // throughout your simulation, you'll need to implement a smarter teid
266 // management algorithm.
267 NS_ABORT_IF (m_teidCount == 0xFFFFFFFF);
268 uint32_t teid = ++m_teidCount;
269
270 NS_LOG_DEBUG (" TEID " << teid);
271 m_enbByTeidMap[teid] = enbAddr;
272
275 bearerContextOut.sgwS5uFteid.teid = teid; // S5U SGW FTEID
276 bearerContextOut.sgwS5uFteid.addr = enbit->second.sgwAddr;
277 bearerContextOut.epsBearerId = bearerContext.epsBearerId;
278 bearerContextOut.bearerLevelQos = bearerContext.bearerLevelQos;
279 bearerContextOut.tft = bearerContext.tft;
280 bearerContextsOut.push_back (bearerContextOut);
281 }
282
283 msgOut.SetBearerContextsToBeCreated (bearerContextsOut);
284
285 msgOut.SetTeid (0);
286 msgOut.ComputeMessageLength ();
287
288 Ptr<Packet> packetOut = Create <Packet> ();
289 packetOut->AddHeader (msgOut);
290 NS_LOG_DEBUG ("Send CreateSessionRequest to PGW " << m_pgwAddr);
292}
293
294void
296{
297 NS_LOG_FUNCTION (this);
298
300 packet->RemoveHeader (msg);
301 uint64_t imsi = msg.GetImsi ();
302 uint16_t cellId = msg.GetUliEcgi ();
303 NS_LOG_DEBUG ("cellId " << cellId << " IMSI " << imsi);
304
305 std::map<uint16_t, EnbInfo>::iterator enbit = m_enbInfoByCellId.find (cellId);
306 NS_ASSERT_MSG (enbit != m_enbInfoByCellId.end (), "unknown CellId " << cellId);
307 Ipv4Address enbAddr = enbit->second.enbAddr;
308 NS_LOG_DEBUG ("eNB " << enbAddr);
309
311 msgOut.SetImsi (imsi);
312 msgOut.SetUliEcgi (cellId);
313
314 std::list<GtpcModifyBearerRequestMessage::BearerContextToBeModified> bearerContextsOut;
315 std::list<GtpcModifyBearerRequestMessage::BearerContextToBeModified> bearerContexts
317 NS_LOG_DEBUG ("BearerContextsToBeModified size = " << bearerContexts.size ());
318 for (auto &bearerContext : bearerContexts)
319 {
320 NS_ASSERT_MSG (bearerContext.fteid.interfaceType == GtpcHeader::S1U_ENB_GTPU,
321 "Wrong FTEID in ModifyBearerRequest msg");
322 uint32_t teid = bearerContext.fteid.teid;
323 Ipv4Address enbAddr = bearerContext.fteid.addr;
324 NS_LOG_DEBUG ("bearerId " << (uint16_t)bearerContext.epsBearerId <<
325 " TEID " << teid);
326 std::map<uint32_t, Ipv4Address>::iterator addrit = m_enbByTeidMap.find (teid);
327 NS_ASSERT_MSG (addrit != m_enbByTeidMap.end (), "unknown TEID " << teid);
328 addrit->second = enbAddr;
330 bearerContextOut.epsBearerId = bearerContext.epsBearerId;
332 bearerContextOut.fteid.addr = m_s5Addr;
333 bearerContextOut.fteid.teid = bearerContext.fteid.teid;
334
335 bearerContextsOut.push_back (bearerContextOut);
336 }
337
338 msgOut.SetTeid (imsi);
339 msgOut.ComputeMessageLength ();
340
341 Ptr<Packet> packetOut = Create <Packet> ();
342 packetOut->AddHeader (msgOut);
343 NS_LOG_DEBUG ("Send ModifyBearerRequest to PGW " << m_pgwAddr);
345}
346
347void
349{
350 NS_LOG_FUNCTION (this);
351
353 packet->RemoveHeader (msg);
354
355 std::list<GtpcDeleteBearerCommandMessage::BearerContext> bearerContextsOut;
356 for (auto &bearerContext : msg.GetBearerContexts ())
357 {
358 NS_LOG_DEBUG ("ebid " << (uint16_t) bearerContext.m_epsBearerId);
360 bearerContextOut.m_epsBearerId = bearerContext.m_epsBearerId;
361 bearerContextsOut.push_back (bearerContextOut);
362 }
363
365 msgOut.SetBearerContexts (bearerContextsOut);
366 msgOut.SetTeid (msg.GetTeid ());
367 msgOut.ComputeMessageLength ();
368
369 Ptr<Packet> packetOut = Create <Packet> ();
370 packetOut->AddHeader (msgOut);
371 NS_LOG_DEBUG ("Send DeleteBearerCommand to PGW " << m_pgwAddr);
373}
374
375void
377{
378 NS_LOG_FUNCTION (this);
379
381 packet->RemoveHeader (msg);
383 msgOut.SetEpsBearerIds (msg.GetEpsBearerIds ());
384 msgOut.SetTeid (msg.GetTeid ());
385 msgOut.ComputeMessageLength ();
386
387 Ptr<Packet> packetOut = Create <Packet> ();
388 packetOut->AddHeader (msgOut);
389 NS_LOG_DEBUG ("Send DeleteBearerResponse to PGW " << m_pgwAddr);
391}
392
393
395// Process messages received from the PGW
397
398void
400{
401 NS_LOG_FUNCTION (this);
402
404 packet->RemoveHeader (msg);
405
406 GtpcHeader::Fteid_t pgwS5cFteid = msg.GetSenderCpFteid ();
408 "wrong interface type");
409
412
413 uint32_t teid = msg.GetTeid ();
415
416 std::list<GtpcCreateSessionResponseMessage::BearerContextCreated> bearerContexts =
418 NS_LOG_DEBUG ("BearerContextsCreated size = " << bearerContexts.size ());
419 std::list<GtpcCreateSessionResponseMessage::BearerContextCreated> bearerContextsOut;
420 for (auto &bearerContext : bearerContexts)
421 {
424 bearerContextOut.fteid.teid = bearerContext.fteid.teid;
425 bearerContextOut.fteid.addr = m_s5Addr;
426 bearerContextOut.epsBearerId = bearerContext.epsBearerId;
427 bearerContextOut.bearerLevelQos = bearerContext.bearerLevelQos;
428 bearerContextOut.tft = bearerContext.tft;
429 bearerContextsOut.push_back (bearerContext);
430 }
431 msgOut.SetBearerContextsCreated (bearerContextsOut);
432
433 msgOut.SetTeid (mmeS11Fteid.teid);
434 msgOut.ComputeMessageLength ();
435
436 Ptr<Packet> packetOut = Create <Packet> ();
437 packetOut->AddHeader (msgOut);
438 NS_LOG_DEBUG ("Send CreateSessionResponse to MME " << mmeS11Fteid.addr);
439 m_s11Socket->SendTo (packetOut, 0, InetSocketAddress (mmeS11Fteid.addr, m_gtpcUdpPort));
440}
441
442void
444{
445 NS_LOG_FUNCTION (this);
446
448 packet->RemoveHeader (msg);
449
452 msgOut.SetTeid (msg.GetTeid ());
453 msgOut.ComputeMessageLength ();
454
455 Ptr<Packet> packetOut = Create <Packet> ();
456 packetOut->AddHeader (msgOut);
457 NS_LOG_DEBUG ("Send ModifyBearerResponse to MME " << m_mmeS11Addr);
459}
460
461void
463{
464 NS_LOG_FUNCTION (this);
465
467 packet->RemoveHeader (msg);
468
470 msgOut.SetEpsBearerIds (msg.GetEpsBearerIds ());
471 msgOut.SetTeid (msg.GetTeid ());
472 msgOut.ComputeMessageLength ();
473
474 Ptr<Packet> packetOut = Create <Packet> ();
475 packetOut->AddHeader (msgOut);
476 NS_LOG_DEBUG ("Send DeleteBearerRequest to MME " << m_mmeS11Addr);
478}
479
480} // namespace ns3
Ptr< Socket > m_s5cSocket
UDP socket to send/receive GTP-C packets to/from the S5 interface.
void SendToS1uSocket(Ptr< Packet > packet, Ipv4Address enbS1uAddress, uint32_t teid)
Send a data packet to an eNB via the S1-U interface.
uint16_t m_gtpuUdpPort
UDP port to be used for GTP-U.
std::map< uint32_t, GtpcHeader::Fteid_t > m_mmeS11FteidBySgwS5cTeid
MME S11 FTEID by SGW S5C TEID.
static TypeId GetTypeId(void)
Get the type ID.
void DoRecvModifyBearerRequest(Ptr< Packet > packet)
Process GTP-C Modify Bearer Request message.
void DoRecvCreateSessionResponse(Ptr< Packet > packet)
Process GTP-C Create Session Response message.
Ipv4Address m_mmeS11Addr
MME address in the S11 interface.
void DoRecvDeleteBearerRequest(Ptr< Packet > packet)
Process GTP-C Delete Bearer Request message.
void AddMme(Ipv4Address mmeS11Addr, Ptr< Socket > s11Socket)
Let the SGW be aware of an MME.
virtual void DoDispose()
Destructor implementation.
void DoRecvDeleteBearerCommand(Ptr< Packet > packet)
Process GTP-C Delete Bearer Command message.
void RecvFromS5cSocket(Ptr< Socket > socket)
Method to be assigned to the recv callback of the S5-C socket.
void SendToS5uSocket(Ptr< Packet > packet, Ipv4Address pgwAddr, uint32_t teid)
Send a data packet to the PGW via the S5 interface.
void DoRecvCreateSessionRequest(Ptr< Packet > packet)
Process GTP-C Create Session Request message.
EpcSgwApplication(const Ptr< Socket > s1uSocket, Ipv4Address s5Addr, const Ptr< Socket > s5uSocket, const Ptr< Socket > s5cSocket)
Constructor that binds callback methods of sockets.
void AddPgw(Ipv4Address pgwAddr)
Let the SGW be aware of a PGW.
void RecvFromS5uSocket(Ptr< Socket > socket)
Method to be assigned to the recv callback of the S5-U socket.
std::map< uint32_t, Ipv4Address > m_enbByTeidMap
Map for eNB address by TEID.
Ptr< Socket > m_s1uSocket
UDP socket to send/receive GTP-U packets to/from the S1-U interface.
Ptr< Socket > m_s11Socket
UDP socket to send/receive control messages to/from the S11 interface.
virtual ~EpcSgwApplication(void)
Destructor.
std::map< uint16_t, EnbInfo > m_enbInfoByCellId
Map for eNB info by cell ID.
uint32_t m_teidCount
TEID count.
void RecvFromS11Socket(Ptr< Socket > socket)
Method to be assigned to the recv callback of the S11 socket.
Ipv4Address m_s5Addr
SGW address in the S5 interface.
uint16_t m_gtpcUdpPort
UDP port to be used for GTP-C.
void RecvFromS1uSocket(Ptr< Socket > socket)
Method to be assigned to the recv callback of the S1-U socket.
void DoRecvDeleteBearerResponse(Ptr< Packet > packet)
Process GTP-C Delete Bearer Response message.
Ptr< Socket > m_s5uSocket
UDP socket to send/receive GTP-U packets to/from the S5 interface.
Ipv4Address m_pgwAddr
PGW address in the S5 interface.
void DoRecvModifyBearerResponse(Ptr< Packet > packet)
Process GTP-C Modify Bearer Response message.
void AddEnb(uint16_t cellId, Ipv4Address enbAddr, Ipv4Address sgwAddr)
Let the SGW be aware of a new eNB.
GTP-C Create Session Request Message.
uint64_t GetImsi() const
Get the IMSI.
void SetUliEcgi(uint32_t uliEcgi)
Set the UliEcgi.
GtpcHeader::Fteid_t GetSenderCpFteid() const
Get the Sender CpFteid.
uint32_t GetUliEcgi() const
Get the UliEcgi.
void SetBearerContextsToBeCreated(std::list< BearerContextToBeCreated > bearerContexts)
Set the Bearer Contexts.
std::list< BearerContextToBeCreated > GetBearerContextsToBeCreated() const
Get the Bearer Contexts.
void SetImsi(uint64_t imsi)
Set the IMSI.
void SetSenderCpFteid(GtpcHeader::Fteid_t fteid)
Set the Sender CpFteid.
GTP-C Create Session Response Message.
void SetCause(Cause_t cause)
Set the Cause.
void SetBearerContextsCreated(std::list< BearerContextCreated > bearerContexts)
Set the Bearer Contexts.
std::list< BearerContextCreated > GetBearerContextsCreated() const
Get the Container of Bearer Contexts.
GtpcHeader::Fteid_t GetSenderCpFteid() const
Get the Sender CpFteid.
GTP-C Delete Bearer Command Message.
std::list< BearerContext > GetBearerContexts() const
Get the Bearer contexts.
void SetBearerContexts(std::list< BearerContext > bearerContexts)
Set the Bearer contexts.
GTP-C Delete Bearer Request Message.
std::list< uint8_t > GetEpsBearerIds() const
Get the Bearers IDs.
void SetEpsBearerIds(std::list< uint8_t > epsBearerIds)
Set the Bearers IDs.
GTP-C Delete Bearer Response Message.
std::list< uint8_t > GetEpsBearerIds() const
Get the Bearers IDs.
void SetEpsBearerIds(std::list< uint8_t > epsBearerIds)
Set the Bearers IDs.
Header of the GTPv2-C protocol.
void ComputeMessageLength(void)
Compute the message length according to the message type.
uint8_t GetMessageType() const
Get message type.
void SetTeid(uint32_t teid)
Set TEID.
uint32_t GetTeid() const
Get TEID.
GTP-C Modify Bearer Request Message.
uint64_t GetImsi() const
Get the IMSI.
uint32_t GetUliEcgi() const
Get the UliEcgi.
void SetUliEcgi(uint32_t uliEcgi)
Set the UliEcgi.
std::list< BearerContextToBeModified > GetBearerContextsToBeModified() const
Get the Bearer Contexts.
void SetImsi(uint64_t imsi)
Set the IMSI.
GTP-C Modify Bearer Response Message.
void SetCause(Cause_t cause)
Set the Cause.
Implementation of the GPRS Tunnelling Protocol header according to GTPv1-U Release 10 as per 3Gpp TS ...
void SetTeid(uint32_t teid)
Set TEID function.
virtual uint32_t GetSerializedSize(void) const
uint32_t GetTeid() const
Get a tunnel endpoint identificator (TEID)
void SetLength(uint16_t length)
Set the length in octets of the payload.
an Inet address class
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:41
A base class which provides memory management and object aggregation.
Definition: object.h:88
uint32_t RemoveHeader(Header &header)
Deserialize and remove the header from the internal buffer.
Definition: packet.cc:280
void AddHeader(const Header &header)
Add header to this packet.
Definition: packet.cc:256
uint32_t PeekHeader(Header &header) const
Deserialize but does not remove the header from the internal buffer.
Definition: packet.cc:290
uint32_t GetSize(void) const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:856
void SetRecvCallback(Callback< void, Ptr< Socket > > receivedData)
Notify application when new data is available to be read.
Definition: socket.cc:128
virtual Ptr< Packet > Recv(uint32_t maxSize, uint32_t flags)=0
Read data from the socket.
virtual int SendTo(Ptr< Packet > p, uint32_t flags, const Address &toAddress)=0
Send data to a specified peer.
a unique identifier for an interface.
Definition: type-id.h:59
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:922
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition: assert.h:67
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
Definition: assert.h:88
Callback< R, Ts... > MakeNullCallback(void)
Definition: callback.h:1688
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:165
#define NS_ABORT_IF(cond)
Abnormal program termination if a condition is true.
Definition: abort.h:77
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:205
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:273
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:45
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Callback< R, Ts... > MakeCallback(R(T::*memPtr)(Ts...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
Definition: callback.h:1648
Ptr< EpcTft > tft
Bearer traffic flow template.
Ipv4Address addr
IPv4 address.
InterfaceType_t interfaceType
Interface type.