New release of ns-O-RAN 46/14246/1
authorAndrea Lacava <thecave003@gmail.com>
Wed, 12 Mar 2025 03:12:42 +0000 (23:12 -0400)
committerAndrea Lacava <thecave003@gmail.com>
Wed, 12 Mar 2025 04:00:30 +0000 (00:00 -0400)
Change-Id: Id2f1d4f6004c29529228fd51f86a6ef06f44b7fe
Signed-off-by: Andrea Lacava <thecave003@gmail.com>
13 files changed:
.gitignore [new file with mode: 0644]
.idea/.gitignore [new file with mode: 0644]
CMakeLists.txt [new file with mode: 0644]
README.md
examples/CMakeLists.txt [new file with mode: 0644]
examples/encode-decode-indication.cc [new file with mode: 0644]
examples/oran-interface-example.cc
examples/ric-indication-messages.cc
examples/wscript [deleted file]
model/asn1c-types.cc
model/kpm-indication.h
test/oran-interface-test-suite.cc [deleted file]
wscript [deleted file]

diff --git a/.gitignore b/.gitignore
new file mode 100644 (file)
index 0000000..8cc8400
--- /dev/null
@@ -0,0 +1,3 @@
+.vscode/settings.json
+.vscode/c_cpp_properties.json
+build/**
\ No newline at end of file
diff --git a/.idea/.gitignore b/.idea/.gitignore
new file mode 100644 (file)
index 0000000..8bf4d45
--- /dev/null
@@ -0,0 +1,6 @@
+# Default ignored files
+/shelf/
+/workspace.xml
+# Datasource local storage ignored files
+/dataSources/
+/dataSources.local.xml
diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644 (file)
index 0000000..3c1f326
--- /dev/null
@@ -0,0 +1,62 @@
+check_include_file_cxx(stdint.h HAVE_STDINT_H)
+if(HAVE_STDINT_H)
+    add_definitions(-DHAVE_STDINT_H)
+endif()
+
+set(examples_as_tests_sources)
+if(${ENABLE_EXAMPLES})
+    set(examples_as_tests_sources
+        #test/oran-interface-examples-test-suite.cc
+        )
+endif()
+
+#include_directories(/usr/local/include/e2sim)
+#link_directories(/usr/local/lib)
+#link_libraries(e2sim)
+
+find_external_library(DEPENDENCY_NAME e2sim
+                      HEADER_NAME e2sim.hpp
+                      LIBRARY_NAME e2sim
+                      SEARCH_PATHS /usr/local/include/e2sim)
+
+if(!${e2sim_FOUND})
+    message(WARNING "e2sim is required by oran-interface and was not found" )
+    return ()
+endif()
+
+include_directories(${e2sim_INCLUDE_DIRS})
+message(STATUS "dirs found:  ${e2sim_INCLUDE_DIRS}" )
+message(STATUS "libraries found:  ${e2sim_LIBRARIES}" )
+
+build_lib(
+    LIBNAME oran-interface
+    SOURCE_FILES model/oran-interface.cc
+                 helper/oran-interface-helper.cc
+                 model/asn1c-types.cc
+                 model/function-description.cc
+                 model/kpm-indication.cc
+                 model/kpm-function-description.cc
+                 model/ric-control-message.cc
+                 model/ric-control-function-description.cc
+                 helper/oran-interface-helper.cc
+                 helper/indication-message-helper.cc
+                 helper/lte-indication-message-helper.cc
+                 helper/mmwave-indication-message-helper.cc
+    HEADER_FILES model/oran-interface.h
+                 helper/oran-interface-helper.h
+                 model/asn1c-types.h
+                 model/function-description.h
+                 model/kpm-indication.h
+                 model/kpm-function-description.h
+                 model/ric-control-message.h
+                 model/ric-control-function-description.h
+                 helper/indication-message-helper.h
+                 helper/lte-indication-message-helper.h
+                 helper/mmwave-indication-message-helper.h
+    LIBRARIES_TO_LINK 
+                    ${libcore}
+                    ${e2sim_LIBRARIES}
+    TEST_SOURCES test/oran-interface-test-suite.cc
+                 ${examples_as_tests_sources}
+)
+
index 41d733b..2afc029 100644 (file)
--- a/README.md
+++ b/README.md
@@ -1,28 +1,44 @@
-# ns3-o-ran-e2
+# ns3-o-ran-e2 aka ns-O-RAN
 
 ================================
 
-This ns-3 module enables the support for running multiple terminations of an O-RAN-compliant E2 interface inside the simulation process. It has been developed as part of a collaborative effort between the [Institute for the Wireless Internet of Things (WIoT)](https://wiot.northeastern.edu) at Northeastern University, Mavenir, and the University of Padova.
+This ns-3 module enables the support for running multiple terminations of an O-RAN-compliant E2 interface inside the simulation process.
+This module has been developed by a team at the [Institute for the Wireless Internet of Things (WIoT)](https://wiot.northeastern.edu) at Northeastern University, in collaboration with Sapienza University of Rome, the University of Padova and with support from Mavenir.
 
-## References
+## How to use
 
-More information can be found in the paper
+This module can be used with an extension of the [ns3-mmWave module](https://github.com/wineslab/ns-o-ran-ns3-mmwave).
+This repository must be cloned in the `contrib` folder.
+Moreover, our custom version of the [e2sim library](https://github.com/wineslab/o-ran-e2sim) must be installed.
+Please refer to this [quick start guide](https://openrangym.com/tutorials/ns-o-ran) that presents a tutorial to bridge ns-O-RAN and Colosseum RIC (i.e., OSC RIC bronze reduced) ns-O-RAN.
 
-> A. Lacava, M. Polese, R. Sivaraj, R. Soundrarajan, B. S. Bhati, T. Singh, T. Zugno, F. Cuomo, T. Melodia "Programmable and Customized Intelligence for Traffic Steering in 5G Networks Using Open RAN Architectures" in arXiv:2209.14171 October 2022 [pdf](https://arxiv.org/pdf/2209.14171.pdf) [bibtex](https://ece.northeastern.edu/wineslab/wines_bibtex/andrea/LacavaAMC22.txt)
+Additional material:
 
-## How to use
+- Framework presentation https://openrangym.com/ran-frameworks/ns-o-ran 
+- Tutorial OSC RIC version E ns-O-RAN connection  https://www.nsnam.org/tutorials/consortium23/oran-tutorial-slides-wns3-2023.pdf 
+- Recording of the tutorial OSC RIC version E done at the WNS3 2023 https://vimeo.com/867704832 
+- xApp repositories working with ns-O-RAN:
+  - https://github.com/wineslab/ns-o-ran-scp-ric-app-kpimon 
+  - https://github.com/wineslab/ns-o-ran-xapp-rc 
+- Gymnasium Environment wrapper for ns-O-RAN https://github.com/wineslab/ns-o-ran-gym-environment
+
+## References
+
+More information can be found in the technical paper:
+
+> A. Lacava, M. Bordin, M. Polese, R. Sivaraj, T. Zugno, F. Cuomo, and T. Melodia. "ns-O-RAN: Simulating O-RAN 5G Systems in ns-3", Proceedings of the 2023 Workshop on ns-3 (2023), [DOI:10.1145/3592149.3592161](https://dl.acm.org/doi/abs/10.1145/3592149.3592161)
 
-This module can be used with an extension of the [ns3-mmWave module](https://github.com/nyuwireless-unipd/ns3-mmwave) that will soon be released. The module needs to be cloned in the contrib folder. The [e2sim library](https://github.com/o-ran-sc/sim-e2-interface) needs to be installed.
+If you use the scenario-one.cc or the traffic steering implementation please cite:
 
-We will provide further instructions as part of this README file.
+>A. Lacava, M. Polese, R. Sivaraj, R. Soundrarajan, B. Bhati, T. Singh, T. Zugno, F. Cuomo, and T. Melodia. "Programmable and Customized Intelligence for Traffic Steering in 5G Networks Using Open RAN Architectures", IEEE Transactions on Mobile Computing (2024), [DOI:10.1109/TMC.2023.3266642](https://doi.org/10.1109/TMC.2023.3266642) [pdf](https://ieeexplore.ieee.org/document/10102369) [bibtex](https://ece.northeastern.edu/wineslab/wines_bibtex/andrea/LacavaAMC22.txt)
 
 ## Authors
 
 The ns3-o-ran-e2 module is the result of the development effort carried out by different people. The main contributors are:
 
-- Andrea Lacava, Northeastern University and Sapienza, University of Rome
+- Andrea Lacava, Northeastern University and Sapienza University of Rome
 - Michele Polese, Northeastern University
 - Tommaso Zugno, University of Padova
 - Rajarajan Sivaraj and team, Mavenir
 
-We welcome contributions through pull requests. A contribution guide will be provided soon.
+We welcome contributions through pull requests.
diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt
new file mode 100644 (file)
index 0000000..8bf5ae3
--- /dev/null
@@ -0,0 +1,19 @@
+set(examples
+    e2sim-integration-example
+    l3-rrc-example
+    oran-interface-example
+    encode-decode-indication
+    ric-control-function-desc
+    ric-indication-messages
+    test-wrappers
+)
+foreach(
+  example
+  ${examples}
+)
+  build_lib_example(
+    NAME ${example}
+    SOURCE_FILES ${example}.cc
+    LIBRARIES_TO_LINK ${liboran-interface}
+  )
+endforeach()
\ No newline at end of file
diff --git a/examples/encode-decode-indication.cc b/examples/encode-decode-indication.cc
new file mode 100644 (file)
index 0000000..d6aae3d
--- /dev/null
@@ -0,0 +1,353 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2022 Northeastern University
+ * Copyright (c) 2022 Sapienza, University of Rome
+ * Copyright (c) 2022 University of Padova
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Author: Andrea Lacava <thecave003@gmail.com>
+ *                Tommaso Zugno <tommasozugno@gmail.com>
+ *                Michele Polese <michele.polese@gmail.com>
+ */
+
+#include "ns3/core-module.h"
+#include "ns3/oran-interface.h"
+#include <errno.h>
+#include <E2SM-KPM-IndicationMessage-Format1.h>
+#include <PM-Containers-Item.h>
+#include "ProtocolIE-Field.h"
+#include "CellResourceReportListItem.h"
+#include "ServedPlmnPerCellListItem.h"
+#include "EPC-DU-PM-Container.h"
+#include "FGC-DU-PM-Container.h"
+#include "PerQCIReportListItem.h"
+
+using namespace ns3;
+NS_LOG_COMPONENT_DEFINE ("EncodeDecodeIndication");
+
+std::string DecodeOctectString(OCTET_STRING_t* octetString){
+  int size = octetString->size;
+  char out[size + 1];
+  std::memcpy (out, octetString->buf, size);
+  out[size] = '\0';
+
+  return std::string (out);
+}
+
+void
+readPfDuContainer (ODU_PF_Container_t *oDU)
+{
+  int count = oDU->cellResourceReportList.list.count;
+  if (count <= 0) {
+    NS_LOG_ERROR("[E2SM] received empty ODU list");
+    return;
+  }
+
+  for (int i = 0; i < count; i++)
+  {
+    CellResourceReportListItem_t *report = oDU->cellResourceReportList.list.array[i];
+    // NS_LOG_UNCOND ("CellResourceReportListItem " << i);
+    // NS_LOG_UNCOND (xer_fprint (stderr, &asn_DEF_CellResourceReportListItem, report));
+    NS_LOG_UNCOND ("NRCGI");
+    NS_LOG_UNCOND ("Buf PlmNID: " << report->nRCGI.pLMN_Identity.buf);
+    NS_LOG_UNCOND ("String PlmNID: " << std::string (DecodeOctectString(&report->nRCGI.pLMN_Identity)));
+    
+    // TODO Decode the report->nRCGI.nRCellIdentity to a std::string
+    // It's a bitstring I don't know how to do it
+
+    long ulTotalOfAvailablePRBs = *(report->ul_TotalofAvailablePRBs);
+    long dlTotalOfAvailablePRBs = *(report->dl_TotalofAvailablePRBs);
+    NS_LOG_UNCOND ("UL Total of Available PRBs: " << ulTotalOfAvailablePRBs);
+    NS_LOG_UNCOND("DL Total of Available PRBs: " << dlTotalOfAvailablePRBs);
+
+    for (int j = 0; j < report->servedPlmnPerCellList.list.count; j++)
+    {
+      ServedPlmnPerCellListItem_t *servedPlmnPerCell = report->servedPlmnPerCellList.list.array[j];
+      NS_LOG_UNCOND ("ServedPLMNPerCell " << j << " with PlmNID: " << DecodeOctectString(&servedPlmnPerCell->pLMN_Identity));
+      // NS_LOG_UNCOND (xer_fprint (stderr, &asn_DEF_ServedPlmnPerCellListItem, servedPlmnPerCell));
+      
+      FGC_DU_PM_Container_t* fgcDuPmContainer = servedPlmnPerCell->du_PM_5GC;
+      if (fgcDuPmContainer != NULL)
+      {
+        NS_LOG_UNCOND ("5GC DU PM Container");
+        NS_LOG_UNCOND (xer_fprint (stderr, &asn_DEF_FGC_DU_PM_Container, fgcDuPmContainer));
+      }
+
+      EPC_DU_PM_Container_t *epcDuPmContainer = servedPlmnPerCell->du_PM_EPC;
+      if(epcDuPmContainer != NULL)
+      {
+        NS_LOG_UNCOND ("EPC DU PM Container");
+        // NS_LOG_UNCOND (xer_fprint (stderr, &asn_DEF_EPC_DU_PM_Container, epcDuPmContainer));
+
+        for (int z = 0; z < epcDuPmContainer->perQCIReportList_du.list.count; z++)
+          {
+            PerQCIReportListItem_t * perQCIReportItem = epcDuPmContainer->perQCIReportList_du.list.array[z];
+            long dlPrbUsage = *perQCIReportItem->dl_PRBUsage;
+            long ulPrbUsage = *perQCIReportItem->ul_PRBUsage;
+            long qci =  perQCIReportItem->qci;
+
+            NS_LOG_UNCOND ("QCI " << qci << ", dlPrbUsage: " << dlPrbUsage
+                                  << ", ulPrbUsage: " << ulPrbUsage);
+          }
+      }
+    }
+
+  }
+}
+
+void
+readPfCuContainer (OCUCP_PF_Container_t *oCU_CP)
+{
+  // Decode the values in container and create a variable for each decoded values and then print on screen with UNCOND
+  NS_LOG_UNCOND (xer_fprint (stderr, &asn_DEF_OCUCP_PF_Container, oCU_CP));
+  NS_LOG_UNCOND ("OCUCP_PF_Container_t");
+  long numActiveUes = *oCU_CP->cu_CP_Resource_Status.numberOfActive_UEs;
+  NS_LOG_UNCOND (numActiveUes);
+}
+
+void
+readPfCuContainer (OCUUP_PF_Container_t *oCU_UP)
+{
+}
+
+void
+ProcessIndicationMessage (E2SM_KPM_IndicationMessage_t *indMsg)
+{
+  if (indMsg->present == E2SM_KPM_IndicationMessage_PR_indicationMessage_Format1)
+  {
+    NS_LOG_UNCOND ("Format 1 present\n");
+
+    E2SM_KPM_IndicationMessage_Format1_t *e2SmIndicationMessageFormat1 = indMsg->choice.indicationMessage_Format1;
+
+    // extract RAN container, which is where we put our payload
+    std::vector<uint8_t *> serving_cell_payload_vec;
+    std::vector<uint8_t *> neighbor_cell_payload_vec;
+    for (int i = 0; i < e2SmIndicationMessageFormat1->pm_Containers.list.count; i++){
+      PM_Containers_Item_t *pmContainer = e2SmIndicationMessageFormat1->pm_Containers.list.array[i];
+      // NS_LOG_UNCOND ("PM Container");
+      // NS_LOG_UNCOND (xer_fprint (stderr, &asn_DEF_PM_Containers_Item, pmContainer));
+      PF_Container_t *pfContainer = pmContainer->performanceContainer;
+      switch (pfContainer->present)
+        {
+        case PF_Container_PR_NOTHING:
+          NS_LOG_ERROR ("PF Container is empty");
+          break;
+        case PF_Container_PR_oDU:
+          // NS_LOG_UNCOND ("oDU PF Container");
+          // NS_LOG_UNCOND (xer_fprint (stderr, &asn_DEF_PF_Container, pfContainer));
+          readPfDuContainer (pfContainer->choice.oDU);
+          break;
+        case PF_Container_PR_oCU_CP:
+          // NS_LOG_UNCOND ("oCU CP PF Container");
+          // NS_LOG_UNCOND (xer_fprint (stderr, &asn_DEF_PF_Container, pfContainer));
+          readPfCuContainer (pfContainer->choice.oCU_CP);
+          break;
+
+        case PF_Container_PR_oCU_UP:
+          // NS_LOG_UNCOND ("oCU UP PF Container");
+          // NS_LOG_UNCOND (xer_fprint (stderr, &asn_DEF_PF_Container, pfContainer));
+          readPfCuContainer (pfContainer->choice.oCU_UP);
+          break;
+
+        default:
+          NS_LOG_ERROR ("PF Container not supported");
+          break;
+        }
+    }
+
+    //                        // combine content of vectors, there should be a single entry in the vector anyway
+    //                        std::ostringstream serving_cell_payload_oss;
+    //                        std::copy(serving_cell_payload_vec.begin(), serving_cell_payload_vec.end() - 1, std::ostream_iterator<uint8_t*>(serving_cell_payload_oss, ", "));
+    //                        serving_cell_payload_oss << serving_cell_payload_vec.back();
+    //                        std::string serving_cell_payload = serving_cell_payload_oss.str();
+    //
+    //                        std::ostringstream neighbor_cell_payload_oss;
+    //                        std::copy(neighbor_cell_payload_vec.begin(), neighbor_cell_payload_vec.end() - 1, std::ostream_iterator<uint8_t*>(neighbor_cell_payload_oss, ", "));
+    //                        neighbor_cell_payload_oss << neighbor_cell_payload_vec.back();
+    //                        std::string neighbor_cell_payload = neighbor_cell_payload_oss.str();
+    //
+    //                        NS_LOG_UNCOND( "String conversion: serving_Cell_RF_Type %s, neighbor_Cell_RF: %s\n", serving_cell_payload.c_str(), neighbor_cell_payload.c_str());
+    //
+    //                        // assemble final payload
+    //                        if (serving_cell_payload.length() > 0 && neighbor_cell_payload.length() > 0) {
+    //                            payload = serving_cell_payload + ", " + neighbor_cell_payload;
+    //                        }
+    //                        else if (serving_cell_payload.length() > 0 && neighbor_cell_payload.length() == 0) {
+    //                            payload = serving_cell_payload;
+    //                        }
+    //                        else if (serving_cell_payload.length() == 0 && neighbor_cell_payload.length() > 0) {
+    //                            payload = neighbor_cell_payload;
+    //                        }
+    //                        else {
+    //                            payload = "";
+    //                        }
+    //
+    //                        NS_LOG_UNCOND( "Payload from RIC Indication message: %s\n", payload.c_str());
+  }
+  else
+  {
+    NS_LOG_UNCOND ("No payload received in RIC Indication message (or was unable to decode "
+                   "received payload\n");
+  }
+  //                    add_gnb_to_vector_unique(gnb_id);
+  //
+  //                    if (payload.length() > 0) {
+  //                        // add gnb id to payload
+  //                        payload += "\n{\"gnb_id\": \"" + std::string(reinterpret_cast<char const*>(gnb_id)) + "\"}";
+  //
+  //                        NS_LOG_UNCOND( "Sending RIC Indication message to agent\n");
+  //                        send_socket(payload.c_str());
+  //                    }
+  //                    else if (payload.length() <= 0) {
+  //                        NS_LOG_UNCOND( "Received empty payload\n");
+  //                    }
+  //                    else {
+  //                        NS_LOG_UNCOND( "Returned empty agent IP\n");
+  //                    }
+}
+
+void
+DecodeIndicationMessage (Ptr<KpmIndicationMessage> msg)
+{
+  asn_dec_rval_t decode_result;
+  E2SM_KPM_IndicationMessage_t *indMsg = 0;
+
+  decode_result = aper_decode_complete (NULL, &asn_DEF_E2SM_KPM_IndicationMessage,
+                                        (void **) &indMsg, msg->m_buffer, msg->m_size);
+
+  if (decode_result.code == RC_OK)
+    {
+      NS_LOG_UNCOND ("Decode OKAY");
+      // NS_LOG_UNCOND (xer_fprint (stderr, &asn_DEF_E2SM_KPM_IndicationMessage, indMsg));
+      ProcessIndicationMessage (indMsg);
+    }
+  else
+    {
+      ASN_STRUCT_FREE (asn_DEF_E2SM_KPM_IndicationMessage, indMsg);
+      NS_LOG_UNCOND ("DECODE NOT OKAY");
+    }
+}
+
+/**
+* Create and encode RIC Indication messages.
+* Prints the encoded messages in XML format. 
+*/
+
+int 
+main (int argc, char *argv[])
+{
+  // LogComponentEnable ("Asn1Types", LOG_LEVEL_ALL);
+  LogComponentEnable ("KpmIndication", LOG_LEVEL_INFO);
+  
+  std::string plmId = "111";
+  std::string gnbId = "1";
+  uint16_t nrCellId = 5;
+
+  uint64_t timestamp = 1630068655325;
+
+  NS_LOG_UNCOND ("----------- Begin of Kpm Indication header -----------");
+
+  KpmIndicationHeader::KpmRicIndicationHeaderValues headerValues; 
+  headerValues.m_plmId = plmId;
+  headerValues.m_gnbId = gnbId;
+  headerValues.m_nrCellId = nrCellId;
+  headerValues.m_timestamp = timestamp;
+
+  Ptr<KpmIndicationHeader> header = Create<KpmIndicationHeader> (KpmIndicationHeader::GlobalE2nodeType::eNB, headerValues);
+  
+  NS_LOG_UNCOND ("----------- End of the Kpm Indication header -----------");
+
+  NS_LOG_UNCOND ("----------- Start decode of Header -----------");
+  asn_dec_rval_t decode_header_result;
+  E2SM_KPM_IndicationHeader_t *indHdr = 0;
+  decode_header_result = aper_decode_complete(NULL, &asn_DEF_E2SM_KPM_IndicationHeader, (void **)&indHdr, header->m_buffer,
+  header->m_size);
+   if(decode_header_result.code == RC_OK) {
+       NS_LOG_UNCOND ("Decode OKAY");
+       NS_LOG_UNCOND (xer_fprint (stderr, &asn_DEF_E2SM_KPM_IndicationHeader, indHdr));
+    }
+    else {
+        ASN_STRUCT_FREE(asn_DEF_E2SM_KPM_IndicationHeader, indHdr);
+        NS_LOG_UNCOND ("DECODE NOT OKAY");
+    }
+  NS_LOG_UNCOND ("----------- End test of decode header -----------");
+
+
+  NS_LOG_UNCOND ("----------- Begin test of the DU message -----------");
+  KpmIndicationMessage::KpmIndicationMessageValues msgValues3;
+  msgValues3.m_cellObjectId = "NRCellCU";
+
+  Ptr<ODuContainerValues> oDuContainerVal = Create<ODuContainerValues> ();
+  Ptr<CellResourceReport> cellResRep = Create<CellResourceReport> ();
+  cellResRep->m_plmId = "111";
+  // std::stringstream ss;
+  // ss << std::hex << 1340012;
+  cellResRep->m_nrCellId = 2;
+  cellResRep->dlAvailablePrbs = 6;
+  cellResRep->ulAvailablePrbs = 6;
+
+    Ptr<CellResourceReport> cellResRep2 = Create<CellResourceReport> ();
+  cellResRep2->m_plmId = "444";
+  cellResRep2->m_nrCellId = 3;
+  cellResRep2->dlAvailablePrbs = 5;
+  cellResRep2->ulAvailablePrbs = 5;
+
+  Ptr<ServedPlmnPerCell> servedPlmnPerCell = Create<ServedPlmnPerCell> ();
+  servedPlmnPerCell->m_plmId = "121";
+  servedPlmnPerCell->m_nrCellId = 3;
+
+  Ptr<ServedPlmnPerCell> servedPlmnPerCell2 = Create<ServedPlmnPerCell> ();
+  servedPlmnPerCell2->m_plmId = "121";
+  servedPlmnPerCell2->m_nrCellId = 2;
+
+  Ptr<EpcDuPmContainer> epcDuVal = Create<EpcDuPmContainer> ();
+  epcDuVal->m_qci = 1;
+  epcDuVal->m_dlPrbUsage = 1;
+  epcDuVal->m_ulPrbUsage = 2;
+
+  Ptr<EpcDuPmContainer> epcDuVal2 = Create<EpcDuPmContainer> ();
+  epcDuVal2->m_qci = 1;
+  epcDuVal2->m_dlPrbUsage = 3;
+  epcDuVal2->m_ulPrbUsage = 4;
+
+  servedPlmnPerCell->m_perQciReportItems.insert (epcDuVal);
+  servedPlmnPerCell->m_perQciReportItems.insert (epcDuVal2);
+  servedPlmnPerCell2->m_perQciReportItems.insert (epcDuVal);
+  servedPlmnPerCell2->m_perQciReportItems.insert (epcDuVal2);
+  cellResRep->m_servedPlmnPerCellItems.insert (servedPlmnPerCell2);
+  cellResRep->m_servedPlmnPerCellItems.insert (servedPlmnPerCell);
+  cellResRep2->m_servedPlmnPerCellItems.insert (servedPlmnPerCell2);
+  cellResRep2->m_servedPlmnPerCellItems.insert (servedPlmnPerCell);
+  
+  oDuContainerVal->m_cellResourceReportItems.insert (cellResRep);
+  oDuContainerVal->m_cellResourceReportItems.insert (cellResRep2);
+
+  Ptr<MeasurementItemList> ue5DummyValues = Create<MeasurementItemList> ("UE-5");
+  ue5DummyValues->AddItem<long> ("DRB.EstabSucc.5QI.UEID", 6);
+  ue5DummyValues->AddItem<long> ("DRB.RelActNbr.5QI.UEID", 7);
+  msgValues3.m_ueIndications.insert (ue5DummyValues);
+
+  msgValues3.m_pmContainerValues = oDuContainerVal;
+  Ptr<KpmIndicationMessage> msg = Create<KpmIndicationMessage> (msgValues3);
+  
+  NS_LOG_UNCOND ("----------- End test of the DU message -----------");
+
+  NS_LOG_UNCOND ("----------- Start decode of DU message -----------");
+  DecodeIndicationMessage (msg);
+  NS_LOG_UNCOND ("----------- End test of decode DU message -----------");
+
+  return 0;
+}
index d6d763e..e966abe 100644 (file)
@@ -133,13 +133,26 @@ RicControlMessageCallback (E2AP_PDU_t *ric_ctrl_pdu)
 int 
 main (int argc, char *argv[])
 {
-  LogComponentEnable ("Asn1Types", LOG_LEVEL_ALL);
-  LogComponentEnable ("RicControlMessage", LOG_LEVEL_ALL);
-  e2Term = CreateObject<E2Termination> ("10.244.0.191", 36422, 38472, gnb, plmId);
-  Ptr<KpmFunctionDescription> kpmFd = Create<KpmFunctionDescription> ();
-  e2Term->RegisterKpmCallbackToE2Sm (200, kpmFd, &KpmSubscriptionCallback);    
-  Ptr<RicControlFunctionDescription> rcFd = Create<RicControlFunctionDescription> ();
-  e2Term->RegisterSmCallbackToE2Sm (300, rcFd, &RicControlMessageCallback);
+  LogComponentEnable ("E2Termination", LOG_LEVEL_ALL);
+  // LogComponentEnable ("Asn1Types", LOG_LEVEL_ALL);
+  // LogComponentEnable ("RicControlMessage", LOG_LEVEL_ALL);
+  e2Term = CreateObject<E2Termination> ("10.0.2.10", 36422, 38472, gnb, plmId);
+  e2Term->Start ();
+  bool use = true;
+  if (use){
+
+    Ptr<KpmFunctionDescription> kpmFd = Create<KpmFunctionDescription> ();
+    e2Term->RegisterKpmCallbackToE2Sm (200, kpmFd, &KpmSubscriptionCallback);    
+    Ptr<RicControlFunctionDescription> rcFd = Create<RicControlFunctionDescription> ();
+    e2Term->RegisterSmCallbackToE2Sm (300, rcFd, &RicControlMessageCallback);
+
+    E2Termination::RicSubscriptionRequest_rval_s params;
+    params.actionId = 0;
+    params.instanceId = 1;
+    params.ranFuncionId = 2;
+    params.requestorId = 1;
+    BuildAndSendReportMessage (params);
+  }
 
   return 0;
 }
