A Discrete-Event Network Simulator
API
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 namespace ns3 {
31 
32 NS_LOG_COMPONENT_DEFINE ("EpcX2");
33 
34 X2IfaceInfo::X2IfaceInfo (Ipv4Address remoteIpAddr, Ptr<Socket> localCtrlPlaneSocket, Ptr<Socket> localUserPlaneSocket)
35 {
36  m_remoteIpAddr = remoteIpAddr;
37  m_localCtrlPlaneSocket = localCtrlPlaneSocket;
38  m_localUserPlaneSocket = localUserPlaneSocket;
39 }
40 
42 {
45 }
46 
49 {
50  NS_LOG_FUNCTION (this);
54  return *this;
55 }
56 
58 
59 X2CellInfo::X2CellInfo (uint16_t localCellId, uint16_t remoteCellId)
60 {
61  m_localCellId = localCellId;
62  m_remoteCellId = remoteCellId;
63 }
64 
66 {
67  m_localCellId = 0;
68  m_remoteCellId = 0;
69 }
70 
71 X2CellInfo&
73 {
74  NS_LOG_FUNCTION (this);
77  return *this;
78 }
79 
81 
83 
85  : m_x2cUdpPort (4444),
86  m_x2uUdpPort (2152)
87 {
88  NS_LOG_FUNCTION (this);
89 
91 }
92 
94 {
95  NS_LOG_FUNCTION (this);
96 }
97 
98 void
100 {
101  NS_LOG_FUNCTION (this);
102 
103  m_x2InterfaceSockets.clear ();
104  m_x2InterfaceCellIds.clear ();
105  delete m_x2SapProvider;
106 }
107 
108 TypeId
110 {
111  static TypeId tid = TypeId ("ns3::EpcX2")
112  .SetParent<Object> ();
113  return tid;
114 }
115 
116 void
118 {
119  NS_LOG_FUNCTION (this << s);
120  m_x2SapUser = s;
121 }
122 
125 {
126  NS_LOG_FUNCTION (this);
127  return m_x2SapProvider;
128 }
129 
130 
131 void
132 EpcX2::AddX2Interface (uint16_t localCellId, Ipv4Address localX2Address, uint16_t remoteCellId, Ipv4Address remoteX2Address)
133 {
134  NS_LOG_FUNCTION (this << localCellId << localX2Address << remoteCellId << remoteX2Address);
135 
136  int retval;
137 
138  // Get local eNB where this X2 entity belongs to
139  Ptr<Node> localEnb = GetObject<Node> ();
140 
141  // Create X2-C socket for the local eNB
142  Ptr<Socket> localX2cSocket = Socket::CreateSocket (localEnb, TypeId::LookupByName ("ns3::UdpSocketFactory"));
143  retval = localX2cSocket->Bind (InetSocketAddress (localX2Address, m_x2cUdpPort));
144  NS_ASSERT (retval == 0);
145  localX2cSocket->SetRecvCallback (MakeCallback (&EpcX2::RecvFromX2cSocket, this));
146 
147  // Create X2-U socket for the local eNB
148  Ptr<Socket> localX2uSocket = Socket::CreateSocket (localEnb, TypeId::LookupByName ("ns3::UdpSocketFactory"));
149  retval = localX2uSocket->Bind (InetSocketAddress (localX2Address, m_x2uUdpPort));
150  NS_ASSERT (retval == 0);
151  localX2uSocket->SetRecvCallback (MakeCallback (&EpcX2::RecvFromX2uSocket, this));
152 
153 
154  NS_ASSERT_MSG (m_x2InterfaceSockets.find (remoteCellId) == m_x2InterfaceSockets.end (),
155  "Mapping for remoteCellId = " << remoteCellId << " is already known");
156  m_x2InterfaceSockets [remoteCellId] = Create<X2IfaceInfo> (remoteX2Address, localX2cSocket, localX2uSocket);
157 
158  NS_ASSERT_MSG (m_x2InterfaceCellIds.find (localX2cSocket) == m_x2InterfaceCellIds.end (),
159  "Mapping for control plane localSocket = " << localX2cSocket << " is already known");
160  m_x2InterfaceCellIds [localX2cSocket] = Create<X2CellInfo> (localCellId, remoteCellId);
161 
162  NS_ASSERT_MSG (m_x2InterfaceCellIds.find (localX2uSocket) == m_x2InterfaceCellIds.end (),
163  "Mapping for data plane localSocket = " << localX2uSocket << " is already known");
164  m_x2InterfaceCellIds [localX2uSocket] = Create<X2CellInfo> (localCellId, remoteCellId);
165 }
166 
167 
168 void
170 {
171  NS_LOG_FUNCTION (this << socket);
172 
173  NS_LOG_LOGIC ("Recv X2 message: from Socket");
174  Ptr<Packet> packet = socket->Recv ();
175  NS_LOG_LOGIC ("packetLen = " << packet->GetSize ());
176 
178  "Missing infos of local and remote CellId");
179  Ptr<X2CellInfo> cellsInfo = m_x2InterfaceCellIds [socket];
180 
181  EpcX2Header x2Header;
182  packet->RemoveHeader (x2Header);
183 
184  NS_LOG_LOGIC ("X2 header: " << x2Header);
185 
186  uint8_t messageType = x2Header.GetMessageType ();
187  uint8_t procedureCode = x2Header.GetProcedureCode ();
188 
189  if (procedureCode == EpcX2Header::HandoverPreparation)
190  {
191  if (messageType == EpcX2Header::InitiatingMessage)
192  {
193  NS_LOG_LOGIC ("Recv X2 message: HANDOVER REQUEST");
194 
195  EpcX2HandoverRequestHeader x2HoReqHeader;
196  packet->RemoveHeader (x2HoReqHeader);
197 
198  NS_LOG_INFO ("X2 HandoverRequest header: " << x2HoReqHeader);
199 
201  params.oldEnbUeX2apId = x2HoReqHeader.GetOldEnbUeX2apId ();
202  params.cause = x2HoReqHeader.GetCause ();
203  params.sourceCellId = cellsInfo->m_remoteCellId;
204  params.targetCellId = x2HoReqHeader.GetTargetCellId ();
205  params.mmeUeS1apId = x2HoReqHeader.GetMmeUeS1apId ();
208  params.bearers = x2HoReqHeader.GetBearers ();
209  params.rrcContext = packet;
210 
211  NS_LOG_LOGIC ("oldEnbUeX2apId = " << params.oldEnbUeX2apId);
212  NS_LOG_LOGIC ("sourceCellId = " << params.sourceCellId);
213  NS_LOG_LOGIC ("targetCellId = " << params.targetCellId);
214  NS_LOG_LOGIC ("mmeUeS1apId = " << params.mmeUeS1apId);
215  NS_LOG_LOGIC ("cellsInfo->m_localCellId = " << cellsInfo->m_localCellId);
216  NS_ASSERT_MSG (params.targetCellId == cellsInfo->m_localCellId,
217  "TargetCellId mismatches with localCellId");
218 
220  }
221  else if (messageType == EpcX2Header::SuccessfulOutcome)
222  {
223  NS_LOG_LOGIC ("Recv X2 message: HANDOVER REQUEST ACK");
224 
225  EpcX2HandoverRequestAckHeader x2HoReqAckHeader;
226  packet->RemoveHeader (x2HoReqAckHeader);
227 
228  NS_LOG_INFO ("X2 HandoverRequestAck header: " << x2HoReqAckHeader);
229 
231  params.oldEnbUeX2apId = x2HoReqAckHeader.GetOldEnbUeX2apId ();
232  params.newEnbUeX2apId = x2HoReqAckHeader.GetNewEnbUeX2apId ();
233  params.sourceCellId = cellsInfo->m_localCellId;
234  params.targetCellId = cellsInfo->m_remoteCellId;
235  params.admittedBearers = x2HoReqAckHeader.GetAdmittedBearers ();
236  params.notAdmittedBearers = x2HoReqAckHeader.GetNotAdmittedBearers ();
237  params.rrcContext = packet;
238 
239  NS_LOG_LOGIC ("oldEnbUeX2apId = " << params.oldEnbUeX2apId);
240  NS_LOG_LOGIC ("newEnbUeX2apId = " << params.newEnbUeX2apId);
241  NS_LOG_LOGIC ("sourceCellId = " << params.sourceCellId);
242  NS_LOG_LOGIC ("targetCellId = " << params.targetCellId);
243 
245  }
246  else // messageType == EpcX2Header::UnsuccessfulOutcome
247  {
248  NS_LOG_LOGIC ("Recv X2 message: HANDOVER PREPARATION FAILURE");
249 
250  EpcX2HandoverPreparationFailureHeader x2HoPrepFailHeader;
251  packet->RemoveHeader (x2HoPrepFailHeader);
252 
253  NS_LOG_INFO ("X2 HandoverPreparationFailure header: " << x2HoPrepFailHeader);
254 
256  params.oldEnbUeX2apId = x2HoPrepFailHeader.GetOldEnbUeX2apId ();
257  params.sourceCellId = cellsInfo->m_localCellId;
258  params.targetCellId = cellsInfo->m_remoteCellId;
259  params.cause = x2HoPrepFailHeader.GetCause ();
260  params.criticalityDiagnostics = x2HoPrepFailHeader.GetCriticalityDiagnostics ();
261 
262  NS_LOG_LOGIC ("oldEnbUeX2apId = " << params.oldEnbUeX2apId);
263  NS_LOG_LOGIC ("sourceCellId = " << params.sourceCellId);
264  NS_LOG_LOGIC ("targetCellId = " << params.targetCellId);
265  NS_LOG_LOGIC ("cause = " << params.cause);
266  NS_LOG_LOGIC ("criticalityDiagnostics = " << params.criticalityDiagnostics);
267 
269  }
270  }
271  else if (procedureCode == EpcX2Header::LoadIndication)
272  {
273  if (messageType == EpcX2Header::InitiatingMessage)
274  {
275  NS_LOG_LOGIC ("Recv X2 message: LOAD INFORMATION");
276 
277  EpcX2LoadInformationHeader x2LoadInfoHeader;
278  packet->RemoveHeader (x2LoadInfoHeader);
279 
280  NS_LOG_INFO ("X2 LoadInformation header: " << x2LoadInfoHeader);
281 
283  params.cellInformationList = x2LoadInfoHeader.GetCellInformationList ();
284 
285  NS_LOG_LOGIC ("cellInformationList size = " << params.cellInformationList.size ());
286 
288  }
289  }
290  else if (procedureCode == EpcX2Header::SnStatusTransfer)
291  {
292  if (messageType == EpcX2Header::InitiatingMessage)
293  {
294  NS_LOG_LOGIC ("Recv X2 message: SN STATUS TRANSFER");
295 
296  EpcX2SnStatusTransferHeader x2SnStatusXferHeader;
297  packet->RemoveHeader (x2SnStatusXferHeader);
298 
299  NS_LOG_INFO ("X2 SnStatusTransfer header: " << x2SnStatusXferHeader);
300 
302  params.oldEnbUeX2apId = x2SnStatusXferHeader.GetOldEnbUeX2apId ();
303  params.newEnbUeX2apId = x2SnStatusXferHeader.GetNewEnbUeX2apId ();
304  params.sourceCellId = cellsInfo->m_remoteCellId;
305  params.targetCellId = cellsInfo->m_localCellId;
307 
308  NS_LOG_LOGIC ("oldEnbUeX2apId = " << params.oldEnbUeX2apId);
309  NS_LOG_LOGIC ("newEnbUeX2apId = " << params.newEnbUeX2apId);
310  NS_LOG_LOGIC ("sourceCellId = " << params.sourceCellId);
311  NS_LOG_LOGIC ("targetCellId = " << params.targetCellId);
312  NS_LOG_LOGIC ("erabsList size = " << params.erabsSubjectToStatusTransferList.size ());
313 
315  }
316  }
317  else if (procedureCode == EpcX2Header::UeContextRelease)
318  {
319  if (messageType == EpcX2Header::InitiatingMessage)
320  {
321  NS_LOG_LOGIC ("Recv X2 message: UE CONTEXT RELEASE");
322 
323  EpcX2UeContextReleaseHeader x2UeCtxReleaseHeader;
324  packet->RemoveHeader (x2UeCtxReleaseHeader);
325 
326  NS_LOG_INFO ("X2 UeContextRelease header: " << x2UeCtxReleaseHeader);
327 
329  params.oldEnbUeX2apId = x2UeCtxReleaseHeader.GetOldEnbUeX2apId ();
330  params.newEnbUeX2apId = x2UeCtxReleaseHeader.GetNewEnbUeX2apId ();
331 
332  NS_LOG_LOGIC ("oldEnbUeX2apId = " << params.oldEnbUeX2apId);
333  NS_LOG_LOGIC ("newEnbUeX2apId = " << params.newEnbUeX2apId);
334 
336  }
337  }
338  else if (procedureCode == EpcX2Header::ResourceStatusReporting)
339  {
340  if (messageType == EpcX2Header::InitiatingMessage)
341  {
342  NS_LOG_LOGIC ("Recv X2 message: RESOURCE STATUS UPDATE");
343 
344  EpcX2ResourceStatusUpdateHeader x2ResStatUpdHeader;
345  packet->RemoveHeader (x2ResStatUpdHeader);
346 
347  NS_LOG_INFO ("X2 ResourceStatusUpdate header: " << x2ResStatUpdHeader);
348 
350  params.enb1MeasurementId = x2ResStatUpdHeader.GetEnb1MeasurementId ();
351  params.enb2MeasurementId = x2ResStatUpdHeader.GetEnb2MeasurementId ();
352  params.cellMeasurementResultList = x2ResStatUpdHeader.GetCellMeasurementResultList ();
353 
354  NS_LOG_LOGIC ("enb1MeasurementId = " << params.enb1MeasurementId);
355  NS_LOG_LOGIC ("enb2MeasurementId = " << params.enb2MeasurementId);
356  NS_LOG_LOGIC ("cellMeasurementResultList size = " << params.cellMeasurementResultList.size ());
357 
359  }
360  }
361  else
362  {
363  NS_ASSERT_MSG (false, "ProcedureCode NOT SUPPORTED!!!");
364  }
365 }
366 
367 
368 void
370 {
371  NS_LOG_FUNCTION (this << socket);
372 
373  NS_LOG_LOGIC ("Recv UE DATA through X2-U interface from Socket");
374  Ptr<Packet> packet = socket->Recv ();
375  NS_LOG_LOGIC ("packetLen = " << packet->GetSize ());
376 
378  "Missing infos of local and remote CellId");
379  Ptr<X2CellInfo> cellsInfo = m_x2InterfaceCellIds [socket];
380 
381  GtpuHeader gtpu;
382  packet->RemoveHeader (gtpu);
383 
384  NS_LOG_LOGIC ("GTP-U header: " << gtpu);
385 
387  params.sourceCellId = cellsInfo->m_remoteCellId;
388  params.targetCellId = cellsInfo->m_localCellId;
389  params.gtpTeid = gtpu.GetTeid ();
390  params.ueData = packet;
391 
392  m_x2SapUser->RecvUeData (params);
393 }
394 
395 
396 //
397 // Implementation of the X2 SAP Provider
398 //
399 void
401 {
402  NS_LOG_FUNCTION (this);
403 
404  NS_LOG_LOGIC ("oldEnbUeX2apId = " << params.oldEnbUeX2apId);
405  NS_LOG_LOGIC ("sourceCellId = " << params.sourceCellId);
406  NS_LOG_LOGIC ("targetCellId = " << params.targetCellId);
407  NS_LOG_LOGIC ("mmeUeS1apId = " << params.mmeUeS1apId);
408 
410  "Missing infos for targetCellId = " << params.targetCellId);
411  Ptr<X2IfaceInfo> socketInfo = m_x2InterfaceSockets [params.targetCellId];
412  Ptr<Socket> sourceSocket = socketInfo->m_localCtrlPlaneSocket;
413  Ipv4Address targetIpAddr = socketInfo->m_remoteIpAddr;
414 
415  NS_LOG_LOGIC ("sourceSocket = " << sourceSocket);
416  NS_LOG_LOGIC ("targetIpAddr = " << targetIpAddr);
417 
418  NS_LOG_INFO ("Send X2 message: HANDOVER REQUEST");
419 
420  // Build the X2 message
421  EpcX2HandoverRequestHeader x2HoReqHeader;
422  x2HoReqHeader.SetOldEnbUeX2apId (params.oldEnbUeX2apId);
423  x2HoReqHeader.SetCause (params.cause);
424  x2HoReqHeader.SetTargetCellId (params.targetCellId);
425  x2HoReqHeader.SetMmeUeS1apId (params.mmeUeS1apId);
428  x2HoReqHeader.SetBearers (params.bearers);
429 
430  EpcX2Header x2Header;
433  x2Header.SetLengthOfIes (x2HoReqHeader.GetLengthOfIes ());
434  x2Header.SetNumberOfIes (x2HoReqHeader.GetNumberOfIes ());
435 
436  NS_LOG_INFO ("X2 header: " << x2Header);
437  NS_LOG_INFO ("X2 HandoverRequest header: " << x2HoReqHeader);
438 
439  // Build the X2 packet
440  Ptr<Packet> packet = (params.rrcContext != 0) ? (params.rrcContext) : (Create <Packet> ());
441  packet->AddHeader (x2HoReqHeader);
442  packet->AddHeader (x2Header);
443  NS_LOG_INFO ("packetLen = " << packet->GetSize ());
444 
445  // Send the X2 message through the socket
446  sourceSocket->SendTo (packet, 0, InetSocketAddress (targetIpAddr, m_x2cUdpPort));
447 }
448 
449 
450 void
452 {
453  NS_LOG_FUNCTION (this);
454 
455  NS_LOG_LOGIC ("oldEnbUeX2apId = " << params.oldEnbUeX2apId);
456  NS_LOG_LOGIC ("newEnbUeX2apId = " << params.newEnbUeX2apId);
457  NS_LOG_LOGIC ("sourceCellId = " << params.sourceCellId);
458  NS_LOG_LOGIC ("targetCellId = " << params.targetCellId);
459 
461  "Socket infos not defined for sourceCellId = " << params.sourceCellId);
462 
463  Ptr<Socket> localSocket = m_x2InterfaceSockets [params.sourceCellId]->m_localCtrlPlaneSocket;
464  Ipv4Address remoteIpAddr = m_x2InterfaceSockets [params.sourceCellId]->m_remoteIpAddr;
465 
466  NS_LOG_LOGIC ("localSocket = " << localSocket);
467  NS_LOG_LOGIC ("remoteIpAddr = " << remoteIpAddr);
468 
469  NS_LOG_INFO ("Send X2 message: HANDOVER REQUEST ACK");
470 
471  // Build the X2 message
472  EpcX2HandoverRequestAckHeader x2HoAckHeader;
473  x2HoAckHeader.SetOldEnbUeX2apId (params.oldEnbUeX2apId);
474  x2HoAckHeader.SetNewEnbUeX2apId (params.newEnbUeX2apId);
475  x2HoAckHeader.SetAdmittedBearers (params.admittedBearers);
476  x2HoAckHeader.SetNotAdmittedBearers (params.notAdmittedBearers);
477 
478  EpcX2Header x2Header;
481  x2Header.SetLengthOfIes (x2HoAckHeader.GetLengthOfIes ());
482  x2Header.SetNumberOfIes (x2HoAckHeader.GetNumberOfIes ());
483 
484  NS_LOG_INFO ("X2 header: " << x2Header);
485  NS_LOG_INFO ("X2 HandoverAck header: " << x2HoAckHeader);
486  NS_LOG_INFO ("RRC context: " << params.rrcContext);
487 
488  // Build the X2 packet
489  Ptr<Packet> packet = (params.rrcContext != 0) ? (params.rrcContext) : (Create <Packet> ());
490  packet->AddHeader (x2HoAckHeader);
491  packet->AddHeader (x2Header);
492  NS_LOG_INFO ("packetLen = " << packet->GetSize ());
493 
494  // Send the X2 message through the socket
495  localSocket->SendTo (packet, 0, InetSocketAddress (remoteIpAddr, m_x2cUdpPort));
496 }
497 
498 
499 void
501 {
502  NS_LOG_FUNCTION (this);
503 
504  NS_LOG_LOGIC ("oldEnbUeX2apId = " << params.oldEnbUeX2apId);
505  NS_LOG_LOGIC ("sourceCellId = " << params.sourceCellId);
506  NS_LOG_LOGIC ("targetCellId = " << params.targetCellId);
507  NS_LOG_LOGIC ("cause = " << params.cause);
508  NS_LOG_LOGIC ("criticalityDiagnostics = " << params.criticalityDiagnostics);
509 
511  "Socket infos not defined for sourceCellId = " << params.sourceCellId);
512 
513  Ptr<Socket> localSocket = m_x2InterfaceSockets [params.sourceCellId]->m_localCtrlPlaneSocket;
514  Ipv4Address remoteIpAddr = m_x2InterfaceSockets [params.sourceCellId]->m_remoteIpAddr;
515 
516  NS_LOG_LOGIC ("localSocket = " << localSocket);
517  NS_LOG_LOGIC ("remoteIpAddr = " << remoteIpAddr);
518 
519  NS_LOG_INFO ("Send X2 message: HANDOVER PREPARATION FAILURE");
520 
521  // Build the X2 message
522  EpcX2HandoverPreparationFailureHeader x2HoPrepFailHeader;
523  x2HoPrepFailHeader.SetOldEnbUeX2apId (params.oldEnbUeX2apId);
524  x2HoPrepFailHeader.SetCause (params.cause);
525  x2HoPrepFailHeader.SetCriticalityDiagnostics (params.criticalityDiagnostics);
526 
527  EpcX2Header x2Header;
530  x2Header.SetLengthOfIes (x2HoPrepFailHeader.GetLengthOfIes ());
531  x2Header.SetNumberOfIes (x2HoPrepFailHeader.GetNumberOfIes ());
532 
533  NS_LOG_INFO ("X2 header: " << x2Header);
534  NS_LOG_INFO ("X2 HandoverPrepFail header: " << x2HoPrepFailHeader);
535 
536  // Build the X2 packet
537  Ptr<Packet> packet = Create <Packet> ();
538  packet->AddHeader (x2HoPrepFailHeader);
539  packet->AddHeader (x2Header);
540  NS_LOG_INFO ("packetLen = " << packet->GetSize ());
541 
542  // Send the X2 message through the socket
543  localSocket->SendTo (packet, 0, InetSocketAddress (remoteIpAddr, m_x2cUdpPort));
544 }
545 
546 
547 void
549 {
550  NS_LOG_FUNCTION (this);
551 
552  NS_LOG_LOGIC ("oldEnbUeX2apId = " << params.oldEnbUeX2apId);
553  NS_LOG_LOGIC ("newEnbUeX2apId = " << params.newEnbUeX2apId);
554  NS_LOG_LOGIC ("sourceCellId = " << params.sourceCellId);
555  NS_LOG_LOGIC ("targetCellId = " << params.targetCellId);
556  NS_LOG_LOGIC ("erabsList size = " << params.erabsSubjectToStatusTransferList.size ());
557 
559  "Socket infos not defined for targetCellId = " << params.targetCellId);
560 
561  Ptr<Socket> localSocket = m_x2InterfaceSockets [params.targetCellId]->m_localCtrlPlaneSocket;
562  Ipv4Address remoteIpAddr = m_x2InterfaceSockets [params.targetCellId]->m_remoteIpAddr;
563 
564  NS_LOG_LOGIC ("localSocket = " << localSocket);
565  NS_LOG_LOGIC ("remoteIpAddr = " << remoteIpAddr);
566 
567  NS_LOG_INFO ("Send X2 message: SN STATUS TRANSFER");
568 
569  // Build the X2 message
570  EpcX2SnStatusTransferHeader x2SnStatusXferHeader;
571  x2SnStatusXferHeader.SetOldEnbUeX2apId (params.oldEnbUeX2apId);
572  x2SnStatusXferHeader.SetNewEnbUeX2apId (params.newEnbUeX2apId);
574 
575  EpcX2Header x2Header;
578  x2Header.SetLengthOfIes (x2SnStatusXferHeader.GetLengthOfIes ());
579  x2Header.SetNumberOfIes (x2SnStatusXferHeader.GetNumberOfIes ());
580 
581  NS_LOG_INFO ("X2 header: " << x2Header);
582  NS_LOG_INFO ("X2 SnStatusTransfer header: " << x2SnStatusXferHeader);
583 
584  // Build the X2 packet
585  Ptr<Packet> packet = Create <Packet> ();
586  packet->AddHeader (x2SnStatusXferHeader);
587  packet->AddHeader (x2Header);
588  NS_LOG_INFO ("packetLen = " << packet->GetSize ());
589 
590  // Send the X2 message through the socket
591  localSocket->SendTo (packet, 0, InetSocketAddress (remoteIpAddr, m_x2cUdpPort));
592 }
593 
594 
595 void
597 {
598  NS_LOG_FUNCTION (this);
599 
600  NS_LOG_LOGIC ("oldEnbUeX2apId = " << params.oldEnbUeX2apId);
601  NS_LOG_LOGIC ("newEnbUeX2apId = " << params.newEnbUeX2apId);
602  NS_LOG_LOGIC ("sourceCellId = " << params.sourceCellId);
603 
605  "Socket infos not defined for sourceCellId = " << params.sourceCellId);
606 
607  Ptr<Socket> localSocket = m_x2InterfaceSockets [params.sourceCellId]->m_localCtrlPlaneSocket;
608  Ipv4Address remoteIpAddr = m_x2InterfaceSockets [params.sourceCellId]->m_remoteIpAddr;
609 
610  NS_LOG_LOGIC ("localSocket = " << localSocket);
611  NS_LOG_LOGIC ("remoteIpAddr = " << remoteIpAddr);
612 
613  NS_LOG_INFO ("Send X2 message: UE CONTEXT RELEASE");
614 
615  // Build the X2 message
616  EpcX2UeContextReleaseHeader x2UeCtxReleaseHeader;
617  x2UeCtxReleaseHeader.SetOldEnbUeX2apId (params.oldEnbUeX2apId);
618  x2UeCtxReleaseHeader.SetNewEnbUeX2apId (params.newEnbUeX2apId);
619 
620  EpcX2Header x2Header;
623  x2Header.SetLengthOfIes (x2UeCtxReleaseHeader.GetLengthOfIes ());
624  x2Header.SetNumberOfIes (x2UeCtxReleaseHeader.GetNumberOfIes ());
625 
626  NS_LOG_INFO ("X2 header: " << x2Header);
627  NS_LOG_INFO ("X2 UeContextRelease header: " << x2UeCtxReleaseHeader);
628 
629  // Build the X2 packet
630  Ptr<Packet> packet = Create <Packet> ();
631  packet->AddHeader (x2UeCtxReleaseHeader);
632  packet->AddHeader (x2Header);
633  NS_LOG_INFO ("packetLen = " << packet->GetSize ());
634 
635  // Send the X2 message through the socket
636  localSocket->SendTo (packet, 0, InetSocketAddress (remoteIpAddr, m_x2cUdpPort));
637 }
638 
639 
640 void
642 {
643  NS_LOG_FUNCTION (this);
644 
645  NS_LOG_LOGIC ("targetCellId = " << params.targetCellId);
646  NS_LOG_LOGIC ("cellInformationList size = " << params.cellInformationList.size ());
647 
649  "Missing infos for targetCellId = " << params.targetCellId);
650  Ptr<X2IfaceInfo> socketInfo = m_x2InterfaceSockets [params.targetCellId];
651  Ptr<Socket> sourceSocket = socketInfo->m_localCtrlPlaneSocket;
652  Ipv4Address targetIpAddr = socketInfo->m_remoteIpAddr;
653 
654  NS_LOG_LOGIC ("sourceSocket = " << sourceSocket);
655  NS_LOG_LOGIC ("targetIpAddr = " << targetIpAddr);
656 
657  NS_LOG_INFO ("Send X2 message: LOAD INFORMATION");
658 
659  // Build the X2 message
660  EpcX2LoadInformationHeader x2LoadInfoHeader;
661  x2LoadInfoHeader.SetCellInformationList (params.cellInformationList);
662 
663  EpcX2Header x2Header;
666  x2Header.SetLengthOfIes (x2LoadInfoHeader.GetLengthOfIes ());
667  x2Header.SetNumberOfIes (x2LoadInfoHeader.GetNumberOfIes ());
668 
669  NS_LOG_INFO ("X2 header: " << x2Header);
670  NS_LOG_INFO ("X2 LoadInformation header: " << x2LoadInfoHeader);
671 
672  // Build the X2 packet
673  Ptr<Packet> packet = Create <Packet> ();
674  packet->AddHeader (x2LoadInfoHeader);
675  packet->AddHeader (x2Header);
676  NS_LOG_INFO ("packetLen = " << packet->GetSize ());
677 
678  // Send the X2 message through the socket
679  sourceSocket->SendTo (packet, 0, InetSocketAddress (targetIpAddr, m_x2cUdpPort));
680 
681 }
682 
683 
684 void
686 {
687  NS_LOG_FUNCTION (this);
688 
689  NS_LOG_LOGIC ("targetCellId = " << params.targetCellId);
690  NS_LOG_LOGIC ("enb1MeasurementId = " << params.enb1MeasurementId);
691  NS_LOG_LOGIC ("enb2MeasurementId = " << params.enb2MeasurementId);
692  NS_LOG_LOGIC ("cellMeasurementResultList size = " << params.cellMeasurementResultList.size ());
693 
695  "Missing infos for targetCellId = " << params.targetCellId);
696  Ptr<X2IfaceInfo> socketInfo = m_x2InterfaceSockets [params.targetCellId];
697  Ptr<Socket> sourceSocket = socketInfo->m_localCtrlPlaneSocket;
698  Ipv4Address targetIpAddr = socketInfo->m_remoteIpAddr;
699 
700  NS_LOG_LOGIC ("sourceSocket = " << sourceSocket);
701  NS_LOG_LOGIC ("targetIpAddr = " << targetIpAddr);
702 
703  NS_LOG_INFO ("Send X2 message: RESOURCE STATUS UPDATE");
704 
705  // Build the X2 message
706  EpcX2ResourceStatusUpdateHeader x2ResourceStatUpdHeader;
707  x2ResourceStatUpdHeader.SetEnb1MeasurementId (params.enb1MeasurementId);
708  x2ResourceStatUpdHeader.SetEnb2MeasurementId (params.enb2MeasurementId);
709  x2ResourceStatUpdHeader.SetCellMeasurementResultList (params.cellMeasurementResultList);
710 
711  EpcX2Header x2Header;
714  x2Header.SetLengthOfIes (x2ResourceStatUpdHeader.GetLengthOfIes ());
715  x2Header.SetNumberOfIes (x2ResourceStatUpdHeader.GetNumberOfIes ());
716 
717  NS_LOG_INFO ("X2 header: " << x2Header);
718  NS_LOG_INFO ("X2 ResourceStatusUpdate header: " << x2ResourceStatUpdHeader);
719 
720  // Build the X2 packet
721  Ptr<Packet> packet = Create <Packet> ();
722  packet->AddHeader (x2ResourceStatUpdHeader);
723  packet->AddHeader (x2Header);
724  NS_LOG_INFO ("packetLen = " << packet->GetSize ());
725 
726  // Send the X2 message through the socket
727  sourceSocket->SendTo (packet, 0, InetSocketAddress (targetIpAddr, m_x2cUdpPort));
728 
729 }
730 
731 
732 void
734 {
735  NS_LOG_FUNCTION (this);
736 
737  NS_LOG_LOGIC ("sourceCellId = " << params.sourceCellId);
738  NS_LOG_LOGIC ("targetCellId = " << params.targetCellId);
739  NS_LOG_LOGIC ("gtpTeid = " << params.gtpTeid);
740 
742  "Missing infos for targetCellId = " << params.targetCellId);
743  Ptr<X2IfaceInfo> socketInfo = m_x2InterfaceSockets [params.targetCellId];
744  Ptr<Socket> sourceSocket = socketInfo->m_localUserPlaneSocket;
745  Ipv4Address targetIpAddr = socketInfo->m_remoteIpAddr;
746 
747  NS_LOG_LOGIC ("sourceSocket = " << sourceSocket);
748  NS_LOG_LOGIC ("targetIpAddr = " << targetIpAddr);
749 
750  GtpuHeader gtpu;
751  gtpu.SetTeid (params.gtpTeid);
752  gtpu.SetLength (params.ueData->GetSize () + gtpu.GetSerializedSize () - 8);
753  NS_LOG_INFO ("GTP-U header: " << gtpu);
754 
755  Ptr<Packet> packet = params.ueData;
756  packet->AddHeader (gtpu);
757 
758  NS_LOG_INFO ("Forward UE DATA through X2 interface");
759  sourceSocket->SendTo (packet, 0, InetSocketAddress (targetIpAddr, m_x2uUdpPort));
760 }
761 
762 } // 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:93
Introspection did not find any typical Config paths.
virtual void DoSendHandoverRequest(EpcX2SapProvider::HandoverRequestParams params)
Definition: epc-x2.cc:400
virtual ~X2IfaceInfo(void)
Definition: epc-x2.cc:41
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)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by "...
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
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:44
void SetOldEnbUeX2apId(uint16_t x2apId)
X2CellInfo & operator=(const X2CellInfo &)
Definition: epc-x2.cc:72
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
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:109
virtual void RecvSnStatusTransfer(SnStatusTransferParams params)=0
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file...
Definition: assert.h:61
virtual void RecvHandoverRequest(HandoverRequestParams params)=0
Service primitives.
std::vector< EpcX2Sap::CellMeasurementResultItem > GetCellMeasurementResultList() const
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:201
virtual void DoSendLoadInformation(EpcX2SapProvider::LoadInformationParams params)
Definition: epc-x2.cc:641
uint32_t GetSize(void) const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:766
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)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:244
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:369
virtual ~X2CellInfo(void)
Definition: epc-x2.cc:65
virtual void DoSendUeData(EpcX2SapProvider::UeDataParams params)
Definition: epc-x2.cc:733
virtual void DoSendUeContextRelease(EpcX2SapProvider::UeContextReleaseParams params)
Definition: epc-x2.cc:596
std::vector< EpcX2Sap::ErabsSubjectToStatusTransferItem > GetErabsSubjectToStatusTransferList() const
void SetLengthOfIes(uint32_t lengthOfIes)
virtual void DoSendSnStatusTransfer(EpcX2SapProvider::SnStatusTransferParams params)
Definition: epc-x2.cc:548
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
Introspection did not find any typical Config paths.
Definition: epc-x2-header.h:80
virtual void DoSendResourceStatusUpdate(EpcX2SapProvider::ResourceStatusUpdateParams params)
Definition: epc-x2.cc:685
void SetTargetCellId(uint16_t targetCellId)
X2IfaceInfo & operator=(const X2IfaceInfo &)
Definition: epc-x2.cc:48
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:169
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:451
Callback< R > MakeCallback(R(T::*memPtr)(void), OBJ objPtr)
Definition: callback.h:1290
void SetEnb1MeasurementId(uint16_t enb1MeasurementId)
Introspection did not find any typical Config paths.
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:127
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:70
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:84
X2IfaceInfo(Ipv4Address remoteIpAddr, Ptr< Socket > localCtrlPlaneSocket, Ptr< Socket > localUserPlaneSocket)
Definition: epc-x2.cc:34
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition: log.h:252
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:59
virtual int Bind(const Address &address)=0
Allocate a local endpoint for this socket.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
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
#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:84
virtual void DoSendHandoverPreparationFailure(EpcX2SapProvider::HandoverPreparationFailureParams params)
Definition: epc-x2.cc:500
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:40
EpcX2SapProvider * GetEpcX2SapProvider()
Definition: epc-x2.cc:124
std::vector< EpcX2Sap::CellInformationItem > GetCellInformationList() const
void SetEpcX2SapUser(EpcX2SapUser *s)
Definition: epc-x2.cc:117
void SetErabsSubjectToStatusTransferList(std::vector< EpcX2Sap::ErabsSubjectToStatusTransferItem > erabs)
std::vector< ErabNotAdmittedItem > notAdmittedBearers
Definition: epc-x2-sap.h:250
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:87
virtual void RecvLoadInformation(LoadInformationParams params)=0
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:132
void SetOldEnbUeX2apId(uint16_t x2apId)
virtual void DoDispose(void)
Destructor implementation.
Definition: epc-x2.cc:99
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:51
void SetCriticalityDiagnostics(uint16_t criticalityDiagnostics)
TypeId SetParent(TypeId tid)
Definition: type-id.cc:631
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:556
Implementation of the GTPv1-U Release 10 as per 3Gpp TS 29.281 document.
void SetMmeUeS1apId(uint32_t mmeUeS1apId)