A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
epc-x2.cc
Go to the documentation of this file.
1 /* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2012 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/inet-socket-address.h"
23 #include "ns3/packet.h"
24 #include "ns3/node.h"
25 #include "ns3/epc-gtpu-header.h"
26 
27 #include "ns3/epc-x2-header.h"
28 #include "ns3/epc-x2.h"
29 
30 NS_LOG_COMPONENT_DEFINE ("EpcX2");
31 
32 namespace ns3 {
33 
34 
35 X2IfaceInfo::X2IfaceInfo (Ipv4Address remoteIpAddr, Ptr<Socket> localCtrlPlaneSocket, Ptr<Socket> localUserPlaneSocket)
36 {
37  m_remoteIpAddr = remoteIpAddr;
38  m_localCtrlPlaneSocket = localCtrlPlaneSocket;
39  m_localUserPlaneSocket = localUserPlaneSocket;
40 }
41 
43 {
46 }
47 
50 {
51  NS_LOG_FUNCTION (this);
55  return *this;
56 }
57 
59 
60 X2CellInfo::X2CellInfo (uint16_t localCellId, uint16_t remoteCellId)
61 {
62  m_localCellId = localCellId;
63  m_remoteCellId = remoteCellId;
64 }
65 
67 {
68  m_localCellId = 0;
69  m_remoteCellId = 0;
70 }
71 
72 X2CellInfo&
74 {
75  NS_LOG_FUNCTION (this);
78  return *this;
79 }
80 
82 
84  ;
85 
87  : m_x2cUdpPort (4444),
88  m_x2uUdpPort (2152)
89 {
90  NS_LOG_FUNCTION (this);
91 
93 }
94 
96 {
97  NS_LOG_FUNCTION (this);
98 }
99 
100 void
102 {
103  NS_LOG_FUNCTION (this);
104 
105  m_x2InterfaceSockets.clear ();
106  m_x2InterfaceCellIds.clear ();
107  delete m_x2SapProvider;
108 }
109 
110 TypeId
112 {
113  static TypeId tid = TypeId ("ns3::EpcX2")
114  .SetParent<Object> ();
115  return tid;
116 }
117 
118 void
120 {
121  NS_LOG_FUNCTION (this << s);
122  m_x2SapUser = s;
123 }
124 
127 {
128  NS_LOG_FUNCTION (this);
129  return m_x2SapProvider;
130 }
131 
132 
133 void
134 EpcX2::AddX2Interface (uint16_t localCellId, Ipv4Address localX2Address, uint16_t remoteCellId, Ipv4Address remoteX2Address)
135 {
136  NS_LOG_FUNCTION (this << localCellId << localX2Address << remoteCellId << remoteX2Address);
137 
138  int retval;
139 
140  // Get local eNB where this X2 entity belongs to
141  Ptr<Node> localEnb = GetObject<Node> ();
142 
143  // Create X2-C socket for the local eNB
144  Ptr<Socket> localX2cSocket = Socket::CreateSocket (localEnb, TypeId::LookupByName ("ns3::UdpSocketFactory"));
145  retval = localX2cSocket->Bind (InetSocketAddress (localX2Address, m_x2cUdpPort));
146  NS_ASSERT (retval == 0);
147  localX2cSocket->SetRecvCallback (MakeCallback (&EpcX2::RecvFromX2cSocket, this));
148 
149  // Create X2-U socket for the local eNB
150  Ptr<Socket> localX2uSocket = Socket::CreateSocket (localEnb, TypeId::LookupByName ("ns3::UdpSocketFactory"));
151  retval = localX2uSocket->Bind (InetSocketAddress (localX2Address, m_x2uUdpPort));
152  NS_ASSERT (retval == 0);
153  localX2uSocket->SetRecvCallback (MakeCallback (&EpcX2::RecvFromX2uSocket, this));
154 
155 
156  NS_ASSERT_MSG (m_x2InterfaceSockets.find (remoteCellId) == m_x2InterfaceSockets.end (),
157  "Mapping for remoteCellId = " << remoteCellId << " is already known");
158  m_x2InterfaceSockets [remoteCellId] = Create<X2IfaceInfo> (remoteX2Address, localX2cSocket, localX2uSocket);
159 
160  NS_ASSERT_MSG (m_x2InterfaceCellIds.find (localX2cSocket) == m_x2InterfaceCellIds.end (),
161  "Mapping for control plane localSocket = " << localX2cSocket << " is already known");
162  m_x2InterfaceCellIds [localX2cSocket] = Create<X2CellInfo> (localCellId, remoteCellId);
163 
164  NS_ASSERT_MSG (m_x2InterfaceCellIds.find (localX2uSocket) == m_x2InterfaceCellIds.end (),
165  "Mapping for data plane localSocket = " << localX2uSocket << " is already known");
166  m_x2InterfaceCellIds [localX2uSocket] = Create<X2CellInfo> (localCellId, remoteCellId);
167 }
168 
169 
170 void
172 {
173  NS_LOG_FUNCTION (this << socket);
174 
175  NS_LOG_LOGIC ("Recv X2 message: from Socket");
176  Ptr<Packet> packet = socket->Recv ();
177  NS_LOG_LOGIC ("packetLen = " << packet->GetSize ());
178 
180  "Missing infos of local and remote CellId");
181  Ptr<X2CellInfo> cellsInfo = m_x2InterfaceCellIds [socket];
182 
183  EpcX2Header x2Header;
184  packet->RemoveHeader (x2Header);
185 
186  NS_LOG_LOGIC ("X2 header: " << x2Header);
187 
188  uint8_t messageType = x2Header.GetMessageType ();
189  uint8_t procedureCode = x2Header.GetProcedureCode ();
190 
191  if (procedureCode == EpcX2Header::HandoverPreparation)
192  {
193  if (messageType == EpcX2Header::InitiatingMessage)
194  {
195  NS_LOG_LOGIC ("Recv X2 message: HANDOVER REQUEST");
196 
197  EpcX2HandoverRequestHeader x2HoReqHeader;
198  packet->RemoveHeader (x2HoReqHeader);
199 
200  NS_LOG_INFO ("X2 HandoverRequest header: " << x2HoReqHeader);
201 
203  params.oldEnbUeX2apId = x2HoReqHeader.GetOldEnbUeX2apId ();
204  params.cause = x2HoReqHeader.GetCause ();
205  params.sourceCellId = cellsInfo->m_remoteCellId;
206  params.targetCellId = x2HoReqHeader.GetTargetCellId ();
207  params.mmeUeS1apId = x2HoReqHeader.GetMmeUeS1apId ();
210  params.bearers = x2HoReqHeader.GetBearers ();
211  params.rrcContext = packet;
212 
213  NS_LOG_LOGIC ("oldEnbUeX2apId = " << params.oldEnbUeX2apId);
214  NS_LOG_LOGIC ("sourceCellId = " << params.sourceCellId);
215  NS_LOG_LOGIC ("targetCellId = " << params.targetCellId);
216  NS_LOG_LOGIC ("mmeUeS1apId = " << params.mmeUeS1apId);
217  NS_LOG_LOGIC ("cellsInfo->m_localCellId = " << cellsInfo->m_localCellId);
218  NS_ASSERT_MSG (params.targetCellId == cellsInfo->m_localCellId,
219  "TargetCellId mismatches with localCellId");
220 
222  }
223  else if (messageType == EpcX2Header::SuccessfulOutcome)
224  {
225  NS_LOG_LOGIC ("Recv X2 message: HANDOVER REQUEST ACK");
226 
227  EpcX2HandoverRequestAckHeader x2HoReqAckHeader;
228  packet->RemoveHeader (x2HoReqAckHeader);
229 
230  NS_LOG_INFO ("X2 HandoverRequestAck header: " << x2HoReqAckHeader);
231 
233  params.oldEnbUeX2apId = x2HoReqAckHeader.GetOldEnbUeX2apId ();
234  params.newEnbUeX2apId = x2HoReqAckHeader.GetNewEnbUeX2apId ();
235  params.sourceCellId = cellsInfo->m_localCellId;
236  params.targetCellId = cellsInfo->m_remoteCellId;
237  params.admittedBearers = x2HoReqAckHeader.GetAdmittedBearers ();
238  params.notAdmittedBearers = x2HoReqAckHeader.GetNotAdmittedBearers ();
239  params.rrcContext = packet;
240 
241  NS_LOG_LOGIC ("oldEnbUeX2apId = " << params.oldEnbUeX2apId);
242  NS_LOG_LOGIC ("newEnbUeX2apId = " << params.newEnbUeX2apId);
243  NS_LOG_LOGIC ("sourceCellId = " << params.sourceCellId);
244  NS_LOG_LOGIC ("targetCellId = " << params.targetCellId);
245 
247  }
248  else // messageType == EpcX2Header::UnsuccessfulOutcome
249  {
250  NS_LOG_LOGIC ("Recv X2 message: HANDOVER PREPARATION FAILURE");
251 
252  EpcX2HandoverPreparationFailureHeader x2HoPrepFailHeader;
253  packet->RemoveHeader (x2HoPrepFailHeader);
254 
255  NS_LOG_INFO ("X2 HandoverPreparationFailure header: " << x2HoPrepFailHeader);
256 
258  params.oldEnbUeX2apId = x2HoPrepFailHeader.GetOldEnbUeX2apId ();
259  params.sourceCellId = cellsInfo->m_localCellId;
260  params.targetCellId = cellsInfo->m_remoteCellId;
261  params.cause = x2HoPrepFailHeader.GetCause ();
262  params.criticalityDiagnostics = x2HoPrepFailHeader.GetCriticalityDiagnostics ();
263 
264  NS_LOG_LOGIC ("oldEnbUeX2apId = " << params.oldEnbUeX2apId);
265  NS_LOG_LOGIC ("sourceCellId = " << params.sourceCellId);
266  NS_LOG_LOGIC ("targetCellId = " << params.targetCellId);
267  NS_LOG_LOGIC ("cause = " << params.cause);
268  NS_LOG_LOGIC ("criticalityDiagnostics = " << params.criticalityDiagnostics);
269 
271  }
272  }
273  else if (procedureCode == EpcX2Header::LoadIndication)
274  {
275  if (messageType == EpcX2Header::InitiatingMessage)
276  {
277  NS_LOG_LOGIC ("Recv X2 message: LOAD INFORMATION");
278 
279  EpcX2LoadInformationHeader x2LoadInfoHeader;
280  packet->RemoveHeader (x2LoadInfoHeader);
281 
282  NS_LOG_INFO ("X2 LoadInformation header: " << x2LoadInfoHeader);
283 
285  params.cellInformationList = x2LoadInfoHeader.GetCellInformationList ();
286 
287  NS_LOG_LOGIC ("cellInformationList size = " << params.cellInformationList.size ());
288 
290  }
291  }
292  else if (procedureCode == EpcX2Header::SnStatusTransfer)
293  {
294  if (messageType == EpcX2Header::InitiatingMessage)
295  {
296  NS_LOG_LOGIC ("Recv X2 message: SN STATUS TRANSFER");
297 
298  EpcX2SnStatusTransferHeader x2SnStatusXferHeader;
299  packet->RemoveHeader (x2SnStatusXferHeader);
300 
301  NS_LOG_INFO ("X2 SnStatusTransfer header: " << x2SnStatusXferHeader);
302 
304  params.oldEnbUeX2apId = x2SnStatusXferHeader.GetOldEnbUeX2apId ();
305  params.newEnbUeX2apId = x2SnStatusXferHeader.GetNewEnbUeX2apId ();
306  params.sourceCellId = cellsInfo->m_remoteCellId;
307  params.targetCellId = cellsInfo->m_localCellId;
309 
310  NS_LOG_LOGIC ("oldEnbUeX2apId = " << params.oldEnbUeX2apId);
311  NS_LOG_LOGIC ("newEnbUeX2apId = " << params.newEnbUeX2apId);
312  NS_LOG_LOGIC ("sourceCellId = " << params.sourceCellId);
313  NS_LOG_LOGIC ("targetCellId = " << params.targetCellId);
314  NS_LOG_LOGIC ("erabsList size = " << params.erabsSubjectToStatusTransferList.size ());
315 
317  }
318  }
319  else if (procedureCode == EpcX2Header::UeContextRelease)
320  {
321  if (messageType == EpcX2Header::InitiatingMessage)
322  {
323  NS_LOG_LOGIC ("Recv X2 message: UE CONTEXT RELEASE");
324 
325  EpcX2UeContextReleaseHeader x2UeCtxReleaseHeader;
326  packet->RemoveHeader (x2UeCtxReleaseHeader);
327 
328  NS_LOG_INFO ("X2 UeContextRelease header: " << x2UeCtxReleaseHeader);
329 
331  params.oldEnbUeX2apId = x2UeCtxReleaseHeader.GetOldEnbUeX2apId ();
332  params.newEnbUeX2apId = x2UeCtxReleaseHeader.GetNewEnbUeX2apId ();
333 
334  NS_LOG_LOGIC ("oldEnbUeX2apId = " << params.oldEnbUeX2apId);
335  NS_LOG_LOGIC ("newEnbUeX2apId = " << params.newEnbUeX2apId);
336 
338  }
339  }
340  else if (procedureCode == EpcX2Header::ResourceStatusReporting)
341  {
342  if (messageType == EpcX2Header::InitiatingMessage)
343  {
344  NS_LOG_LOGIC ("Recv X2 message: RESOURCE STATUS UPDATE");
345 
346  EpcX2ResourceStatusUpdateHeader x2ResStatUpdHeader;
347  packet->RemoveHeader (x2ResStatUpdHeader);
348 
349  NS_LOG_INFO ("X2 ResourceStatusUpdate header: " << x2ResStatUpdHeader);
350 
352  params.enb1MeasurementId = x2ResStatUpdHeader.GetEnb1MeasurementId ();
353  params.enb2MeasurementId = x2ResStatUpdHeader.GetEnb2MeasurementId ();
354  params.cellMeasurementResultList = x2ResStatUpdHeader.GetCellMeasurementResultList ();
355 
356  NS_LOG_LOGIC ("enb1MeasurementId = " << params.enb1MeasurementId);
357  NS_LOG_LOGIC ("enb2MeasurementId = " << params.enb2MeasurementId);
358  NS_LOG_LOGIC ("cellMeasurementResultList size = " << params.cellMeasurementResultList.size ());
359 
361  }
362  }
363  else
364  {
365  NS_ASSERT_MSG (false, "ProcedureCode NOT SUPPORTED!!!");
366  }
367 }
368 
369 
370 void
372 {
373  NS_LOG_FUNCTION (this << socket);
374 
375  NS_LOG_LOGIC ("Recv UE DATA through X2-U interface from Socket");
376  Ptr<Packet> packet = socket->Recv ();
377  NS_LOG_LOGIC ("packetLen = " << packet->GetSize ());
378 
380  "Missing infos of local and remote CellId");
381  Ptr<X2CellInfo> cellsInfo = m_x2InterfaceCellIds [socket];
382 
383  GtpuHeader gtpu;
384  packet->RemoveHeader (gtpu);
385 
386  NS_LOG_LOGIC ("GTP-U header: " << gtpu);
387 
389  params.sourceCellId = cellsInfo->m_remoteCellId;
390  params.targetCellId = cellsInfo->m_localCellId;
391  params.gtpTeid = gtpu.GetTeid ();
392  params.ueData = packet;
393 
394  m_x2SapUser->RecvUeData (params);
395 }
396 
397 
398 //
399 // Implementation of the X2 SAP Provider
400 //
401 void
403 {
404  NS_LOG_FUNCTION (this);
405 
406  NS_LOG_LOGIC ("oldEnbUeX2apId = " << params.oldEnbUeX2apId);
407  NS_LOG_LOGIC ("sourceCellId = " << params.sourceCellId);
408  NS_LOG_LOGIC ("targetCellId = " << params.targetCellId);
409  NS_LOG_LOGIC ("mmeUeS1apId = " << params.mmeUeS1apId);
410 
412  "Missing infos for targetCellId = " << params.targetCellId);
413  Ptr<X2IfaceInfo> socketInfo = m_x2InterfaceSockets [params.targetCellId];
414  Ptr<Socket> sourceSocket = socketInfo->m_localCtrlPlaneSocket;
415  Ipv4Address targetIpAddr = socketInfo->m_remoteIpAddr;
416 
417  NS_LOG_LOGIC ("sourceSocket = " << sourceSocket);
418  NS_LOG_LOGIC ("targetIpAddr = " << targetIpAddr);
419 
420  NS_LOG_INFO ("Send X2 message: HANDOVER REQUEST");
421 
422  // Build the X2 message
423  EpcX2HandoverRequestHeader x2HoReqHeader;
424  x2HoReqHeader.SetOldEnbUeX2apId (params.oldEnbUeX2apId);
425  x2HoReqHeader.SetCause (params.cause);
426  x2HoReqHeader.SetTargetCellId (params.targetCellId);
427  x2HoReqHeader.SetMmeUeS1apId (params.mmeUeS1apId);
430  x2HoReqHeader.SetBearers (params.bearers);
431 
432  EpcX2Header x2Header;
435  x2Header.SetLengthOfIes (x2HoReqHeader.GetLengthOfIes ());
436  x2Header.SetNumberOfIes (x2HoReqHeader.GetNumberOfIes ());
437 
438  NS_LOG_INFO ("X2 header: " << x2Header);
439  NS_LOG_INFO ("X2 HandoverRequest header: " << x2HoReqHeader);
440 
441  // Build the X2 packet
442  Ptr<Packet> packet = (params.rrcContext != 0) ? (params.rrcContext) : (Create <Packet> ());
443  packet->AddHeader (x2HoReqHeader);
444  packet->AddHeader (x2Header);
445  NS_LOG_INFO ("packetLen = " << packet->GetSize ());
446 
447  // Send the X2 message through the socket
448  sourceSocket->SendTo (packet, 0, InetSocketAddress (targetIpAddr, m_x2cUdpPort));
449 }
450 
451 
452 void
454 {
455  NS_LOG_FUNCTION (this);
456 
457  NS_LOG_LOGIC ("oldEnbUeX2apId = " << params.oldEnbUeX2apId);
458  NS_LOG_LOGIC ("newEnbUeX2apId = " << params.newEnbUeX2apId);
459  NS_LOG_LOGIC ("sourceCellId = " << params.sourceCellId);
460  NS_LOG_LOGIC ("targetCellId = " << params.targetCellId);
461 
463  "Socket infos not defined for sourceCellId = " << params.sourceCellId);
464 
465  Ptr<Socket> localSocket = m_x2InterfaceSockets [params.sourceCellId]->m_localCtrlPlaneSocket;
466  Ipv4Address remoteIpAddr = m_x2InterfaceSockets [params.sourceCellId]->m_remoteIpAddr;
467 
468  NS_LOG_LOGIC ("localSocket = " << localSocket);
469  NS_LOG_LOGIC ("remoteIpAddr = " << remoteIpAddr);
470 
471  NS_LOG_INFO ("Send X2 message: HANDOVER REQUEST ACK");
472 
473  // Build the X2 message
474  EpcX2HandoverRequestAckHeader x2HoAckHeader;
475  x2HoAckHeader.SetOldEnbUeX2apId (params.oldEnbUeX2apId);
476  x2HoAckHeader.SetNewEnbUeX2apId (params.newEnbUeX2apId);
477  x2HoAckHeader.SetAdmittedBearers (params.admittedBearers);
478  x2HoAckHeader.SetNotAdmittedBearers (params.notAdmittedBearers);
479 
480  EpcX2Header x2Header;
483  x2Header.SetLengthOfIes (x2HoAckHeader.GetLengthOfIes ());
484  x2Header.SetNumberOfIes (x2HoAckHeader.GetNumberOfIes ());
485 
486  NS_LOG_INFO ("X2 header: " << x2Header);
487  NS_LOG_INFO ("X2 HandoverAck header: " << x2HoAckHeader);
488  NS_LOG_INFO ("RRC context: " << params.rrcContext);
489 
490  // Build the X2 packet
491  Ptr<Packet> packet = (params.rrcContext != 0) ? (params.rrcContext) : (Create <Packet> ());
492  packet->AddHeader (x2HoAckHeader);
493  packet->AddHeader (x2Header);
494  NS_LOG_INFO ("packetLen = " << packet->GetSize ());
495 
496  // Send the X2 message through the socket
497  localSocket->SendTo (packet, 0, InetSocketAddress (remoteIpAddr, m_x2cUdpPort));
498 }
499 
500 
501 void
503 {
504  NS_LOG_FUNCTION (this);
505 
506  NS_LOG_LOGIC ("oldEnbUeX2apId = " << params.oldEnbUeX2apId);
507  NS_LOG_LOGIC ("sourceCellId = " << params.sourceCellId);
508  NS_LOG_LOGIC ("targetCellId = " << params.targetCellId);
509  NS_LOG_LOGIC ("cause = " << params.cause);
510  NS_LOG_LOGIC ("criticalityDiagnostics = " << params.criticalityDiagnostics);
511 
513  "Socket infos not defined for sourceCellId = " << params.sourceCellId);
514 
515  Ptr<Socket> localSocket = m_x2InterfaceSockets [params.sourceCellId]->m_localCtrlPlaneSocket;
516  Ipv4Address remoteIpAddr = m_x2InterfaceSockets [params.sourceCellId]->m_remoteIpAddr;
517 
518  NS_LOG_LOGIC ("localSocket = " << localSocket);
519  NS_LOG_LOGIC ("remoteIpAddr = " << remoteIpAddr);
520 
521  NS_LOG_INFO ("Send X2 message: HANDOVER PREPARATION FAILURE");
522 
523  // Build the X2 message
524  EpcX2HandoverPreparationFailureHeader x2HoPrepFailHeader;
525  x2HoPrepFailHeader.SetOldEnbUeX2apId (params.oldEnbUeX2apId);
526  x2HoPrepFailHeader.SetCause (params.cause);
527  x2HoPrepFailHeader.SetCriticalityDiagnostics (params.criticalityDiagnostics);
528 
529  EpcX2Header x2Header;
532  x2Header.SetLengthOfIes (x2HoPrepFailHeader.GetLengthOfIes ());
533  x2Header.SetNumberOfIes (x2HoPrepFailHeader.GetNumberOfIes ());
534 
535  NS_LOG_INFO ("X2 header: " << x2Header);
536  NS_LOG_INFO ("X2 HandoverPrepFail header: " << x2HoPrepFailHeader);
537 
538  // Build the X2 packet
539  Ptr<Packet> packet = Create <Packet> ();
540  packet->AddHeader (x2HoPrepFailHeader);
541  packet->AddHeader (x2Header);
542  NS_LOG_INFO ("packetLen = " << packet->GetSize ());
543 
544  // Send the X2 message through the socket
545  localSocket->SendTo (packet, 0, InetSocketAddress (remoteIpAddr, m_x2cUdpPort));
546 }
547 
548 
549 void
551 {
552  NS_LOG_FUNCTION (this);
553 
554  NS_LOG_LOGIC ("oldEnbUeX2apId = " << params.oldEnbUeX2apId);
555  NS_LOG_LOGIC ("newEnbUeX2apId = " << params.newEnbUeX2apId);
556  NS_LOG_LOGIC ("sourceCellId = " << params.sourceCellId);
557  NS_LOG_LOGIC ("targetCellId = " << params.targetCellId);
558  NS_LOG_LOGIC ("erabsList size = " << params.erabsSubjectToStatusTransferList.size ());
559 
561  "Socket infos not defined for targetCellId = " << params.targetCellId);
562 
563  Ptr<Socket> localSocket = m_x2InterfaceSockets [params.targetCellId]->m_localCtrlPlaneSocket;
564  Ipv4Address remoteIpAddr = m_x2InterfaceSockets [params.targetCellId]->m_remoteIpAddr;
565 
566  NS_LOG_LOGIC ("localSocket = " << localSocket);
567  NS_LOG_LOGIC ("remoteIpAddr = " << remoteIpAddr);
568 
569  NS_LOG_INFO ("Send X2 message: SN STATUS TRANSFER");
570 
571  // Build the X2 message
572  EpcX2SnStatusTransferHeader x2SnStatusXferHeader;
573  x2SnStatusXferHeader.SetOldEnbUeX2apId (params.oldEnbUeX2apId);
574  x2SnStatusXferHeader.SetNewEnbUeX2apId (params.newEnbUeX2apId);
576 
577  EpcX2Header x2Header;
580  x2Header.SetLengthOfIes (x2SnStatusXferHeader.GetLengthOfIes ());
581  x2Header.SetNumberOfIes (x2SnStatusXferHeader.GetNumberOfIes ());
582 
583  NS_LOG_INFO ("X2 header: " << x2Header);
584  NS_LOG_INFO ("X2 SnStatusTransfer header: " << x2SnStatusXferHeader);
585 
586  // Build the X2 packet
587  Ptr<Packet> packet = Create <Packet> ();
588  packet->AddHeader (x2SnStatusXferHeader);
589  packet->AddHeader (x2Header);
590  NS_LOG_INFO ("packetLen = " << packet->GetSize ());
591 
592  // Send the X2 message through the socket
593  localSocket->SendTo (packet, 0, InetSocketAddress (remoteIpAddr, m_x2cUdpPort));
594 }
595 
596 
597 void
599 {
600  NS_LOG_FUNCTION (this);
601 
602  NS_LOG_LOGIC ("oldEnbUeX2apId = " << params.oldEnbUeX2apId);
603  NS_LOG_LOGIC ("newEnbUeX2apId = " << params.newEnbUeX2apId);
604  NS_LOG_LOGIC ("sourceCellId = " << params.sourceCellId);
605 
607  "Socket infos not defined for sourceCellId = " << params.sourceCellId);
608 
609  Ptr<Socket> localSocket = m_x2InterfaceSockets [params.sourceCellId]->m_localCtrlPlaneSocket;
610  Ipv4Address remoteIpAddr = m_x2InterfaceSockets [params.sourceCellId]->m_remoteIpAddr;
611 
612  NS_LOG_LOGIC ("localSocket = " << localSocket);
613  NS_LOG_LOGIC ("remoteIpAddr = " << remoteIpAddr);
614 
615  NS_LOG_INFO ("Send X2 message: UE CONTEXT RELEASE");
616 
617  // Build the X2 message
618  EpcX2UeContextReleaseHeader x2UeCtxReleaseHeader;
619  x2UeCtxReleaseHeader.SetOldEnbUeX2apId (params.oldEnbUeX2apId);
620  x2UeCtxReleaseHeader.SetNewEnbUeX2apId (params.newEnbUeX2apId);
621 
622  EpcX2Header x2Header;
625  x2Header.SetLengthOfIes (x2UeCtxReleaseHeader.GetLengthOfIes ());
626  x2Header.SetNumberOfIes (x2UeCtxReleaseHeader.GetNumberOfIes ());
627 
628  NS_LOG_INFO ("X2 header: " << x2Header);
629  NS_LOG_INFO ("X2 UeContextRelease header: " << x2UeCtxReleaseHeader);
630 
631  // Build the X2 packet
632  Ptr<Packet> packet = Create <Packet> ();
633  packet->AddHeader (x2UeCtxReleaseHeader);
634  packet->AddHeader (x2Header);
635  NS_LOG_INFO ("packetLen = " << packet->GetSize ());
636 
637  // Send the X2 message through the socket
638  localSocket->SendTo (packet, 0, InetSocketAddress (remoteIpAddr, m_x2cUdpPort));
639 }
640 
641 
642 void
644 {
645  NS_LOG_FUNCTION (this);
646 
647  NS_LOG_LOGIC ("targetCellId = " << params.targetCellId);
648  NS_LOG_LOGIC ("cellInformationList size = " << params.cellInformationList.size ());
649 
651  "Missing infos for targetCellId = " << params.targetCellId);
652  Ptr<X2IfaceInfo> socketInfo = m_x2InterfaceSockets [params.targetCellId];
653  Ptr<Socket> sourceSocket = socketInfo->m_localCtrlPlaneSocket;
654  Ipv4Address targetIpAddr = socketInfo->m_remoteIpAddr;
655 
656  NS_LOG_LOGIC ("sourceSocket = " << sourceSocket);
657  NS_LOG_LOGIC ("targetIpAddr = " << targetIpAddr);
658 
659  NS_LOG_INFO ("Send X2 message: LOAD INFORMATION");
660 
661  // Build the X2 message
662  EpcX2LoadInformationHeader x2LoadInfoHeader;
663  x2LoadInfoHeader.SetCellInformationList (params.cellInformationList);
664 
665  EpcX2Header x2Header;
668  x2Header.SetLengthOfIes (x2LoadInfoHeader.GetLengthOfIes ());
669  x2Header.SetNumberOfIes (x2LoadInfoHeader.GetNumberOfIes ());
670 
671  NS_LOG_INFO ("X2 header: " << x2Header);
672  NS_LOG_INFO ("X2 LoadInformation header: " << x2LoadInfoHeader);
673 
674  // Build the X2 packet
675  Ptr<Packet> packet = Create <Packet> ();
676  packet->AddHeader (x2LoadInfoHeader);
677  packet->AddHeader (x2Header);
678  NS_LOG_INFO ("packetLen = " << packet->GetSize ());
679 
680  // Send the X2 message through the socket
681  sourceSocket->SendTo (packet, 0, InetSocketAddress (targetIpAddr, m_x2cUdpPort));
682 
683 }
684 
685 
686 void
688 {
689  NS_LOG_FUNCTION (this);
690 
691  NS_LOG_LOGIC ("targetCellId = " << params.targetCellId);
692  NS_LOG_LOGIC ("enb1MeasurementId = " << params.enb1MeasurementId);
693  NS_LOG_LOGIC ("enb2MeasurementId = " << params.enb2MeasurementId);
694  NS_LOG_LOGIC ("cellMeasurementResultList size = " << params.cellMeasurementResultList.size ());
695 
697  "Missing infos for targetCellId = " << params.targetCellId);
698  Ptr<X2IfaceInfo> socketInfo = m_x2InterfaceSockets [params.targetCellId];
699  Ptr<Socket> sourceSocket = socketInfo->m_localCtrlPlaneSocket;
700  Ipv4Address targetIpAddr = socketInfo->m_remoteIpAddr;
701 
702  NS_LOG_LOGIC ("sourceSocket = " << sourceSocket);
703  NS_LOG_LOGIC ("targetIpAddr = " << targetIpAddr);
704 
705  NS_LOG_INFO ("Send X2 message: RESOURCE STATUS UPDATE");
706 
707  // Build the X2 message
708  EpcX2ResourceStatusUpdateHeader x2ResourceStatUpdHeader;
709  x2ResourceStatUpdHeader.SetEnb1MeasurementId (params.enb1MeasurementId);
710  x2ResourceStatUpdHeader.SetEnb2MeasurementId (params.enb2MeasurementId);
711  x2ResourceStatUpdHeader.SetCellMeasurementResultList (params.cellMeasurementResultList);
712 
713  EpcX2Header x2Header;
716  x2Header.SetLengthOfIes (x2ResourceStatUpdHeader.GetLengthOfIes ());
717  x2Header.SetNumberOfIes (x2ResourceStatUpdHeader.GetNumberOfIes ());
718 
719  NS_LOG_INFO ("X2 header: " << x2Header);
720  NS_LOG_INFO ("X2 ResourceStatusUpdate header: " << x2ResourceStatUpdHeader);
721 
722  // Build the X2 packet
723  Ptr<Packet> packet = Create <Packet> ();
724  packet->AddHeader (x2ResourceStatUpdHeader);
725  packet->AddHeader (x2Header);
726  NS_LOG_INFO ("packetLen = " << packet->GetSize ());
727 
728  // Send the X2 message through the socket
729  sourceSocket->SendTo (packet, 0, InetSocketAddress (targetIpAddr, m_x2cUdpPort));
730 
731 }
732 
733 
734 void
736 {
737  NS_LOG_FUNCTION (this);
738 
739  NS_LOG_LOGIC ("sourceCellId = " << params.sourceCellId);
740  NS_LOG_LOGIC ("targetCellId = " << params.targetCellId);
741  NS_LOG_LOGIC ("gtpTeid = " << params.gtpTeid);
742 
744  "Missing infos for targetCellId = " << params.targetCellId);
745  Ptr<X2IfaceInfo> socketInfo = m_x2InterfaceSockets [params.targetCellId];
746  Ptr<Socket> sourceSocket = socketInfo->m_localUserPlaneSocket;
747  Ipv4Address targetIpAddr = socketInfo->m_remoteIpAddr;
748 
749  NS_LOG_LOGIC ("sourceSocket = " << sourceSocket);
750  NS_LOG_LOGIC ("targetIpAddr = " << targetIpAddr);
751 
752  GtpuHeader gtpu;
753  gtpu.SetTeid (params.gtpTeid);
754  gtpu.SetLength (params.ueData->GetSize () + gtpu.GetSerializedSize () - 8);
755  NS_LOG_INFO ("GTP-U header: " << gtpu);
756 
757  Ptr<Packet> packet = params.ueData;
758  packet->AddHeader (gtpu);
759 
760  NS_LOG_INFO ("Forward UE DATA through X2 interface");
761  sourceSocket->SendTo (packet, 0, InetSocketAddress (targetIpAddr, m_x2uUdpPort));
762 }
763 
764 } // namespace ns3
void SetNumberOfIes(uint32_t numberOfIes)
uint32_t RemoveHeader(Header &header)
Deserialize and remove the header from the internal buffer.
Definition: packet.cc:268
virtual ~EpcX2(void)
Destructor.
Definition: epc-x2.cc:95
Doxygen introspection did not find any typical Config paths.
virtual void DoSendHandoverRequest(EpcX2SapProvider::HandoverRequestParams params)
Definition: epc-x2.cc:402
virtual ~X2IfaceInfo(void)
Definition: epc-x2.cc:42
an Inet address class
uint8_t GetMessageType() const
These service primitives of this part of the X2 SAP are provided by the X2 entity and issued by RRC e...
Definition: epc-x2-sap.h:340
#define NS_LOG_FUNCTION(parameters)
Definition: log.h:345
uint16_t GetOldEnbUeX2apId() const
uint16_t m_remoteCellId
Definition: epc-x2.h:61
void SetNewEnbUeX2apId(uint16_t x2apId)
Ptr< Socket > m_localUserPlaneSocket
Definition: epc-x2.h:47
void SetOldEnbUeX2apId(uint16_t x2apId)
X2CellInfo & operator=(const X2CellInfo &)
Definition: epc-x2.cc:73
std::vector< EpcX2Sap::ErabNotAdmittedItem > GetNotAdmittedBearers() const
std::vector< CellMeasurementResultItem > cellMeasurementResultList
Definition: epc-x2-sap.h:316
uint16_t m_localCellId
Definition: epc-x2.h:60
Doxygen introspection did not find any typical Config paths.
Definition: epc-x2-header.h:33
virtual void RecvUeContextRelease(UeContextReleaseParams params)=0
Parameters of the HANDOVER REQUEST message.
Definition: epc-x2-sap.h:225
void SetCause(uint16_t cause)
static TypeId GetTypeId(void)
Definition: epc-x2.cc:111
virtual void RecvSnStatusTransfer(SnStatusTransferParams params)=0
#define NS_ASSERT(condition)
Definition: assert.h:64
virtual void RecvHandoverRequest(HandoverRequestParams params)=0
Service primitives.
std::vector< EpcX2Sap::CellMeasurementResultItem > GetCellMeasurementResultList() const
NS_OBJECT_ENSURE_REGISTERED(NullMessageSimulatorImpl)
virtual void DoSendLoadInformation(EpcX2SapProvider::LoadInformationParams params)
Definition: epc-x2.cc:643
uint32_t GetSize(void) const
Definition: packet.h:650
uint16_t m_x2cUdpPort
UDP ports to be used for the X2 interfaces: X2-C and X2-U.
Definition: epc-x2.h:160
#define NS_LOG_INFO(msg)
Definition: log.h:298
void RecvFromX2uSocket(Ptr< Socket > socket)
Method to be assigned to the recv callback of the X2-U (X2 User Plane) socket.
Definition: epc-x2.cc:371
virtual ~X2CellInfo(void)
Definition: epc-x2.cc:66
virtual void DoSendUeData(EpcX2SapProvider::UeDataParams params)
Definition: epc-x2.cc:735
virtual void DoSendUeContextRelease(EpcX2SapProvider::UeContextReleaseParams params)
Definition: epc-x2.cc:598
std::vector< EpcX2Sap::ErabsSubjectToStatusTransferItem > GetErabsSubjectToStatusTransferList() const
void SetLengthOfIes(uint32_t lengthOfIes)
virtual void DoSendSnStatusTransfer(EpcX2SapProvider::SnStatusTransferParams params)
Definition: epc-x2.cc:550
Doxygen introspection did not find any typical Config paths.
uint64_t GetUeAggregateMaxBitRateUplink() const
std::vector< EpcX2Sap::ErabToBeSetupItem > GetBearers() const
uint16_t m_x2uUdpPort
Definition: epc-x2.h:161
Doxygen introspection did not find any typical Config paths.
Definition: epc-x2-header.h:80
virtual void DoSendResourceStatusUpdate(EpcX2SapProvider::ResourceStatusUpdateParams params)
Definition: epc-x2.cc:687
void SetTargetCellId(uint16_t targetCellId)
X2IfaceInfo & operator=(const X2IfaceInfo &)
Definition: epc-x2.cc:49
virtual uint32_t GetSerializedSize(void) const
void RecvFromX2cSocket(Ptr< Socket > socket)
Method to be assigned to the recv callback of the X2-C (X2 Control Plane) socket. ...
Definition: epc-x2.cc:171
void SetUeAggregateMaxBitRateUplink(uint64_t bitRate)
Parameters of the HANDOVER PREPARATION FAILURE message.
Definition: epc-x2-sap.h:259
Ptr< Socket > m_localCtrlPlaneSocket
Definition: epc-x2.h:46
void SetOldEnbUeX2apId(uint16_t x2apId)
Ptr< SampleEmitter > s
std::vector< ErabAdmittedItem > admittedBearers
Definition: epc-x2-sap.h:249
std::vector< CellInformationItem > cellInformationList
Definition: epc-x2-sap.h:303
Parameters of the SN STATUS TRANSFER message.
Definition: epc-x2-sap.h:273
virtual void DoSendHandoverRequestAck(EpcX2SapProvider::HandoverRequestAckParams params)
Definition: epc-x2.cc:453
Callback< R > MakeCallback(R(T::*memPtr)(void), OBJ objPtr)
Definition: callback.h:1238
void SetEnb1MeasurementId(uint16_t enb1MeasurementId)
Doxygen introspection did not find any typical Config paths.
Doxygen introspection did not find any typical Config paths.
void SetRecvCallback(Callback< void, Ptr< Socket > >)
Notify application when new data is available to be read.
Definition: socket.cc:128
static Ptr< Socket > CreateSocket(Ptr< Node > node, TypeId tid)
This method wraps the creation of sockets that is performed on a given node by a SocketFactory specif...
Definition: socket.cc:71
std::map< uint16_t, Ptr< X2IfaceInfo > > m_x2InterfaceSockets
Map the targetCellId to the corresponding (sourceSocket, remoteIpAddr) to be used to send the X2 mess...
Definition: epc-x2.h:149
EpcX2()
Constructor.
Definition: epc-x2.cc:86
X2IfaceInfo(Ipv4Address remoteIpAddr, Ptr< Socket > localCtrlPlaneSocket, Ptr< Socket > localUserPlaneSocket)
Definition: epc-x2.cc:35
#define NS_LOG_LOGIC(msg)
Definition: log.h:368
void SetUeAggregateMaxBitRateDownlink(uint64_t bitRate)
virtual void RecvHandoverPreparationFailure(HandoverPreparationFailureParams params)=0
uint8_t GetProcedureCode() const
X2CellInfo(uint16_t localCellId, uint16_t remoteCellId)
Definition: epc-x2.cc:60
virtual int Bind(const Address &address)=0
Allocate a local endpoint for this socket.
Parameters of the RESOURCE STATUS UPDATE message.
Definition: epc-x2-sap.h:311
This entity is installed inside an eNB and provides the functionality for the X2 interface.
Definition: epc-x2.h:70
void SetTeid(uint32_t m_teid)
virtual Ptr< Packet > Recv(uint32_t maxSize, uint32_t flags)=0
Read data from the socket.
Parameters of the UE CONTEXT RELEASE message.
Definition: epc-x2-sap.h:287
void SetNotAdmittedBearers(std::vector< EpcX2Sap::ErabNotAdmittedItem > bearers)
Parameters of the HANDOVER REQUEST ACKNOWLEDGE message.
Definition: epc-x2-sap.h:243
void SetProcedureCode(uint8_t procedureCode)
These service primitives of this part of the X2 SAP are provided by the RRC entity and issued by the ...
Definition: epc-x2-sap.h:371
void SetNewEnbUeX2apId(uint16_t x2apId)
virtual void RecvUeData(UeDataParams params)=0
uint32_t GetTeid() const
std::vector< ErabToBeSetupItem > bearers
Definition: epc-x2-sap.h:234
EpcX2SapUser * m_x2SapUser
Definition: epc-x2.h:139
NS_LOG_COMPONENT_DEFINE("EpcX2")
#define NS_ASSERT_MSG(condition, message)
Definition: assert.h:86
virtual void DoSendHandoverPreparationFailure(EpcX2SapProvider::HandoverPreparationFailureParams params)
Definition: epc-x2.cc:502
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:38
EpcX2SapProvider * GetEpcX2SapProvider()
Definition: epc-x2.cc:126
std::vector< EpcX2Sap::CellInformationItem > GetCellInformationList() const
void SetEpcX2SapUser(EpcX2SapUser *s)
Definition: epc-x2.cc:119
void SetErabsSubjectToStatusTransferList(std::vector< EpcX2Sap::ErabsSubjectToStatusTransferItem > erabs)
std::vector< ErabNotAdmittedItem > notAdmittedBearers
Definition: epc-x2-sap.h:250
Doxygen introspection did not find any typical Config paths.
void SetNewEnbUeX2apId(uint16_t x2apId)
Parameters of the LOAD INFORMATION message.
Definition: epc-x2-sap.h:300
void SetLength(uint16_t m_length)
void SetEnb2MeasurementId(uint16_t enb2MeasurementId)
void SetCellInformationList(std::vector< EpcX2Sap::CellInformationItem > cellInformationList)
void SetAdmittedBearers(std::vector< EpcX2Sap::ErabAdmittedItem > bearers)
virtual int SendTo(Ptr< Packet > p, uint32_t flags, const Address &toAddress)=0
Send data to a specified peer.
void SetBearers(std::vector< EpcX2Sap::ErabToBeSetupItem > bearers)
std::vector< EpcX2Sap::ErabAdmittedItem > GetAdmittedBearers() const
uint64_t GetUeAggregateMaxBitRateDownlink() const
EpcX2SapProvider * m_x2SapProvider
Definition: epc-x2.h:140
void SetOldEnbUeX2apId(uint16_t x2apId)
std::map< Ptr< Socket >, Ptr< X2CellInfo > > m_x2InterfaceCellIds
Map the localSocket (the one receiving the X2 message) to the corresponding (sourceCellId, targetCellId) associated with the X2 interface.
Definition: epc-x2.h:155
a base class which provides memory management and object aggregation
Definition: object.h:63
virtual void RecvLoadInformation(LoadInformationParams params)=0
Doxygen introspection did not find any typical Config paths.
void AddX2Interface(uint16_t enb1CellId, Ipv4Address enb1X2Address, uint16_t enb2CellId, Ipv4Address enb2X2Address)
Add an X2 interface to this EPC X2 entity.
Definition: epc-x2.cc:134
void SetOldEnbUeX2apId(uint16_t x2apId)
virtual void DoDispose(void)
This method is called by Object::Dispose or by the object's destructor, whichever comes first...
Definition: epc-x2.cc:101
virtual void RecvHandoverRequestAck(HandoverRequestAckParams params)=0
Parameters of the UE DATA primitive.
Definition: epc-x2-sap.h:325
Ipv4Address m_remoteIpAddr
Definition: epc-x2.h:45
std::vector< ErabsSubjectToStatusTransferItem > erabsSubjectToStatusTransferList
Definition: epc-x2-sap.h:279
a unique identifier for an interface.
Definition: type-id.h:49
void SetCriticalityDiagnostics(uint16_t criticalityDiagnostics)
TypeId SetParent(TypeId tid)
Definition: type-id.cc:611
void SetCellMeasurementResultList(std::vector< EpcX2Sap::CellMeasurementResultItem > cellMeasurementResultList)
void AddHeader(const Header &header)
Add header to this packet.
Definition: packet.cc:253
virtual void RecvResourceStatusUpdate(ResourceStatusUpdateParams params)=0
void SetMessageType(uint8_t messageType)
static TypeId LookupByName(std::string name)
Definition: type-id.cc:536
Implementation of the GTPv1-U Release 10 as per 3Gpp TS 29.281 document.
void SetMmeUeS1apId(uint32_t mmeUeS1apId)