index 6605a57..5b6f9f5 100644 (file)
@@ -84,7 +84,6 @@ KpmIndicationHeader::KpmRicIndicationHeaderValues headerValues2;
   Ptr<KpmIndicationHeader> header4 = Create<KpmIndicationHeader> (KpmIndicationHeader::GlobalE2nodeType::en_gNB, headerValues4);
 
   NS_LOG_UNCOND ("----------- End of the Kpm Indication header -----------");
-  return 0;
 
   KpmIndicationMessage::KpmIndicationMessageValues msgValues1;
 
diff --git a/examples/wscript b/examples/wscript
deleted file mode 100644 (file)
index ac88cd1..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-# -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
-
-def build(bld):    
-    obj = bld.create_ns3_program('e2sim-integration-example', ['oran-interface'])
-    obj.source = 'e2sim-integration-example.cc'
-
-    obj = bld.create_ns3_program('oran-interface-example', ['oran-interface'])
-    obj.source = 'oran-interface-example.cc'
-    
-    obj = bld.create_ns3_program('ric-indication-messages', ['oran-interface'])
-    obj.source = 'ric-indication-messages.cc'
-        
-    obj = bld.create_ns3_program('ric-control-function-desc', ['oran-interface'])
-    obj.source = 'ric-control-function-desc.cc'
-
-    obj = bld.create_ns3_program('l3-rrc-example', ['oran-interface'])
-    obj.source = 'l3-rrc-example.cc'
-
-    obj = bld.create_ns3_program('test-wrappers', ['oran-interface'])
-    obj.source = 'test-wrappers.cc'
index 7dbcfb2..c43cc8f 100644 (file)
@@ -856,6 +856,8 @@ MeasurementItem::~MeasurementItem ()
 
   if (m_pmType != NULL)
     ASN_STRUCT_FREE (asn_DEF_MeasurementType, m_pmType);
+
+  // TODO clear m_measurementItem
 }
 
 PM_Info_Item_t *
@@ -877,8 +879,6 @@ RANParameterItem::RANParameterItem (RANParameter_Item_t *ranParameterItem)
 
 RANParameterItem::~RANParameterItem ()
 {
-  if (m_ranParameterItem != NULL)
-    ASN_STRUCT_FREE (asn_DEF_RANParameter_Item, m_ranParameterItem);
 }
 
 std::vector<RANParameterItem>
index 7121ef0..1f03bc2 100644 (file)
@@ -48,7 +48,7 @@ namespace ns3 {
   public:
     enum GlobalE2nodeType { gNB = 0, eNB = 1, ng_eNB = 2, en_gNB = 3 };
 
-    const static int TIMESTAMP_LIMIT_SIZE = 8;
+    int TIMESTAMP_LIMIT_SIZE = 8;
     /**
     * Holds the values to be used to fill the RIC Indication header 
     */
diff --git a/test/oran-interface-test-suite.cc b/test/oran-interface-test-suite.cc
deleted file mode 100644 (file)
index fa33f64..0000000
+++ /dev/null
@@ -1,90 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2022 Northeastern University
- * Copyright (c) 2022 Sapienza, University of Rome
- * Copyright (c) 2022 University of Padova
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- * Author: Andrea Lacava <thecave003@gmail.com>
- *                Tommaso Zugno <tommasozugno@gmail.com>
- *                Michele Polese <michele.polese@gmail.com>
- */
-
-// Include a header file from your module to test.
-#include "ns3/oran-interface.h"
-
-// An essential include is test.h
-#include "ns3/test.h"
-
-// Do not put your test classes in namespace ns3.  You may find it useful
-// to use the using directive to access the ns3 namespace directly
-using namespace ns3;
-
-// This is an example TestCase.
-class OranInterfaceTestCase1 : public TestCase
-{
-public:
-  OranInterfaceTestCase1 ();
-  virtual ~OranInterfaceTestCase1 ();
-
-private:
-  virtual void DoRun (void);
-};
-
-// Add some help text to this case to describe what it is intended to test
-OranInterfaceTestCase1::OranInterfaceTestCase1 ()
-  : TestCase ("OranInterface test case (does nothing)")
-{
-}
-
-// This destructor does nothing but we include it as a reminder that
-// the test case should clean up after itself
-OranInterfaceTestCase1::~OranInterfaceTestCase1 ()
-{
-}
-
-//
-// This method is the pure virtual method from class TestCase that every
-// TestCase must implement
-//
-void
-OranInterfaceTestCase1::DoRun (void)
-{
-  // A wide variety of test macros are available in src/core/test.h
-  NS_TEST_ASSERT_MSG_EQ (true, true, "true doesn't equal true for some reason");
-  // Use this one for floating point comparisons
-  NS_TEST_ASSERT_MSG_EQ_TOL (0.01, 0.01, 0.001, "Numbers are not equal within tolerance");
-}
-
-// The TestSuite class names the TestSuite, identifies what type of TestSuite,
-// and enables the TestCases to be run.  Typically, only the constructor for
-// this class must be defined
-//
-class OranInterfaceTestSuite : public TestSuite
-{
-public:
-  OranInterfaceTestSuite ();
-};
-
-OranInterfaceTestSuite::OranInterfaceTestSuite ()
-  : TestSuite ("oran-interface", UNIT)
-{
-  // TestDuration for TestCase can be QUICK, EXTENSIVE or TAKES_FOREVER
-  AddTestCase (new OranInterfaceTestCase1, TestCase::QUICK);
-}
-
-// Do not forget to allocate an instance of this TestSuite
-static OranInterfaceTestSuite soranInterfaceTestSuite;
-
diff --git a/wscript b/wscript
deleted file mode 100644 (file)
index 2f7c033..0000000
--- a/wscript
+++ /dev/null
@@ -1,57 +0,0 @@
-# -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
-
-# def options(opt):
-#     pass
-
-def configure(conf):
-    conf.env.append_value('CXXFLAGS', '-I/usr/local/include/e2sim')
-    conf.env.append_value("LINKFLAGS", ["-L/usr/local/lib"])
-    conf.env.append_value("LIB", ["e2sim"])
-
-def build(bld):
-    module = bld.create_ns3_module('oran-interface', ['core'])    
-    module.source = [
-        'model/oran-interface.cc',
-        'model/asn1c-types.cc',
-        'model/function-description.cc',
-        'model/kpm-indication.cc',
-        'model/kpm-function-description.cc',
-        'model/ric-control-message.cc',
-        'model/ric-control-function-description.cc',
-        'helper/oran-interface-helper.cc',
-        'helper/indication-message-helper.cc',
-        'helper/lte-indication-message-helper.cc',
-        'helper/mmwave-indication-message-helper.cc'
-        ]
-
-    module_test = bld.create_ns3_module_test_library('oran-interface')
-    module_test.source = [
-        'test/oran-interface-test-suite.cc',
-        ]
-    # Tests encapsulating example programs should be listed here
-    if (bld.env['ENABLE_EXAMPLES']):
-        module_test.source.extend([
-        #    'test/oran-interface-examples-test-suite.cc',
-             ])
-
-    headers = bld(features='ns3header')
-    headers.module = 'oran-interface'
-    headers.source = [
-        'model/oran-interface.h',
-        'model/asn1c-types.h',
-        'model/function-description.h',
-        'model/kpm-indication.h',
-        'model/kpm-function-description.h',
-        'model/ric-control-message.h',
-        'model/ric-control-function-description.h',
-        'helper/oran-interface-helper.h',
-        'helper/indication-message-helper.h',
-        'helper/lte-indication-message-helper.h',
-        'helper/mmwave-indication-message-helper.h',
-        ]
-
-    if bld.env.ENABLE_EXAMPLES:
-        bld.recurse('examples')
-    
-
-    # bld.ns3_python_bindings()