diff --git a/openairinterface5g/openairinterface-conf/README.md b/openairinterface5g/openairinterface-conf/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..1f44668f77c8c6a7e0011a291e1eb5ebbd696c4b
--- /dev/null
+++ b/openairinterface5g/openairinterface-conf/README.md
@@ -0,0 +1,107 @@
+## Minimum hardware requirements for OAI CN5G and OAI gNB
+    1. Operating System: Ubuntu 20.04.5 LTS
+    3. CPU: 8 cores x86_64 @ 3.5 GHz
+    2. RAM: 32 GB
+
+## Minimum hardware requirements for OAI UE
+    1. CPU: 4 cores x86_64
+    2. RAM: 8 GB
+    
+## 5G Core Installation
+### The following steps can be executed by the file oai_5g_core_install.sh
+    1. First step is to download docker, docker-compose, git and network tools. 
+    2. Following you need to download wireshark
+        A. sudo add-apt-repository ppa:wireshark-dev/stable
+        B. sudo apt update
+        C. sudo apt install wireshark
+    3. Git clone the 5GC
+        A. git clone --branch v1.4.0 https://gitlab.eurecom.fr/oai/cn5g/oai-cn5g-fed.git
+        B. Configuration of the packet forwarding
+            - sudo sysctl net.ipv4.conf.all.forwarding=1
+            - sudo iptables -P FORWARD ACCEPT
+    4. Pulling the images from Docker Hub
+        A. docker pull oaisoftwarealliance/oai-amf:v1.4.0
+        B. docker pull oaisoftwarealliance/oai-nrf:v1.4.0
+        C. docker pull oaisoftwarealliance/oai-smf:v1.4.0 
+        D. docker pull oaisoftwarealliance/oai-spgwu-tiny:v1.4.0
+        E. docker pull oaisoftwarealliance/oai-udr:v1.4.0
+        F. docker pull oaisoftwarealliance/oai-udm:v1.4.0
+        G. docker pull oaisoftwarealliance/oai-ausf:v1.4.0
+        H. docker pull oaisoftwarealliance/oai-upf-vpp:v1.4.0
+        I. docker pull oaisoftwarealliance/oai-nssf:v1.4.0
+        J. docker pull oaisoftwarealliance/trf-gen-cn5g:latest
+    5. Tag docker images
+        A. docker image tag oaisoftwarealliance/oai-amf:v1.4.0 oai-amf:v1.4.0
+        B. docker image tag oaisoftwarealliance/oai-nrf:v1.4.0 oai-nrf:v1.4.0
+        C. docker image tag oaisoftwarealliance/oai-smf:v1.4.0 oai-smf:v1.4.0
+        D. docker image tag oaisoftwarealliance/oai-spgwu-tiny:v1.4.0 oai-spgwu-tiny:v1.4.0
+        E. docker image tag oaisoftwarealliance/oai-udr:v1.4.0 oai-udr:v1.4.0
+        F. docker image tag oaisoftwarealliance/oai-udm:v1.4.0 oai-udm:v1.4.0
+        G. docker image tag oaisoftwarealliance/oai-ausf:v1.4.0 oai-ausf:v1.4.0
+        H. docker image tag oaisoftwarealliance/oai-upf-vpp:v1.4.0 oai-upf-vpp:v1.4.0
+        I. docker image tag oaisoftwarealliance/oai-nssf:v1.4.0 oai-nssf:v1.4.0
+        J. docker image tag oaisoftwarealliance/trf-gen-cn5g:latest trf-gen-cn5g:latest
+    6. Synchronizing the tutorials
+        A. Change the directory for ~/oai-cn5g-fed/
+        B. ./scripts/syncComponents.sh
+        C. git submodule deinit --all --force
+        D. git submodule init
+        F. git submodule update        
+    7. Configure the bridge before deploying 5GC.
+        A. docker network create \ --driver=bridge \ --subnet=192.168.70.128/26 \ -o "com.docker.network.bridge.name"="demo-oai" \ demo-oai-public-net
+    8. Deploy the 5GC
+        A. Change the directory for ~/oai-cn5g-fed/docker-compose
+        B. python3 core-network.py --type start-basic --scenario 1
+
+## FlexRIC, gNB and UE Installation
+### The following steps can be executed by the file flexRIC_oai_gNB_install.sh
+    1. Install the following dependencies
+        A. sudo apt-get install autotools-dev
+        B. sudo apt-get install automake
+        C. sudo apt-get install libpcre2-dev
+        D. sudo apt-get install pcre2-utils
+        E. sudo apt-get install bison
+        F. sudo apt-get install byacc
+        G. sudo apt install g++
+        H. sudo apt install libsctp-dev python3.8 cmake-curses-gui libpcre2-dev python3-dev    
+    2. Configure swig
+        A. git clone https://github.com/swig/swig.git 
+        B. cd path_to_swig
+        C. ./autogen.sh
+        D. ./configure --prefix=/usr/
+        E. sudo make
+        F. sudo make install
+    3. Install FlexRIC
+        A. git clone https://gitlab.eurecom.fr/mosaic5g/flexric.git ~/flexric
+        B. cd path_to_flexric
+        C. git checkout v1.0.0
+        D. mkdir build
+        E. cd build
+        F. sudo cmake ..
+        G. sudo make
+        H. sudo make install
+    4. Install dependencies for OpenAirInterface 5G
+        A. sudo add-apt-repository ppa:ettusresearch/uhd -y
+        B. sudo apt-get update -y
+        C. sudo apt-get install libuhd-dev uhd-host -y
+        D. sudo apt-get install libuhd4.2.0 -y
+        E. sudo dpkg -i --force-overwrite /var/cache/apt/archives/libuhd4.2.0_4.2.0.1-0ubuntu1~focal1_amd64.deb
+    5. Download the OpenAirInterface 5G repository 
+        A. git clone https://gitlab.eurecom.fr/oai/openairinterface5g.git oai
+    6. Change the openairinterface 5G branch for 2022.41
+        A. cd oai/
+        B. git checkout 2022.41
+    7. Apply FlexRIC patch
+        A. git am <pathtoflexricsrc>/flexric/multiRAT/oai/oai.patch --whitespace=nowarn
+    8. Download the OAI configuration files (CU/DU, OAI UE, and gNB configuration)
+        A. sudo wget -O ~/oai/executables/nr-softmodem.c https://projetos.imd.ufrn.br/reginalab/sdran-openairinterface/-/raw/main/OpenAirInterface/OpenAirInterface-Conf/nr-softmodem.c?inline=false
+        B. sudo wget -O ~/oai/ci-scripts/conf_files/gNB_SA_CU.conf https://projetos.imd.ufrn.br/reginalab/sdran-openairinterface/-/raw/main/OpenAirInterface/OpenAirInterface-Conf/gNB_SA_CU.conf?inline=false
+        C. sudo wget -O ~/oai/ci-scripts/conf_files/gNB_SA_DU.conf https://projetos.imd.ufrn.br/reginalab/sdran-openairinterface/-/raw/main/OpenAirInterface/OpenAirInterface-Conf/gNB_SA_DU.conf?inline=false
+        D. sudo wget -O ~/oai/targets/PROJECTS/GENERIC-NR-5GC/CONF/ue.conf https://projetos.imd.ufrn.br/reginalab/sdran-openairinterface/-/raw/main/OpenAirInterface/OpenAirInterface-Conf/ue.conf?inline=false
+
+    9. Install the gNB and UE
+        A. source oaienv
+        B. cd cmake_targets
+        C. ./build_oai -I -w USRP -i  #For OAI first time installation. it will install some dependencies
+        D. ./build_oai --gNB --nrUE -c -C -w USRP --ninja --build-lib all
+
diff --git a/openairinterface5g/openairinterface-conf/gNB_SA_CU.conf b/openairinterface5g/openairinterface-conf/gNB_SA_CU.conf
new file mode 100644
index 0000000000000000000000000000000000000000..9dd463913b3277766245c118ad52954316ca3d8d
--- /dev/null
+++ b/openairinterface5g/openairinterface-conf/gNB_SA_CU.conf
@@ -0,0 +1,225 @@
+Active_gNBs = ( "gNB-Eurecom-CU");
+# Asn1_verbosity, choice in: none, info, annoying
+Asn1_verbosity = "none";
+Num_Threads_PUSCH = 8;
+
+gNBs =
+(
+ {
+    ////////// Identification parameters:
+    gNB_ID = 0xe00;
+
+#     cell_type =  "CELL_MACRO_GNB";
+
+    gNB_name  =  "gNB-Eurecom-CU";
+
+    // Tracking area code, 0x0000 and 0xfffe are reserved values
+    tracking_area_code  =  0x0001;
+    plmn_list = ({ mcc = 001; mnc = 01; mnc_length = 2; snssaiList = ({ sst = 1, sd = 0x1 }) });
+
+
+    nr_cellid = 12345678L;
+
+    tr_s_preference = "f1";
+
+    local_s_if_name = "lo";
+    local_s_address = "127.0.0.4";
+    remote_s_address = "127.0.0.3";
+    local_s_portc   = 501;
+    local_s_portd   = 2152;
+    remote_s_portc  = 500;
+    remote_s_portd  = 2152;
+    min_rxtxtime                                              = 6;
+
+     pdcch_ConfigSIB1 = (
+      {
+        controlResourceSetZero = 12;
+        searchSpaceZero = 0;
+      }
+      );
+
+    servingCellConfigCommon = (
+    {
+ #spCellConfigCommon
+
+      physCellId                                                    = 0;
+
+#  downlinkConfigCommon
+    #frequencyInfoDL
+      # this is 3600 MHz + 43 PRBs@30kHz SCS (same as initial BWP)
+      absoluteFrequencySSB                                             = 641280;
+      dl_frequencyBand                                                 = 78;
+      # this is 3600 MHz
+      dl_absoluteFrequencyPointA                                       = 640008;
+      #scs-SpecificCarrierList
+        dl_offstToCarrier                                              = 0;
+# subcarrierSpacing
+# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
+        dl_subcarrierSpacing                                           = 1;
+        dl_carrierBandwidth                                            = 106;
+     #initialDownlinkBWP
+      #genericParameters
+        # this is RBstart=27,L=48 (275*(L-1))+RBstart
+        initialDLBWPlocationAndBandwidth                               = 28875; # 6366 12925 12956 28875 12952
+# subcarrierSpacing
+# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
+        initialDLBWPsubcarrierSpacing                                   = 1;
+      #pdcch-ConfigCommon
+        initialDLBWPcontrolResourceSetZero                              = 11;
+        initialDLBWPsearchSpaceZero                                     = 0;
+
+  #uplinkConfigCommon
+     #frequencyInfoUL
+      ul_frequencyBand                                              = 78;
+      #scs-SpecificCarrierList
+      ul_offstToCarrier                                             = 0;
+# subcarrierSpacing
+# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
+      ul_subcarrierSpacing                                          = 1;
+      ul_carrierBandwidth                                           = 106;
+      pMax                                                          = 20;
+     #initialUplinkBWP
+      #genericParameters
+        initialULBWPlocationAndBandwidth                            = 28875;
+# subcarrierSpacing
+# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
+        initialULBWPsubcarrierSpacing                               = 1;
+      #rach-ConfigCommon
+        #rach-ConfigGeneric
+          prach_ConfigurationIndex                                  = 98;
+#prach_msg1_FDM
+#0 = one, 1=two, 2=four, 3=eight
+          prach_msg1_FDM                                            = 0;
+          prach_msg1_FrequencyStart                                 = 0;
+          zeroCorrelationZoneConfig                                 = 13;
+          preambleReceivedTargetPower                               = -96;
+#preamblTransMax (0...10) = (3,4,5,6,7,8,10,20,50,100,200)
+          preambleTransMax                                          = 6;
+#powerRampingStep
+# 0=dB0,1=dB2,2=dB4,3=dB6
+        powerRampingStep                                            = 1;
+#ra_ReponseWindow
+#1,2,4,8,10,20,40,80
+        ra_ResponseWindow                                           = 4;
+#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR
+#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen
+        ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR                = 4;
+#oneHalf (0..15) 4,8,12,16,...60,64
+        ssb_perRACH_OccasionAndCB_PreamblesPerSSB                   = 14;
+#ra_ContentionResolutionTimer
+#(0..7) 8,16,24,32,40,48,56,64
+        ra_ContentionResolutionTimer                                = 7;
+        rsrp_ThresholdSSB                                           = 19;
+#prach-RootSequenceIndex_PR
+#1 = 839, 2 = 139
+        prach_RootSequenceIndex_PR                                  = 2;
+        prach_RootSequenceIndex                                     = 1;
+        # SCS for msg1, can only be 15 for 30 kHz < 6 GHz, takes precendence over the one derived from prach-ConfigIndex
+        #
+        msg1_SubcarrierSpacing                                      = 1,
+# restrictedSetConfig
+# 0=unrestricted, 1=restricted type A, 2=restricted type B
+        restrictedSetConfig                                         = 0,
+
+        msg3_DeltaPreamble                                          = 1;
+        p0_NominalWithGrant                                         =-90;
+
+# pucch-ConfigCommon setup :
+# pucchGroupHopping
+# 0 = neither, 1= group hopping, 2=sequence hopping
+        pucchGroupHopping                                           = 0;
+        hoppingId                                                   = 40;
+        p0_nominal                                                  = -90;
+# ssb_PositionsInBurs_BitmapPR
+# 1=short, 2=medium, 3=long
+      ssb_PositionsInBurst_PR                                       = 2;
+      ssb_PositionsInBurst_Bitmap                                   = 1;
+
+# ssb_periodicityServingCell
+# 0 = ms5, 1=ms10, 2=ms20, 3=ms40, 4=ms80, 5=ms160, 6=spare2, 7=spare1
+      ssb_periodicityServingCell                                    = 2;
+
+# dmrs_TypeA_position
+# 0 = pos2, 1 = pos3
+      dmrs_TypeA_Position                                           = 0;
+
+# subcarrierSpacing
+# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
+      subcarrierSpacing                                             = 1;
+
+
+  #tdd-UL-DL-ConfigurationCommon
+# subcarrierSpacing
+# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
+      referenceSubcarrierSpacing                                    = 1;
+      # pattern1
+      # dl_UL_TransmissionPeriodicity
+      # 0=ms0p5, 1=ms0p625, 2=ms1, 3=ms1p25, 4=ms2, 5=ms2p5, 6=ms5, 7=ms10
+      dl_UL_TransmissionPeriodicity                                 = 6;
+      nrofDownlinkSlots                                             = 7;
+      nrofDownlinkSymbols                                           = 6;
+      nrofUplinkSlots                                               = 2;
+      nrofUplinkSymbols                                             = 4;
+
+      ssPBCH_BlockPower                                             = -25;
+  }
+
+  );
+    # ------- SCTP definitions
+    SCTP :
+    {
+        # Number of streams to use in input/output
+        SCTP_INSTREAMS  = 2;
+        SCTP_OUTSTREAMS = 2;
+    };
+
+
+    ////////// AMF parameters:
+        amf_ip_address      = ( { ipv4       = "192.168.70.132";
+                              ipv6       = "192:168:30::17";
+                              active     = "yes";
+                              preference = "ipv4";
+                            }
+                          );
+
+    NETWORK_INTERFACES :
+    {
+
+        GNB_INTERFACE_NAME_FOR_NG_AMF            = "demo-oai";
+        GNB_IPV4_ADDRESS_FOR_NG_AMF              = "192.168.70.129";
+        GNB_INTERFACE_NAME_FOR_NGU               = "demo-oai";
+        GNB_IPV4_ADDRESS_FOR_NGU                 = "192.168.70.129";
+        GNB_PORT_FOR_S1U                         = 2152; # Spec 2152
+    };
+  }
+);
+
+security = {
+  # preferred ciphering algorithms
+  # the first one of the list that an UE supports in chosen
+  # valid values: nea0, nea1, nea2, nea3
+  ciphering_algorithms = ( "nea0" );
+
+  # preferred integrity algorithms
+  # the first one of the list that an UE supports in chosen
+  # valid values: nia0, nia1, nia2, nia3
+  integrity_algorithms = ( "nia2", "nia0" );
+
+  # setting 'drb_ciphering' to "no" disables ciphering for DRBs, no matter
+  # what 'ciphering_algorithms' configures; same thing for 'drb_integrity'
+  drb_ciphering = "yes";
+  drb_integrity = "no";
+};
+     log_config :
+     {
+       global_log_level                      ="info";
+       hw_log_level                          ="info";
+       phy_log_level                         ="info";
+       mac_log_level                         ="info";
+       rlc_log_level                         ="debug";
+       pdcp_log_level                        ="info";
+       rrc_log_level                         ="info";
+       f1ap_log_level                         ="debug";
+       ngap_log_level                         ="debug";
+    };
+
diff --git a/openairinterface5g/openairinterface-conf/gNB_SA_DU.conf b/openairinterface5g/openairinterface-conf/gNB_SA_DU.conf
new file mode 100644
index 0000000000000000000000000000000000000000..e90c581b8827e4ec2d271d70f16cdf4dfffbc34c
--- /dev/null
+++ b/openairinterface5g/openairinterface-conf/gNB_SA_DU.conf
@@ -0,0 +1,243 @@
+Active_gNBs = ( "gNB-Eurecom-DU");
+# Asn1_verbosity, choice in: none, info, annoying
+Asn1_verbosity = "none";
+
+gNBs =
+(
+ {
+    ////////// Identification parameters:
+    gNB_ID = 0xe00;
+
+#     cell_type =  "CELL_MACRO_GNB";
+
+    gNB_name  =  "gNB-Eurecom-DU";
+
+    // Tracking area code, 0x0000 and 0xfffe are reserved values
+    tracking_area_code  =  0x0001;
+    plmn_list = ({ mcc = 001; mnc = 01; mnc_length = 2; snssaiList = ({ sst = 1, sd = 0x1 }) });
+
+
+    nr_cellid = 12345678L;
+
+    ////////// Physical parameters:
+
+    min_rxtxtime                                              = 6;
+
+    pdcch_ConfigSIB1 = (
+      {
+        controlResourceSetZero = 12;
+        searchSpaceZero = 0;
+      }
+    );
+
+    servingCellConfigCommon = (
+    {
+ #spCellConfigCommon
+
+      physCellId                                                    = 0;
+
+#  downlinkConfigCommon
+    #frequencyInfoDL
+      # this is 3600 MHz + 43 PRBs@30kHz SCS (same as initial BWP)
+      absoluteFrequencySSB                                          = 641280;
+      dl_frequencyBand                                                 = 78;
+      # this is 3600 MHz
+      dl_absoluteFrequencyPointA                                       = 640008;
+      #scs-SpecificCarrierList
+        dl_offstToCarrier                                              = 0;
+# subcarrierSpacing
+# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120  
+        dl_subcarrierSpacing                                           = 1;
+        dl_carrierBandwidth                                            = 106;
+     #initialDownlinkBWP
+      #genericParameters
+        # this is RBstart=27,L=48 (275*(L-1))+RBstart
+        initialDLBWPlocationAndBandwidth                               = 28875; # 6366 12925 12956 28875 12952
+# subcarrierSpacing
+# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120  
+        initialDLBWPsubcarrierSpacing                                           = 1;
+      #pdcch-ConfigCommon
+        initialDLBWPcontrolResourceSetZero                              = 11;
+        initialDLBWPsearchSpaceZero                                             = 0;
+
+  #uplinkConfigCommon 
+     #frequencyInfoUL
+      ul_frequencyBand                                                 = 78;
+      #scs-SpecificCarrierList
+      ul_offstToCarrier                                              = 0;
+# subcarrierSpacing
+# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120  
+      ul_subcarrierSpacing                                           = 1;
+      ul_carrierBandwidth                                            = 106;
+      pMax                                                          = 20;
+     #initialUplinkBWP
+      #genericParameters
+        initialULBWPlocationAndBandwidth                            = 28875;
+# subcarrierSpacing
+# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120  
+        initialULBWPsubcarrierSpacing                                           = 1;
+      #rach-ConfigCommon
+        #rach-ConfigGeneric
+          prach_ConfigurationIndex                                  = 98;
+#prach_msg1_FDM
+#0 = one, 1=two, 2=four, 3=eight
+          prach_msg1_FDM                                            = 0;
+          prach_msg1_FrequencyStart                                 = 0;
+          zeroCorrelationZoneConfig                                 = 13;
+          preambleReceivedTargetPower                               = -96;
+#preamblTransMax (0...10) = (3,4,5,6,7,8,10,20,50,100,200)
+          preambleTransMax                                          = 6;
+#powerRampingStep
+# 0=dB0,1=dB2,2=dB4,3=dB6
+        powerRampingStep                                            = 1;
+#ra_ReponseWindow
+#1,2,4,8,10,20,40,80
+        ra_ResponseWindow                                           = 4;
+#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR
+#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen
+        ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR                = 4;
+#oneHalf (0..15) 4,8,12,16,...60,64
+        ssb_perRACH_OccasionAndCB_PreamblesPerSSB                   = 14;
+#ra_ContentionResolutionTimer
+#(0..7) 8,16,24,32,40,48,56,64
+        ra_ContentionResolutionTimer                                = 7;
+        rsrp_ThresholdSSB                                           = 19;
+#prach-RootSequenceIndex_PR
+#1 = 839, 2 = 139
+        prach_RootSequenceIndex_PR                                  = 2;
+        prach_RootSequenceIndex                                     = 1;
+        # SCS for msg1, can only be 15 for 30 kHz < 6 GHz, takes precendence over the one derived from prach-ConfigIndex
+        #  
+        msg1_SubcarrierSpacing                                      = 1,
+# restrictedSetConfig
+# 0=unrestricted, 1=restricted type A, 2=restricted type B
+        restrictedSetConfig                                         = 0,
+
+        msg3_DeltaPreamble                                          = 1;
+        p0_NominalWithGrant                                         =-90;
+
+# pucch-ConfigCommon setup :
+# pucchGroupHopping
+# 0 = neither, 1= group hopping, 2=sequence hopping
+        pucchGroupHopping                                           = 0;
+        hoppingId                                                   = 40;
+        p0_nominal                                                  = -90;
+# ssb_PositionsInBurs_BitmapPR
+# 1=short, 2=medium, 3=long
+      ssb_PositionsInBurst_PR                                       = 2;
+      ssb_PositionsInBurst_Bitmap                                   = 1;
+
+# ssb_periodicityServingCell
+# 0 = ms5, 1=ms10, 2=ms20, 3=ms40, 4=ms80, 5=ms160, 6=spare2, 7=spare1 
+      ssb_periodicityServingCell                                    = 2;
+
+# dmrs_TypeA_position
+# 0 = pos2, 1 = pos3
+      dmrs_TypeA_Position                                           = 0;
+
+# subcarrierSpacing
+# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120  
+      subcarrierSpacing                                             = 1;
+
+
+  #tdd-UL-DL-ConfigurationCommon
+# subcarrierSpacing
+# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120  
+      referenceSubcarrierSpacing                                    = 1;
+      # pattern1 
+      # dl_UL_TransmissionPeriodicity
+      # 0=ms0p5, 1=ms0p625, 2=ms1, 3=ms1p25, 4=ms2, 5=ms2p5, 6=ms5, 7=ms10
+      dl_UL_TransmissionPeriodicity                                 = 6;
+      nrofDownlinkSlots                                             = 7;
+      nrofDownlinkSymbols                                           = 6;
+      nrofUplinkSlots                                               = 2;
+      nrofUplinkSymbols                                             = 4;
+
+      ssPBCH_BlockPower                                             = -25;
+     }
+
+  );
+
+
+    # ------- SCTP definitions
+    SCTP :
+    {
+        # Number of streams to use in input/output
+        SCTP_INSTREAMS  = 2;
+        SCTP_OUTSTREAMS = 2;
+    };
+  }
+);
+
+MACRLCs = (
+  {
+    num_cc           = 1;
+    tr_s_preference  = "local_L1";
+    tr_n_preference  = "f1";
+    local_n_if_name = "lo";
+    local_n_address = "127.0.0.3";
+    remote_n_address = "127.0.0.4";
+    local_n_portc   = 500;
+    local_n_portd   = 2152;
+    remote_n_portc  = 501;
+    remote_n_portd  = 2152;
+
+  }
+);
+
+L1s = (
+{
+  num_cc = 1;
+  tr_n_preference = "local_mac";
+  prach_dtx_threshold = 200;
+  pucch0_dtx_threshold = 150;
+  ofdm_offset_divisor = 8; #set this to UINT_MAX for offset 0
+}
+);
+
+RUs = (
+    {		  
+       local_rf       = "yes"
+         nb_tx          = 1
+         nb_rx          = 1
+         att_tx         = 0
+         att_rx         = 0;
+         bands          = [78];
+         max_pdschReferenceSignalPower = -27;
+         max_rxgain                    = 114;
+         eNB_instances  = [0];
+         #beamforming 1x4 matrix:
+         bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000];
+         clock_src = "internal";
+    }
+);  
+
+THREAD_STRUCT = (
+  {
+    #three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT"
+    parallel_config    = "PARALLEL_SINGLE_THREAD";
+    #two option for worker "WORKER_DISABLE" or "WORKER_ENABLE"
+    worker_config      = "WORKER_ENABLE";
+  }
+);
+rfsimulator: {
+serveraddr = "server";
+    serverport = "4043";
+    options = (); #("saviq"); or/and "chanmod"
+    modelname = "AWGN";
+    IQfile = "/tmp/rfsimulator.iqs"
+}
+
+     log_config :
+     {
+       global_log_level                      ="info";
+       hw_log_level                          ="info";
+       phy_log_level                         ="info";
+       mac_log_level                         ="info";
+       rlc_log_level                         ="info";
+       pdcp_log_level                        ="info";
+       rrc_log_level                         ="info";
+       f1ap_log_level                         ="debug";
+       ngap_log_level                         ="debug";
+    };
+
diff --git a/openairinterface5g/openairinterface-conf/nr-softmodem.c b/openairinterface5g/openairinterface-conf/nr-softmodem.c
new file mode 100644
index 0000000000000000000000000000000000000000..cbaa2139b30b6046b45022be25e7aff62f534a21
--- /dev/null
+++ b/openairinterface5g/openairinterface-conf/nr-softmodem.c
@@ -0,0 +1,1396 @@
+/*
+ * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The OpenAirInterface Software Alliance licenses this file to You under
+ * the OAI Public License, Version 1.1  (the "License"); you may not use this file
+ * except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.openairinterface.org/?page_id=698
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *-------------------------------------------------------------------------------
+ * For more information about the OpenAirInterface (OAI) Software Alliance:
+ *      contact@openairinterface.org
+ */
+
+
+#define _GNU_SOURCE             /* See feature_test_macros(7) */
+#include <sched.h>
+
+
+#include "T.h"
+
+#undef MALLOC //there are two conflicting definitions, so we better make sure we don't use it at all
+#include <common/utils/assertions.h>
+
+#include "PHY/types.h"
+#include "common/ran_context.h"
+
+#include "PHY/defs_gNB.h"
+#include "PHY/defs_common.h"
+#include "common/config/config_userapi.h"
+#include "common/utils/load_module_shlib.h"
+#undef MALLOC //there are two conflicting definitions, so we better make sure we don't use it at all
+//#undef FRAME_LENGTH_COMPLEX_SAMPLES //there are two conflicting definitions, so we better make sure we don't use it at all
+
+#include "sdr/COMMON/common_lib.h"
+#include "sdr/ETHERNET/USERSPACE/LIB/if_defs.h"
+
+//#undef FRAME_LENGTH_COMPLEX_SAMPLES //there are two conflicting definitions, so we better make sure we don't use it at all
+
+#include "PHY/phy_vars.h"
+#include "SCHED/sched_common_vars.h"
+#include "LAYER2/MAC/mac_vars.h"
+#include "RRC/LTE/rrc_vars.h"
+#include "PHY_INTERFACE/phy_interface_vars.h"
+#include "gnb_config.h"
+#include "SIMULATION/TOOLS/sim.h"
+#include <targets/RT/USER/lte-softmodem.h>
+
+#ifdef SMBV
+#include "PHY/TOOLS/smbv.h"
+unsigned short config_frames[4] = {2,9,11,13};
+#endif
+
+#include "common/utils/LOG/log.h"
+#include "common/utils/LOG/vcd_signal_dumper.h"
+#include "UTIL/OPT/opt.h"
+
+#include "intertask_interface.h"
+
+#include "PHY/INIT/phy_init.h"
+
+#include "system.h"
+#include <openair2/GNB_APP/gnb_app.h>
+#include "PHY/TOOLS/phy_scope_interface.h"
+#include "PHY/TOOLS/nr_phy_scope.h"
+#include "stats.h"
+#include "nr-softmodem.h"
+#include "executables/softmodem-common.h"
+#include "executables/thread-common.h"
+#include "NB_IoT_interface.h"
+#include "x2ap_eNB.h"
+#include "ngap_gNB.h"
+#include "gnb_paramdef.h"
+#include <openair3/ocp-gtpu/gtp_itf.h>
+#include "nfapi/oai_integration/vendor_ext.h"
+
+
+//////////////////////////////////
+//// E2 Agent headers
+//////////////////////////////////
+
+#include "agent_if/read/sm_ag_if_rd.h"
+#include "agent_if/sm_io.h"
+#include "agent_if/e2_agent_api.h"
+#include "openair2/LAYER2/nr_rlc/nr_rlc_entity.h"
+#include "openair2/LAYER2/nr_pdcp/nr_pdcp_entity.h"
+#include "openair2/LAYER2/nr_rlc/nr_rlc_oai_api.h"
+#include "openair2/LAYER2/nr_pdcp/nr_pdcp.h"
+#include "openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h"
+#include "openair2/LAYER2/NR_MAC_gNB/mac_proto.h"
+#include "openair2/RRC/NR/rrc_gNB_UE_context.h"
+#include <time.h>
+
+//////////////////////////////////
+//////////////////////////////////
+//////////////////////////////////
+
+
+pthread_cond_t nfapi_sync_cond;
+pthread_mutex_t nfapi_sync_mutex;
+int nfapi_sync_var=-1; //!< protected by mutex \ref nfapi_sync_mutex
+
+extern uint8_t nfapi_mode; // Default to monolithic mode
+THREAD_STRUCT thread_struct;
+pthread_cond_t sync_cond;
+pthread_mutex_t sync_mutex;
+int sync_var=-1; //!< protected by mutex \ref sync_mutex.
+int config_sync_var=-1;
+
+volatile int             start_gNB = 0;
+int oai_exit = 0;
+
+static int wait_for_sync = 0;
+
+unsigned int mmapped_dma=0;
+int single_thread_flag=1;
+
+int8_t threequarter_fs=0;
+
+uint64_t downlink_frequency[MAX_NUM_CCs][4];
+int32_t uplink_frequency_offset[MAX_NUM_CCs][4];
+
+//Temp fix for inexistent NR upper layer
+unsigned char NB_gNB_INST = 1;
+char *uecap_file;
+
+runmode_t mode = normal_txrx;
+static double snr_dB=20;
+
+#if MAX_NUM_CCs == 1
+rx_gain_t rx_gain_mode[MAX_NUM_CCs][4] = {{max_gain,max_gain,max_gain,max_gain}};
+double tx_gain[MAX_NUM_CCs][4] = {{20,0,0,0}};
+double rx_gain[MAX_NUM_CCs][4] = {{110,0,0,0}};
+#else
+rx_gain_t rx_gain_mode[MAX_NUM_CCs][4] = {{max_gain,max_gain,max_gain,max_gain},{max_gain,max_gain,max_gain,max_gain}};
+double tx_gain[MAX_NUM_CCs][4] = {{20,0,0,0},{20,0,0,0}};
+double rx_gain[MAX_NUM_CCs][4] = {{110,0,0,0},{20,0,0,0}};
+#endif
+
+double rx_gain_off = 0.0;
+
+static int tx_max_power[MAX_NUM_CCs]; /* =  {0,0}*/;
+
+
+int chain_offset=0;
+
+
+uint8_t dci_Format = 0;
+uint8_t agregation_Level =0xFF;
+
+uint8_t nb_antenna_tx = 1;
+uint8_t nb_antenna_rx = 1;
+
+char ref[128] = "internal";
+char channels[128] = "0";
+
+int rx_input_level_dBm;
+
+int otg_enabled;
+
+//int number_of_cards = 1;
+
+
+//static NR_DL_FRAME_PARMS      *frame_parms[MAX_NUM_CCs];
+//static nfapi_nr_config_request_t *config[MAX_NUM_CCs];
+uint32_t timing_advance = 0;
+uint64_t num_missed_slots=0; // counter for the number of missed slots
+
+#include <executables/split_headers.h>
+#include <SIMULATION/ETH_TRANSPORT/proto.h>
+
+int split73=0;
+void sendFs6Ul(PHY_VARS_eNB *eNB, int UE_id, int harq_pid, int segmentID, int16_t *data, int dataLen, int r_offset) {
+  AssertFatal(false, "Must not be called in this context\n");
+}
+void sendFs6Ulharq(enum pckType type, int UEid, PHY_VARS_eNB *eNB, LTE_eNB_UCI *uci, int frame, int subframe, uint8_t *harq_ack, uint8_t tdd_mapping_mode, uint16_t tdd_multiplexing_mask,
+                   uint16_t rnti, int32_t stat) {
+  AssertFatal(false, "Must not be called in this context\n");
+}
+
+
+extern void reset_opp_meas(void);
+extern void print_opp_meas(void);
+
+extern void *udp_eNB_task(void *args_p);
+
+int transmission_mode=1;
+int emulate_rf = 0;
+int numerology = 0;
+
+
+static char *parallel_config = NULL;
+static char *worker_config = NULL;
+
+/* struct for ethernet specific parameters given in eNB conf file */
+eth_params_t *eth_params;
+
+openair0_config_t openair0_cfg[MAX_CARDS];
+
+double cpuf;
+
+
+/* see file openair2/LAYER2/MAC/main.c for why abstraction_flag is needed
+ * this is very hackish - find a proper solution
+ */
+uint8_t abstraction_flag=0;
+
+/* forward declarations */
+void set_default_frame_parms(nfapi_nr_config_request_scf_t *config[MAX_NUM_CCs], NR_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs]);
+
+/*---------------------BMC: timespec helpers -----------------------------*/
+
+struct timespec min_diff_time = { .tv_sec = 0, .tv_nsec = 0 };
+struct timespec max_diff_time = { .tv_sec = 0, .tv_nsec = 0 };
+
+struct timespec clock_difftime(struct timespec start, struct timespec end) {
+  struct timespec temp;
+
+  if ((end.tv_nsec-start.tv_nsec)<0) {
+    temp.tv_sec = end.tv_sec-start.tv_sec-1;
+    temp.tv_nsec = 1000000000+end.tv_nsec-start.tv_nsec;
+  } else {
+    temp.tv_sec = end.tv_sec-start.tv_sec;
+    temp.tv_nsec = end.tv_nsec-start.tv_nsec;
+  }
+
+  return temp;
+}
+
+void print_difftimes(void) {
+#ifdef DEBUG
+  printf("difftimes min = %lu ns ; max = %lu ns\n", min_diff_time.tv_nsec, max_diff_time.tv_nsec);
+#else
+  LOG_I(HW,"difftimes min = %lu ns ; max = %lu ns\n", min_diff_time.tv_nsec, max_diff_time.tv_nsec);
+#endif
+}
+
+void update_difftimes(struct timespec start, struct timespec end) {
+  struct timespec diff_time = { .tv_sec = 0, .tv_nsec = 0 };
+  int             changed = 0;
+  diff_time = clock_difftime(start, end);
+
+  if ((min_diff_time.tv_nsec == 0) || (diff_time.tv_nsec < min_diff_time.tv_nsec)) {
+    min_diff_time.tv_nsec = diff_time.tv_nsec;
+    changed = 1;
+  }
+
+  if ((max_diff_time.tv_nsec == 0) || (diff_time.tv_nsec > max_diff_time.tv_nsec)) {
+    max_diff_time.tv_nsec = diff_time.tv_nsec;
+    changed = 1;
+  }
+
+#if 1
+
+  if (changed) print_difftimes();
+
+#endif
+}
+
+/*------------------------------------------------------------------------*/
+
+unsigned int build_rflocal(int txi, int txq, int rxi, int rxq) {
+  return (txi + (txq<<6) + (rxi<<12) + (rxq<<18));
+}
+unsigned int build_rfdc(int dcoff_i_rxfe, int dcoff_q_rxfe) {
+  return (dcoff_i_rxfe + (dcoff_q_rxfe<<8));
+}
+
+
+#define KNRM  "\x1B[0m"
+#define KRED  "\x1B[31m"
+#define KGRN  "\x1B[32m"
+#define KBLU  "\x1B[34m"
+#define RESET "\033[0m"
+
+
+void exit_function(const char *file, const char *function, const int line, const char *s) {
+  int ru_id;
+
+  if (s != NULL) {
+    printf("%s:%d %s() Exiting OAI softmodem: %s\n",file,line, function, s);
+  }
+
+  oai_exit = 1;
+
+  if (RC.ru == NULL)
+    exit(-1); // likely init not completed, prevent crash or hang, exit now...
+
+  for (ru_id=0; ru_id<RC.nb_RU; ru_id++) {
+    if (RC.ru[ru_id] && RC.ru[ru_id]->rfdevice.trx_end_func) {
+      RC.ru[ru_id]->rfdevice.trx_end_func(&RC.ru[ru_id]->rfdevice);
+      RC.ru[ru_id]->rfdevice.trx_end_func = NULL;
+    }
+
+    if (RC.ru[ru_id] && RC.ru[ru_id]->ifdevice.trx_end_func) {
+      RC.ru[ru_id]->ifdevice.trx_end_func(&RC.ru[ru_id]->ifdevice);
+      RC.ru[ru_id]->ifdevice.trx_end_func = NULL;
+    }
+  }
+
+  sleep(1); //allow lte-softmodem threads to exit first
+  exit(1);
+}
+
+
+
+int create_gNB_tasks(uint32_t gnb_nb) {
+  LOG_D(GNB_APP, "%s(gnb_nb:%d)\n", __FUNCTION__, gnb_nb);
+  itti_wait_ready(1);
+
+  if (gnb_nb > 0) {
+    /* Last task to create, others task must be ready before its start */
+    /*if (itti_create_task (TASK_GNB_APP, gNB_app_task, NULL) < 0) {
+      LOG_E(GNB_APP, "Create task for gNB APP failed\n");
+      return -1;
+    }*/
+    if(itti_create_task(TASK_SCTP, sctp_eNB_task, NULL) < 0) {
+      LOG_E(SCTP, "Create task for SCTP failed\n");
+      return -1;
+    }
+
+    if (is_x2ap_enabled()) {
+      if(itti_create_task(TASK_X2AP, x2ap_task, NULL) < 0) {
+        LOG_E(X2AP, "Create task for X2AP failed\n");
+      }
+    } else {
+      LOG_I(X2AP, "X2AP is disabled.\n");
+    }
+  }
+
+  if (get_softmodem_params()->sa) {
+
+    char*             gnb_ipv4_address_for_NGU      = NULL;
+    uint32_t          gnb_port_for_NGU              = 0;
+    char*             gnb_ipv4_address_for_S1U      = NULL;
+    uint32_t          gnb_port_for_S1U              = 0;
+    paramdef_t NETParams[]  =  GNBNETPARAMS_DESC;
+    char aprefix[MAX_OPTNAME_SIZE*2 + 8];
+    sprintf(aprefix,"%s.[%i].%s",GNB_CONFIG_STRING_GNB_LIST,0,GNB_CONFIG_STRING_NETWORK_INTERFACES_CONFIG);
+    config_get( NETParams,sizeof(NETParams)/sizeof(paramdef_t),aprefix);
+    
+    for(int i = GNB_INTERFACE_NAME_FOR_NG_AMF_IDX; i <= GNB_IPV4_ADDRESS_FOR_NG_AMF_IDX; i++) {
+      if( NETParams[i].strptr == NULL) {
+	LOG_E(NGAP, "No AMF configuration in the file.\n");
+      } else {
+	LOG_D(NGAP, "Configuration in the file: %s.\n",*NETParams[i].strptr);
+      }
+    }
+    
+    if (gnb_nb > 0) {
+      if (itti_create_task (TASK_NGAP, ngap_gNB_task, NULL) < 0) {
+        LOG_E(NGAP, "Create task for NGAP failed\n");
+        return -1;
+      }
+    }
+  }
+
+  if (gnb_nb > 0) {
+    if (itti_create_task (TASK_GNB_APP, gNB_app_task, NULL) < 0) {
+      LOG_E(GNB_APP, "Create task for gNB APP failed\n");
+      return -1;
+    }
+
+    LOG_I(NR_RRC,"Creating NR RRC gNB Task\n");
+
+    if (itti_create_task (TASK_RRC_GNB, rrc_gnb_task, NULL) < 0) {
+      LOG_E(NR_RRC, "Create task for NR RRC gNB failed\n");
+      return -1;
+    }
+
+    //Use check on x2ap to consider the NSA scenario and check for SA scenario
+    if(is_x2ap_enabled() || get_softmodem_params()->sa) {
+      if (itti_create_task (TASK_GTPV1_U, &gtpv1uTask, NULL) < 0) {
+        LOG_E(GTPU, "Create task for GTPV1U failed\n");
+        return -1;
+      }
+    }
+  }
+
+  return 0;
+}
+
+
+static void get_options(void) {
+  paramdef_t cmdline_params[] = CMDLINE_PARAMS_DESC_GNB ;
+  CONFIG_SETRTFLAG(CONFIG_NOEXITONHELP);
+  get_common_options(SOFTMODEM_GNB_BIT );
+  config_process_cmdline( cmdline_params,sizeof(cmdline_params)/sizeof(paramdef_t),NULL);
+  CONFIG_CLEARRTFLAG(CONFIG_NOEXITONHELP);
+
+  if ( !(CONFIG_ISFLAGSET(CONFIG_ABORT)) ) {
+    memset((void *)&RC,0,sizeof(RC));
+    /* Read RC configuration file */
+    NRRCConfig();
+    NB_gNB_INST = RC.nb_nr_inst;
+    NB_RU   = RC.nb_RU;
+    printf("Configuration: nb_rrc_inst %d, nb_nr_L1_inst %d, nb_ru %hhu\n",NB_gNB_INST,RC.nb_nr_L1_inst,NB_RU);
+  }
+
+  if(parallel_config != NULL) set_parallel_conf(parallel_config);
+
+  if(worker_config != NULL) set_worker_conf(worker_config);
+}
+
+
+void set_default_frame_parms(nfapi_nr_config_request_scf_t *config[MAX_NUM_CCs],
+                             NR_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs]) {
+  for (int CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
+    frame_parms[CC_id] = (NR_DL_FRAME_PARMS *) malloc(sizeof(NR_DL_FRAME_PARMS));
+    config[CC_id] = (nfapi_nr_config_request_scf_t *) malloc(sizeof(nfapi_nr_config_request_scf_t));
+    config[CC_id]->ssb_config.scs_common.value = 1;
+    config[CC_id]->cell_config.frame_duplex_type.value = 1; //FDD
+    //config[CC_id]->subframe_config.dl_cyclic_prefix_type.value = 0; //NORMAL
+    config[CC_id]->carrier_config.dl_grid_size[1].value = 106;
+    config[CC_id]->carrier_config.ul_grid_size[1].value = 106;
+    config[CC_id]->cell_config.phy_cell_id.value = 0;
+    ///dl frequency to be filled in
+    /*  //Set some default values that may be overwritten while reading options
+        frame_parms[CC_id]->frame_type          = FDD;
+        frame_parms[CC_id]->tdd_config          = 3;
+        frame_parms[CC_id]->tdd_config_S        = 0;
+        frame_parms[CC_id]->N_RB_DL             = 100;
+        frame_parms[CC_id]->N_RB_UL             = 100;
+        frame_parms[CC_id]->Ncp                 = NORMAL;
+        frame_parms[CC_id]->Ncp_UL              = NORMAL;
+        frame_parms[CC_id]->Nid_cell            = 0;
+        frame_parms[CC_id]->num_MBSFN_config    = 0;
+        frame_parms[CC_id]->nb_antenna_ports_gNB  = 1;
+        frame_parms[CC_id]->nb_antennas_tx      = 1;
+        frame_parms[CC_id]->nb_antennas_rx      = 1;
+
+        frame_parms[CC_id]->nushift             = 0;
+
+        frame_parms[CC_id]->phich_config_common.phich_resource = oneSixth;
+        frame_parms[CC_id]->phich_config_common.phich_duration = normal;
+        // UL RS Config
+        frame_parms[CC_id]->pusch_config_common.ul_ReferenceSignalsPUSCH.cyclicShift = 0;//n_DMRS1 set to 0
+        frame_parms[CC_id]->pusch_config_common.ul_ReferenceSignalsPUSCH.groupHoppingEnabled = 0;
+        frame_parms[CC_id]->pusch_config_common.ul_ReferenceSignalsPUSCH.sequenceHoppingEnabled = 0;
+        frame_parms[CC_id]->pusch_config_common.ul_ReferenceSignalsPUSCH.groupAssignmentPUSCH = 0;
+
+        frame_parms[CC_id]->prach_config_common.rootSequenceIndex=22;
+        frame_parms[CC_id]->prach_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig=1;
+        frame_parms[CC_id]->prach_config_common.prach_ConfigInfo.prach_ConfigIndex=0;
+        frame_parms[CC_id]->prach_config_common.prach_ConfigInfo.highSpeedFlag=0;
+        frame_parms[CC_id]->prach_config_common.prach_ConfigInfo.prach_FreqOffset=0;
+
+    //    downlink_frequency[CC_id][0] = 2680000000; // Use float to avoid issue with frequency over 2^31.
+    //    downlink_frequency[CC_id][1] = downlink_frequency[CC_id][0];
+    //    downlink_frequency[CC_id][2] = downlink_frequency[CC_id][0];
+    //    downlink_frequency[CC_id][3] = downlink_frequency[CC_id][0];
+        //printf("Downlink for CC_id %d frequency set to %u\n", CC_id, downlink_frequency[CC_id][0]);
+        frame_parms[CC_id]->dl_CarrierFreq=downlink_frequency[CC_id][0];
+    */
+  }
+}
+
+void wait_RUs(void) {
+  LOG_I(PHY,"Waiting for RUs to be configured ... RC.ru_mask:%02lx\n", RC.ru_mask);
+  // wait for all RUs to be configured over fronthaul
+  pthread_mutex_lock(&RC.ru_mutex);
+
+  while (RC.ru_mask>0) {
+    pthread_cond_wait(&RC.ru_cond,&RC.ru_mutex);
+    printf("RC.ru_mask:%02lx\n", RC.ru_mask);
+  }
+
+  pthread_mutex_unlock(&RC.ru_mutex);
+  LOG_I(PHY,"RUs configured\n");
+}
+
+void wait_gNBs(void) {
+  int i;
+  int waiting=1;
+
+  while (waiting==1) {
+    printf("Waiting for gNB L1 instances to all get configured ... sleeping 50ms (nb_nr_sL1_inst %d)\n",RC.nb_nr_L1_inst);
+    usleep(50*1000);
+    waiting=0;
+
+    for (i=0; i<RC.nb_nr_L1_inst; i++) {
+      if (RC.gNB[i]->configured==0) {
+        waiting=1;
+        break;
+      }
+    }
+  }
+
+  printf("gNB L1 are configured\n");
+}
+
+/*
+ * helper function to terminate a certain ITTI task
+ */
+void terminate_task(task_id_t task_id, module_id_t mod_id) {
+  LOG_I(GNB_APP, "sending TERMINATE_MESSAGE to task %s (%d)\n", itti_get_task_name(task_id), task_id);
+  MessageDef *msg;
+  msg = itti_alloc_new_message (ENB_APP, 0, TERMINATE_MESSAGE);
+  itti_send_msg_to_task (task_id, ENB_MODULE_ID_TO_INSTANCE(mod_id), msg);
+}
+
+//extern void  free_transport(PHY_VARS_gNB *);
+extern void  nr_phy_free_RU(RU_t *);
+
+int stop_L1L2(module_id_t gnb_id) {
+  LOG_W(GNB_APP, "stopping nr-softmodem\n");
+  oai_exit = 1;
+
+  if (!RC.ru) {
+    LOG_F(GNB_APP, "no RU configured\n");
+    return -1;
+  }
+
+  /* stop trx devices, multiple carrier currently not supported by RU */
+  if (RC.ru[gnb_id]) {
+    if (RC.ru[gnb_id]->rfdevice.trx_stop_func) {
+      RC.ru[gnb_id]->rfdevice.trx_stop_func(&RC.ru[gnb_id]->rfdevice);
+      LOG_I(GNB_APP, "turned off RU rfdevice\n");
+    } else {
+      LOG_W(GNB_APP, "can not turn off rfdevice due to missing trx_stop_func callback, proceeding anyway!\n");
+    }
+
+    if (RC.ru[gnb_id]->ifdevice.trx_stop_func) {
+      RC.ru[gnb_id]->ifdevice.trx_stop_func(&RC.ru[gnb_id]->ifdevice);
+      LOG_I(GNB_APP, "turned off RU ifdevice\n");
+    } else {
+      LOG_W(GNB_APP, "can not turn off ifdevice due to missing trx_stop_func callback, proceeding anyway!\n");
+    }
+  } else {
+    LOG_W(GNB_APP, "no RU found for index %d\n", gnb_id);
+    return -1;
+  }
+
+  /* these tasks need to pick up new configuration */
+  terminate_task(TASK_RRC_ENB, gnb_id);
+  LOG_I(GNB_APP, "calling kill_gNB_proc() for instance %d\n", gnb_id);
+  kill_gNB_proc(gnb_id);
+  LOG_I(GNB_APP, "calling kill_NR_RU_proc() for instance %d\n", gnb_id);
+  kill_NR_RU_proc(gnb_id);
+  oai_exit = 0;
+  //free_transport(RC.gNB[gnb_id]);
+  phy_free_nr_gNB(RC.gNB[gnb_id]);
+  nr_phy_free_RU(RC.ru[gnb_id]);
+  free_lte_top();
+  return 0;
+}
+
+/*
+ * Restart the nr-softmodem after it has been soft-stopped with stop_L1L2()
+ */
+int restart_L1L2(module_id_t gnb_id) {
+  RU_t *ru = RC.ru[gnb_id];
+  MessageDef *msg_p = NULL;
+  LOG_W(GNB_APP, "restarting nr-softmodem\n");
+  /* block threads */
+  sync_var = -1;
+  RC.gNB[gnb_id]->configured = 0;
+  RC.ru_mask |= (1 << ru->idx);
+  set_function_spec_param(RC.ru[gnb_id]);
+  LOG_I(GNB_APP, "attempting to create ITTI tasks\n");
+  // No more rrc thread, as many race conditions are hidden behind
+  rrc_enb_init();
+  itti_mark_task_ready(TASK_RRC_ENB);
+  /* pass a reconfiguration request which will configure everything down to
+   * RC.eNB[i][j]->frame_parms, too */
+  msg_p = itti_alloc_new_message(TASK_ENB_APP, 0, RRC_CONFIGURATION_REQ);
+  RRC_CONFIGURATION_REQ(msg_p) = RC.rrc[gnb_id]->configuration;
+  itti_send_msg_to_task(TASK_RRC_ENB, ENB_MODULE_ID_TO_INSTANCE(gnb_id), msg_p);
+  /* TODO XForms might need to be restarted, but it is currently (09/02/18)
+   * broken, so we cannot test it */
+  wait_gNBs();
+  init_RU_proc(ru);
+  ru->rf_map.card = 0;
+  ru->rf_map.chain = 0; /* CC_id + chain_offset;*/
+  wait_RUs();
+  init_eNB_afterRU();
+  printf("Sending sync to all threads\n");
+  pthread_mutex_lock(&sync_mutex);
+  sync_var=0;
+  pthread_cond_broadcast(&sync_cond);
+  pthread_mutex_unlock(&sync_mutex);
+  return 0;
+}
+
+static  void wait_nfapi_init(char *thread_name) {
+  printf( "waiting for NFAPI PNF connection and population of global structure (%s)\n",thread_name);
+  pthread_mutex_lock( &nfapi_sync_mutex );
+
+  while (nfapi_sync_var<0)
+    pthread_cond_wait( &nfapi_sync_cond, &nfapi_sync_mutex );
+
+  pthread_mutex_unlock(&nfapi_sync_mutex);
+  printf( "NFAPI: got sync (%s)\n", thread_name);
+}
+
+void init_pdcp(void) {
+  uint32_t pdcp_initmask = (IS_SOFTMODEM_NOS1) ?
+    PDCP_USE_NETLINK_BIT | LINK_ENB_PDCP_TO_IP_DRIVER_BIT | ENB_NAS_USE_TUN_BIT | SOFTMODEM_NOKRNMOD_BIT:
+    LINK_ENB_PDCP_TO_GTPV1U_BIT;
+  
+  if (!get_softmodem_params()->nsa) {
+    if (!NODE_IS_DU(RC.nrrrc[0]->node_type)) {
+      pdcp_layer_init();
+      nr_pdcp_module_init(pdcp_initmask, 0);
+    }
+  } else {
+    pdcp_layer_init();
+    nr_pdcp_module_init(pdcp_initmask, 0);
+  }
+}
+
+
+static
+const int mod_id = 0;
+
+static
+int64_t time_now_us(void)
+{
+  struct timespec tms;
+
+  /* The C11 way */
+  /* if (! timespec_get(&tms, TIME_UTC))  */
+
+  /* POSIX.1-2008 way */
+  if (clock_gettime(CLOCK_REALTIME,&tms)) {
+    return -1;
+  }
+  /* seconds, multiplied with 1 million */
+  int64_t micros = tms.tv_sec * 1000000;
+  /* Add full microseconds */
+  micros += tms.tv_nsec/1000;
+  /* round up if necessary */
+  if (tms.tv_nsec % 1000 >= 500) {
+    ++micros;
+  }
+  return micros;
+}
+
+
+static
+void read_mac_sm(mac_ind_msg_t* data)
+{
+  assert(data != NULL);
+
+  data->tstamp = time_now_us();
+
+//  assert(0!=0 && "Read MAC called");
+
+  NR_UEs_t *UE_info = &RC.nrmac[mod_id]->UE_info;
+  size_t num_ues = 0;
+  UE_iterator(UE_info->list, ue) {
+    if (ue)
+      num_ues += 1;
+  }
+
+  data->len_ue_stats = num_ues;
+  if(data->len_ue_stats > 0){
+    data->ue_stats = calloc(data->len_ue_stats, sizeof(mac_ue_stats_impl_t));
+    assert( data->ue_stats != NULL && "Memory exhausted" );
+  }
+
+  size_t i = 0; //TODO
+  UE_iterator(UE_info->list, UE) {
+    const NR_UE_sched_ctrl_t* sched_ctrl = &UE->UE_sched_ctrl;
+    mac_ue_stats_impl_t* rd = &data->ue_stats[i];
+
+    rd->frame = RC.nrmac[mod_id]->frame;
+    rd->slot = RC.nrmac[mod_id]->slot;
+
+    rd->dl_aggr_tbs = UE->mac_stats.dl.total_bytes;
+    rd->ul_aggr_tbs = UE->mac_stats.ul.total_bytes;
+
+    if (is_xlsch_in_slot(RC.nrmac[mod_id]->dlsch_slot_bitmap[rd->slot / 64], rd->slot)) {
+      rd->dl_curr_tbs = UE->mac_stats.dl.current_bytes;
+      rd->dl_sched_rb = UE->mac_stats.dl.current_rbs;
+    }
+    if (is_xlsch_in_slot(RC.nrmac[mod_id]->ulsch_slot_bitmap[rd->slot / 64], rd->slot)) {
+      rd->ul_curr_tbs = UE->mac_stats.ul.current_bytes;
+      rd->ul_sched_rb = sched_ctrl->sched_pusch.rbSize;
+    }
+
+    rd->rnti = UE->rnti;
+    rd->dl_aggr_prb = UE->mac_stats.dl.total_rbs;
+    rd->ul_aggr_prb = UE->mac_stats.ul.total_rbs;
+    rd->dl_aggr_retx_prb = UE->mac_stats.dl.total_rbs_retx;
+    rd->ul_aggr_retx_prb = UE->mac_stats.ul.total_rbs_retx;
+
+    rd->dl_aggr_bytes_sdus = UE->mac_stats.dl.lc_bytes[3];
+    rd->ul_aggr_bytes_sdus = UE->mac_stats.ul.lc_bytes[3];
+
+    rd->dl_aggr_sdus = UE->mac_stats.dl.num_mac_sdu;
+    rd->ul_aggr_sdus = UE->mac_stats.ul.num_mac_sdu;
+
+    rd->pusch_snr = (float) sched_ctrl->pusch_snrx10 / 10; //: float = -64;
+    rd->pucch_snr = (float) sched_ctrl->pucch_snrx10 / 10; //: float = -64;
+
+    rd->wb_cqi = sched_ctrl->CSI_report.cri_ri_li_pmi_cqi_report.wb_cqi_1tb;
+    rd->dl_mcs1 = sched_ctrl->dl_bler_stats.mcs;
+    rd->dl_bler = sched_ctrl->dl_bler_stats.bler;
+    rd->ul_mcs1 = sched_ctrl->ul_bler_stats.mcs;
+    rd->ul_bler = sched_ctrl->ul_bler_stats.bler;
+    rd->dl_mcs2 = 0;
+    rd->ul_mcs2 = 0;
+    rd->phr = sched_ctrl->ph;
+
+    const uint32_t bufferSize = sched_ctrl->estimated_ul_buffer - sched_ctrl->sched_ul_bytes;
+    rd->bsr = bufferSize;
+
+    const size_t numDLHarq = 4;
+    rd->dl_num_harq = numDLHarq;
+    for (uint8_t j = 0; j < numDLHarq; ++j)
+      rd->dl_harq[j] = UE->mac_stats.dl.rounds[j];
+    rd->dl_harq[numDLHarq] = UE->mac_stats.dl.errors;
+
+    const size_t numUlHarq = 4;
+    rd->ul_num_harq = numUlHarq;
+    for (uint8_t j = 0; j < numUlHarq; ++j)
+      rd->ul_harq[j] = UE->mac_stats.ul.rounds[j];
+    rd->ul_harq[numUlHarq] = UE->mac_stats.ul.errors;
+
+    ++i;
+  }
+}
+
+static
+uint32_t num_act_rb(NR_UEs_t* UE_info)
+{
+  assert(UE_info!= NULL);
+
+
+  uint32_t act_rb = 0;
+  UE_iterator(UE_info->list, UE) {
+    uint16_t const rnti = UE->rnti;
+    for(int rb_id = 1; rb_id < 6; ++rb_id ){
+      nr_rlc_statistics_t rlc = {0};
+      const int srb_flag = 0;
+      const bool rc = nr_rlc_get_statistics(rnti, srb_flag, rb_id, &rlc);
+      if(rc) ++act_rb;
+    }
+  }
+  return act_rb;
+}
+
+
+static
+void read_rlc_sm(rlc_ind_msg_t* data)
+{
+  assert(data != NULL);
+
+  // use MAC structures to get RNTIs
+  NR_UEs_t *UE_info = &RC.nrmac[mod_id]->UE_info;
+  uint32_t const act_rb = num_act_rb(UE_info);
+
+  //assert(0!=0 && "Read RLC called");
+
+  data->len = act_rb;
+  if(data->len > 0){
+	  data->rb = calloc(data->len, sizeof(rlc_radio_bearer_stats_t));
+	  assert(data->rb != NULL && "Memory exhausted");
+  }
+
+  data->tstamp = time_now_us();
+
+  uint32_t i = 0;
+  UE_iterator(UE_info->list, UE) {
+    uint16_t const rnti = UE->rnti;
+    //for every LC ID
+    for(int rb_id = 1; rb_id < 6; ++rb_id ){
+
+      // activate the rlc to calculate the average tx time
+      nr_rlc_activate_avg_time_to_tx(rnti, rb_id, 1);
+
+      nr_rlc_statistics_t rb_rlc = {0};
+      const int srb_flag = 0;
+      const bool rc = nr_rlc_get_statistics(rnti, srb_flag, rb_id, &rb_rlc);
+      if(!rc) continue;
+      rlc_radio_bearer_stats_t* sm_rb = &data->rb[i];
+
+      /* TX */
+      sm_rb->txpdu_pkts = rb_rlc.txpdu_pkts;
+      sm_rb->txpdu_bytes =  rb_rlc.txpdu_bytes;        /* aggregated amount of transmitted bytes in RLC PDUs */
+      sm_rb->txpdu_wt_ms += rb_rlc.txsdu_avg_time_to_tx;      /* aggregated head-of-line tx packet waiting time to be transmitted (i.e. send to the MAC layer) */
+      sm_rb->txpdu_dd_pkts = rb_rlc.txpdu_dd_pkts;      /* aggregated number of dropped or discarded tx packets by RLC */
+      sm_rb->txpdu_dd_bytes = rb_rlc.txpdu_dd_bytes;     /* aggregated amount of bytes dropped or discarded tx packets by RLC */
+      sm_rb->txpdu_retx_pkts = rb_rlc.txpdu_retx_pkts;    /* aggregated number of tx pdus/pkts to be re-transmitted (only applicable to RLC AM) */
+      sm_rb->txpdu_retx_bytes = rb_rlc.txpdu_retx_bytes ;   /* aggregated amount of bytes to be re-transmitted (only applicable to RLC AM) */
+      sm_rb->txpdu_segmented = rb_rlc.txpdu_segmented  ;    /* aggregated number of segmentations */
+      sm_rb->txpdu_status_pkts = rb_rlc.txpdu_status_pkts  ;  /* aggregated number of tx status pdus/pkts (only applicable to RLC AM) */
+      sm_rb->txpdu_status_bytes = rb_rlc.txpdu_status_bytes  ; /* aggregated amount of tx status bytes  (only applicable to RLC AM) */
+      sm_rb->txbuf_occ_bytes = rb_rlc.txbuf_occ_bytes  ;    /* current tx buffer occupancy in terms of amount of bytes (average: NOT IMPLEMENTED) */
+      sm_rb->txbuf_occ_pkts = rb_rlc.txbuf_occ_pkts  ;     /* current tx buffer occupancy in terms of number of packets (average: NOT IMPLEMENTED) */
+
+      /* RX */
+      sm_rb->rxpdu_pkts = rb_rlc.rxpdu_pkts ;         /* aggregated number of received RLC PDUs */
+      sm_rb->rxpdu_bytes = rb_rlc.rxpdu_bytes ;        /* amount of bytes received by the RLC */
+      sm_rb->rxpdu_dup_pkts = rb_rlc.rxpdu_dup_pkts ;     /* aggregated number of duplicate packets */
+      sm_rb->rxpdu_dup_bytes = rb_rlc.rxpdu_dup_bytes ;    /* aggregated amount of duplicated bytes */
+      sm_rb->rxpdu_dd_pkts = rb_rlc.rxpdu_dd_pkts ;      /* aggregated number of rx packets dropped or discarded by RLC */
+      sm_rb->rxpdu_dd_bytes = rb_rlc.rxpdu_dd_bytes ;     /* aggregated amount of rx bytes dropped or discarded by RLC */
+      sm_rb->rxpdu_ow_pkts = rb_rlc.rxpdu_ow_pkts ;      /* aggregated number of out of window received RLC pdu */
+      sm_rb->rxpdu_ow_bytes = rb_rlc.rxpdu_ow_bytes ;     /* aggregated number of out of window bytes received RLC pdu */
+      sm_rb->rxpdu_status_pkts = rb_rlc.rxpdu_status_pkts ;  /* aggregated number of rx status pdus/pkts (only applicable to RLC AM) */
+      sm_rb->rxpdu_status_bytes = rb_rlc.rxpdu_status_bytes ; /* aggregated amount of rx status bytes  (only applicable to RLC AM) */
+
+      sm_rb->rxbuf_occ_bytes = rb_rlc.rxbuf_occ_bytes ;    /* current rx buffer occupancy in terms of amount of bytes (average: NOT IMPLEMENTED) */
+      sm_rb->rxbuf_occ_pkts = rb_rlc.rxbuf_occ_pkts ;     /* current rx buffer occupancy in terms of number of packets (average: NOT IMPLEMENTED) */
+
+      /* TX */
+      sm_rb->txsdu_pkts = rb_rlc.txsdu_pkts ;         /* number of SDUs delivered */
+      sm_rb->txsdu_bytes = rb_rlc.txsdu_bytes ;        /* number of bytes of SDUs delivered */
+
+      /* RX */
+      sm_rb->rxsdu_pkts = rb_rlc.rxsdu_pkts ;         /* number of SDUs received */
+      sm_rb->rxsdu_bytes = rb_rlc.rxsdu_bytes ;        /* number of bytes of SDUs received */
+      sm_rb->rxsdu_dd_pkts = rb_rlc.rxsdu_dd_pkts ;      /* number of dropped or discarded SDUs */
+      sm_rb->rxsdu_dd_bytes = rb_rlc.rxsdu_dd_bytes ;     /* number of bytes of SDUs dropped or discarded */
+
+      sm_rb->mode = rb_rlc.mode;               /* 0: RLC AM, 1: RLC UM, 2: RLC TM */
+      sm_rb->rnti = rnti;
+      sm_rb->rbid = rb_id;
+
+      ++i;
+    }
+  }
+}
+
+static
+void read_pdcp_sm(pdcp_ind_msg_t* data)
+{
+  assert(data != NULL);
+
+  //assert(0!=0 && "Calling PDCP");
+  // for the moment and while we don't have a split base station, we use the
+  // MAC structures to obtain the RNTIs which we use to query the PDCP
+  NR_UEs_t *UE_info = &RC.nrmac[mod_id]->UE_info;
+  uint32_t const act_rb = num_act_rb(UE_info);
+
+  data->len = act_rb;
+  data->tstamp = time_now_us();
+//  data->slot = 0;
+
+  if(data->len > 0){
+    data->rb = calloc(data->len , sizeof(pdcp_radio_bearer_stats_t));
+    assert(data->rb != NULL && "Memory exhausted!");
+  }
+
+  size_t i = 0;
+  UE_iterator(UE_info->list, UE) {
+
+    const int rnti = UE->rnti;
+    for(size_t rb_id = 1; rb_id < 6; ++rb_id){
+      nr_pdcp_statistics_t pdcp = {0};
+
+      const int srb_flag = 0;
+      const bool rc = nr_pdcp_get_statistics(rnti, srb_flag, rb_id, &pdcp);
+
+      if(!rc) continue;
+
+      pdcp_radio_bearer_stats_t* rd = &data->rb[i];
+
+
+      rd->txpdu_pkts = pdcp.txpdu_pkts ;     /* aggregated number of tx packets */
+      rd->txpdu_bytes = pdcp.txpdu_bytes;    /* aggregated bytes of tx packets */
+      rd->txpdu_sn = pdcp.txpdu_sn ;       /* current sequence number of last tx packet (or TX_NEXT) */
+      rd->rxpdu_pkts = pdcp.rxpdu_pkts ;     /* aggregated number of rx packets */
+      rd->rxpdu_bytes = pdcp.rxpdu_bytes ;    /* aggregated bytes of rx packets */
+      rd->rxpdu_sn = pdcp.rxpdu_sn ;       /* current sequence number of last rx packet (or  RX_NEXT) */
+      rd->rxpdu_oo_pkts = pdcp.rxpdu_oo_pkts  ;       /* aggregated number of out-of-order rx pkts  (or RX_REORD) */
+      rd->rxpdu_oo_bytes = pdcp.rxpdu_oo_bytes  ; /* aggregated amount of out-of-order rx bytes */
+      rd->rxpdu_dd_pkts = pdcp.rxpdu_dd_pkts  ;  /* aggregated number of duplicated discarded packets (or dropped packets because of other reasons such as integrity failure) (or RX_DELIV) */
+      rd->rxpdu_dd_bytes = pdcp.rxpdu_dd_bytes; /* aggregated amount of discarded packets' bytes */
+      rd->rxpdu_ro_count = pdcp.rxpdu_ro_count  ; /* this state variable indicates the COUNT value following the COUNT value associated with the PDCP Data PDU which triggered t-Reordering. (RX_REORD) */
+      rd->txsdu_pkts = pdcp.txsdu_pkts ;     /* number of SDUs delivered */
+      rd->txsdu_bytes = pdcp.txsdu_bytes ;    /* number of bytes of SDUs delivered */
+      rd->rxsdu_pkts = pdcp.rxsdu_pkts ;     /* number of SDUs received */
+      rd->rxsdu_bytes = pdcp.rxsdu_bytes ;    /* number of bytes of SDUs received */
+      rd->rnti = rnti;
+      rd->mode = pdcp.mode;               /* 0: PDCP AM, 1: PDCP UM, 2: PDCP TM */
+      rd->rbid = rb_id;
+
+      ++i;
+    }
+  }
+}
+
+static
+void read_gtp_sm(gtp_ind_msg_t* data)
+{
+  assert(data != NULL);
+
+  data->tstamp = time_now_us();
+
+  NR_UEs_t *UE_info = &RC.nrmac[mod_id]->UE_info;
+  size_t num_ues = 0;
+  UE_iterator(UE_info->list, ue) {
+    if (ue)
+      num_ues += 1;
+  }
+
+  data->len = num_ues;
+  if(data->len > 0){
+    data->ngut = calloc(data->len, sizeof(gtp_ngu_t_stats_t) );
+    assert(data->ngut != NULL);
+  }
+
+  size_t i = 0;
+  UE_iterator(UE_info->list, UE)
+  {
+    uint16_t const rnti = UE->rnti;
+    struct rrc_gNB_ue_context_s *ue_context_p = NULL;
+    ue_context_p = rrc_gNB_get_ue_context(RC.nrrrc[mod_id], rnti);
+    if (ue_context_p != NULL) {
+      int nb_pdu_session = ue_context_p->ue_context.setup_pdu_sessions - 1;
+      data->ngut[i].rnti = ue_context_p->ue_context.rnti;
+      data->ngut[i].teidgnb = ue_context_p->ue_context.pduSession[nb_pdu_session].param.gtp_teid;
+      // TODO: one PDU session has multiple QoS Flow
+      int nb_qos_flow = ue_context_p->ue_context.pduSession[nb_pdu_session].param.nb_qos -1;
+      data->ngut[i].qfi = ue_context_p->ue_context.pduSession[nb_pdu_session].param.qos[nb_qos_flow].qfi;
+      // TODO: not sure for the upf tunnel id
+      data->ngut[i].teidupf = ue_context_p->ue_context.gnb_gtp_teid[0];
+    } else {
+      LOG_W(NR_RRC,"rrc_gNB_get_ue_context return NULL\n");
+      if (data->ngut != NULL) free(data->ngut);
+    }
+    i++;
+  }
+
+}
+
+static
+void read_kpm_sm(kpm_ind_data_t* data)
+{
+  assert(data != NULL);
+
+  // Fill KPM indication header
+  kpm_ind_hdr_t* hdr = &data->hdr;
+  int64_t t = time_now_us();
+  hdr->collectStartTime = t / 1000000; // needs to be truncated to 32 bits to arrive to a resolution of seconds
+  hdr->fileFormatversion = NULL;
+  hdr->senderName = NULL;
+  hdr->senderType = NULL;
+  hdr->vendorName = NULL;
+
+  // Fill KPM indication message
+  kpm_ind_msg_t* msg = &data->msg;
+
+  // TODO: assign MeaData_len according to eventPeriod/granulPeriod from the action definition or subscription request
+  msg->MeasData_len = 1;
+  if (msg->MeasData_len > 0) {
+    msg->MeasData = calloc(msg->MeasData_len, sizeof(adapter_MeasDataItem_t));
+    assert(msg->MeasData != NULL && "Memory exhausted" );
+  }
+
+  // get the number of connected UEs
+  NR_UEs_t *UE_info = &RC.nrmac[mod_id]->UE_info;
+  size_t num_ues = 0;
+  UE_iterator(UE_info->list, ue) {
+    if (ue)
+      num_ues += 1;
+  }
+
+  if (num_ues > 0) {
+    // get the info to calculate the resource utilization
+    NR_ServingCellConfigCommon_t *scc = RC.nrmac[mod_id]->common_channels[0].ServingCellConfigCommon;
+    int cur_slot = RC.nrmac[mod_id]->slot;
+    // int num_dl_slots = scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofDownlinkSlots;
+    // get total number of available resource blocks
+    int n_rb_sched = 0;
+    if (UE_info->list[0] != NULL) {
+      /* Get bwpSize and TDA from the first UE */
+      /* This is temporary and it assumes all UEs have the same BWP and TDA*/
+      NR_UE_info_t *UE = UE_info->list[0];
+      NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
+      NR_UE_DL_BWP_t *current_BWP = &UE->current_DL_BWP;
+      const int tda = get_dl_tda(RC.nrmac[mod_id], scc, cur_slot);
+      int startSymbolIndex, nrOfSymbols;
+      const struct NR_PDSCH_TimeDomainResourceAllocationList *tdaList = current_BWP->tdaList;
+      AssertFatal(tda < tdaList->list.count, "time_domain_allocation %d>=%d\n", tda, tdaList->list.count);
+      const int startSymbolAndLength = tdaList->list.array[tda]->startSymbolAndLength;
+      SLIV2SL(startSymbolAndLength, &startSymbolIndex, &nrOfSymbols);
+      const int coresetid = sched_ctrl->coreset->controlResourceSetId;
+      const uint16_t bwpSize = coresetid == 0 ? RC.nrmac[mod_id]->cset0_bwp_size : current_BWP->BWPSize;
+      const uint16_t BWPStart = coresetid == 0 ? RC.nrmac[mod_id]->cset0_bwp_start : current_BWP->BWPStart;
+      const uint16_t slbitmap = SL_to_bitmap(startSymbolIndex, nrOfSymbols);
+      uint16_t *vrb_map = RC.nrmac[mod_id]->common_channels[0].vrb_map;
+      uint16_t rballoc_mask[bwpSize];
+      for (int i = 0; i < bwpSize; i++) {
+        // calculate mask: init with "NOT" vrb_map:
+        // if any RB in vrb_map is blocked (1), the current RBG will be 0
+        rballoc_mask[i] = (~vrb_map[i + BWPStart]) & 0x3fff; //bitwise not and 14 symbols
+        // if all the pdsch symbols are free
+        if ((rballoc_mask[i] & slbitmap) == slbitmap) {
+          n_rb_sched++;
+        }
+      }
+    }
+
+    // TODO: assign the MeasData every granulPeriod
+    for (size_t i = 0; i < msg->MeasData_len; i++) {
+      adapter_MeasDataItem_t* item = &msg->MeasData[i];
+
+      // TODO: assign measRecord_len according to
+      //  (1) the length of Measurements Information List IE (format1) or
+      //  (2) Measurements Information Condition UE List IE (format2)
+      //  from the action definition or subscription request
+
+      // TODO: only support KPM format 1, and it only can handle one UE's information
+      //  assume to record one data: DL resource utilization
+      item->measRecord_len = 1;
+      if (item->measRecord_len > 0) {
+        item->measRecord = calloc(item->measRecord_len, sizeof(adapter_MeasRecord_t));
+        assert(item->measRecord != NULL && "Memory exhausted");
+      }
+
+      UE_iterator(UE_info->list, UE)
+      {
+        int dl_rb_usage = 0;
+        if (is_xlsch_in_slot(RC.nrmac[mod_id]->dlsch_slot_bitmap[cur_slot / 64], cur_slot))
+          dl_rb_usage = UE->mac_stats.dl.current_rbs*100/n_rb_sched;
+
+        // TODO: go through the measRecord according to the Measurements Information (format 1) or Information Condition UE (format 2) List IE
+        adapter_MeasRecord_t *record_PrbDlUsage = &item->measRecord[0];
+        record_PrbDlUsage->type = MeasRecord_int;
+        record_PrbDlUsage->int_val = dl_rb_usage;
+      }
+
+      // incompleteFlag = -1, the data is reliable
+      item->incompleteFlag = -1;
+    }
+
+    // TODO: assign MeasInfo_len according to the action definition or subscription request
+    msg->MeasInfo_len = 1;
+    if (msg->MeasInfo_len > 0) {
+      msg->MeasInfo = calloc(msg->MeasInfo_len, sizeof(MeasInfo_t));
+      assert(msg->MeasInfo != NULL && "Memory exhausted" );
+
+      MeasInfo_t* info = &msg->MeasInfo[0];
+      info->meas_type = KPM_V2_MEASUREMENT_TYPE_NAME;
+      char* measName = "PrbDlUsage";
+      info->measName.len = strlen(measName);
+      info->measName.buf = malloc(strlen(measName));
+      assert(info->measName.buf != NULL && "memory exhausted");
+      memcpy(info->measName.buf, measName, msg->MeasInfo[0].measName.len);
+
+      // TODO: assign labelInfo_len according to the action definition (?)
+      info->labelInfo_len = 1;
+      info->labelInfo = calloc(info->labelInfo_len, sizeof(adapter_LabelInfoItem_t));
+      assert(info->labelInfo != NULL && "memory exhausted");
+      adapter_LabelInfoItem_t* label = &info->labelInfo[0];
+      label->noLabel = calloc(1, sizeof(long));
+      assert(label->noLabel != NULL && "memory exhausted");
+      *(label->noLabel) = 0;
+    }
+  } else {
+    for (size_t i = 0; i < msg->MeasData_len; i++) {
+      adapter_MeasDataItem_t* item = &msg->MeasData[i];
+      item->measRecord_len = 1;
+      if (item->measRecord_len > 0) {
+        item->measRecord = calloc(item->measRecord_len, sizeof(adapter_MeasRecord_t));
+        assert(item->measRecord != NULL && "Memory exhausted");
+      }
+
+      adapter_MeasRecord_t *record_nodata = &item->measRecord[0];
+      record_nodata->type = MeasRecord_int;
+      record_nodata->int_val = 0;
+
+      // incompleteFlag = 0, the data is not reliable
+      item->incompleteFlag = 0;
+    }
+    msg->MeasInfo_len = 0;
+    msg->MeasInfo = NULL;
+  }
+
+  msg->granulPeriod = NULL;
+}
+
+
+
+static
+void read_RAN(sm_ag_if_rd_t* data)
+{
+  assert(data != NULL);
+  assert(data->type == MAC_STATS_V0
+        || data->type == RLC_STATS_V0
+        || data->type == PDCP_STATS_V0
+        || data->type == GTP_STATS_V0
+        || data->type == KPM_STATS_V0
+        );
+
+  if(data->type == MAC_STATS_V0 ){
+    read_mac_sm(&data->mac_stats.msg);
+  }else if(data->type == RLC_STATS_V0) {
+    read_rlc_sm(&data->rlc_stats.msg);
+  } else if(data->type == PDCP_STATS_V0){
+    read_pdcp_sm(&data->pdcp_stats.msg);
+  } else if(data->type == GTP_STATS_V0){
+    read_gtp_sm(&data->gtp_stats.msg);
+  } else if(data->type == KPM_STATS_V0){
+    read_kpm_sm(&data->kpm_stats);
+  } else {
+    assert(0!=0 && "Unknown data type!");
+  }
+
+}
+
+static
+sm_ag_if_ans_t write_RAN(sm_ag_if_wr_t const* data)
+{
+  assert(data != NULL);
+  assert(0!=0 && "Not implemented");
+  sm_ag_if_ans_t ans = {.type = MAC_AGENT_IF_CTRL_ANS_V0 };
+
+  return ans;
+}
+
+int main( int argc, char **argv ) {
+  int ru_id, CC_id = 0;
+  start_background_system();
+
+  ///static configuration for NR at the moment
+  if ( load_configmodule(argc,argv,CONFIG_ENABLECMDLINEONLY) == NULL) {
+    exit_fun("[SOFTMODEM] Error, configuration module init failed\n");
+  }
+
+  set_softmodem_sighandler();
+#ifdef DEBUG_CONSOLE
+  setvbuf(stdout, NULL, _IONBF, 0);
+  setvbuf(stderr, NULL, _IONBF, 0);
+#endif
+  mode = normal_txrx;
+  memset(&openair0_cfg[0],0,sizeof(openair0_config_t)*MAX_CARDS);
+  memset(tx_max_power,0,sizeof(int)*MAX_NUM_CCs);
+  logInit();
+  set_latency_target();
+  printf("Reading in command-line options\n");
+  get_options ();
+
+  EPC_MODE_ENABLED = !IS_SOFTMODEM_NOS1;
+
+  if (CONFIG_ISFLAGSET(CONFIG_ABORT) ) {
+    fprintf(stderr,"Getting configuration failed\n");
+    exit(-1);
+  }
+
+
+  openair0_cfg[0].threequarter_fs = threequarter_fs;
+
+  if (get_softmodem_params()->do_ra)
+    AssertFatal(get_softmodem_params()->phy_test == 0,"RA and phy_test are mutually exclusive\n");
+
+  if (get_softmodem_params()->sa)
+    AssertFatal(get_softmodem_params()->phy_test == 0,"Standalone mode and phy_test are mutually exclusive\n");
+
+#if T_TRACER
+  T_Config_Init();
+#endif
+  //randominit (0);
+  set_taus_seed (0);
+  printf("configuring for RAU/RRU\n");
+
+  if (opp_enabled ==1) {
+    reset_opp_meas();
+  }
+
+  cpuf=get_cpu_freq_GHz();
+  itti_init(TASK_MAX, tasks_info);
+  // initialize mscgen log after ITTI
+  init_opt();
+  if(PDCP_USE_NETLINK && !IS_SOFTMODEM_NOS1) {
+    netlink_init();
+    if (get_softmodem_params()->nsa) {
+      init_pdcp();
+    }
+  }
+#ifndef PACKAGE_VERSION
+#  define PACKAGE_VERSION "UNKNOWN-EXPERIMENTAL"
+#endif
+  LOG_I(HW, "Version: %s\n", PACKAGE_VERSION);
+
+  if (RC.nb_nr_L1_inst > 0)
+    RCconfig_NR_L1();
+
+  // don't create if node doesn't connect to RRC/S1/GTP
+  int ret=create_gNB_tasks(1);
+  AssertFatal(ret==0,"cannot create ITTI tasks\n");
+
+  /* Start the agent. If it is turned off in the configuration, it won't start */
+  /*
+  RCconfig_nr_flexran();
+
+  for (i = 0; i < RC.nb_nr_L1_inst; i++) {
+    flexran_agent_start(i);
+  }
+  */
+  // init UE_PF_PO and mutex lock
+  pthread_mutex_init(&ue_pf_po_mutex, NULL);
+  memset (&UE_PF_PO[0][0], 0, sizeof(UE_PF_PO_t)*NUMBER_OF_UE_MAX*MAX_NUM_CCs);
+  mlockall(MCL_CURRENT | MCL_FUTURE);
+  pthread_cond_init(&sync_cond,NULL);
+  pthread_mutex_init(&sync_mutex, NULL);
+  usleep(1000);
+
+  if (NFAPI_MODE) {
+    printf("NFAPI*** - mutex and cond created - will block shortly for completion of PNF connection\n");
+    pthread_cond_init(&sync_cond,NULL);
+    pthread_mutex_init(&sync_mutex, NULL);
+  }
+
+  const char *nfapi_mode_str = "<UNKNOWN>";
+
+  switch(NFAPI_MODE) {
+    case 0:
+      nfapi_mode_str = "MONOLITHIC";
+      break;
+
+    case 1:
+      nfapi_mode_str = "PNF";
+      break;
+
+    case 2:
+      nfapi_mode_str = "VNF";
+      break;
+
+    default:
+      nfapi_mode_str = "<UNKNOWN NFAPI MODE>";
+      break;
+  }
+
+  printf("NFAPI MODE:%s\n", nfapi_mode_str);
+
+  printf("START MAIN THREADS\n");
+  // start the main threads
+  number_of_cards = 1;
+  printf("RC.nb_nr_L1_inst:%d\n", RC.nb_nr_L1_inst);
+
+  if (RC.nb_nr_L1_inst > 0) {
+    printf("Initializing gNB threads single_thread_flag:%d wait_for_sync:%d\n", single_thread_flag,wait_for_sync);
+    init_gNB(single_thread_flag,wait_for_sync);
+  }
+
+  printf("wait_gNBs()\n");
+  wait_gNBs();
+  printf("About to Init RU threads RC.nb_RU:%d\n", RC.nb_RU);
+  int sl_ahead=6;
+  if (RC.nb_RU >0) {
+    printf("Initializing RU threads\n");
+    init_NR_RU(get_softmodem_params()->rf_config_file);
+
+    for (ru_id=0; ru_id<RC.nb_RU; ru_id++) {
+      RC.ru[ru_id]->rf_map.card=0;
+      RC.ru[ru_id]->rf_map.chain=CC_id+chain_offset;
+      if (ru_id==0) sl_ahead = RC.ru[ru_id]->sl_ahead;	
+      else AssertFatal(RC.ru[ru_id]->sl_ahead != RC.ru[0]->sl_ahead,"RU %d has different sl_ahead %d than RU 0 %d\n",ru_id,RC.ru[ru_id]->sl_ahead,RC.ru[0]->sl_ahead);
+    }
+    
+  }
+
+  config_sync_var=0;
+
+//////////////////////////////////
+//////////////////////////////////
+//// Init the E2 Agent
+
+  sleep(2);
+  const gNB_RRC_INST* rrc = RC.nrrrc[mod_id];
+  assert(rrc != NULL && "rrc cannot be NULL");
+
+  const int mcc = rrc->configuration.mcc[0];
+  const int mnc = rrc->configuration.mnc[0];
+  const int mnc_digit_len = rrc->configuration.mnc_digit_length[0];
+  const ngran_node_t node_type = rrc->node_type;
+  int nb_id = 0;
+  int cu_du_id = 0;
+  if (node_type == ngran_gNB) {
+    nb_id = rrc->configuration.cell_identity;
+  } else if (node_type == ngran_gNB_DU) {
+    cu_du_id = rrc->configuration.cell_identity;
+    nb_id = rrc->configuration.cell_identity;
+  } else if (node_type == ngran_gNB_CU) {
+    cu_du_id = rrc->node_id;
+    nb_id = rrc->node_id;
+  } else {
+    LOG_E(NR_RRC, "not supported ran type detect\n");
+  }
+  sm_io_ag_t io = {.read = read_RAN, .write = write_RAN};
+  printf("[E2 NODE]: mcc = %d mnc = %d mnc_digit = %d nd_id = %d \n", mcc, mnc, mnc_digit_len, nb_id);
+
+  // TODO: need to fix, parse the FlexRIC config in runtime
+  int const agent_argc = 1;
+  char** agent_argv = NULL;
+  fr_args_t ric_args = init_fr_args(agent_argc, agent_argv);
+  // TODO: integrate with oai config
+  char* conf_dir = getenv("FLEXRIC_CONF");
+  char* lib_dir = getenv("FLEXRIC_LIB_DIR");
+
+  if (conf_dir != NULL)
+    strcpy(ric_args.conf_file, conf_dir);
+  else
+    strcpy(ric_args.conf_file, "/usr/local/etc/flexric/flexric.conf");
+  if (lib_dir != NULL)
+    strcpy(ric_args.libs_dir, lib_dir);
+  else
+    strcpy(ric_args.libs_dir, "/usr/local/lib/flexric/");
+
+  init_agent_api( mcc, mnc, mnc_digit_len, nb_id, cu_du_id, node_type, io, &ric_args);
+//////////////////////////////////
+//////////////////////////////////
+
+  if (NFAPI_MODE==NFAPI_MODE_PNF) {
+    wait_nfapi_init("main?");
+  }
+
+  if (RC.nb_nr_L1_inst > 0) {
+    printf("wait RUs\n");
+    wait_RUs();
+    printf("ALL RUs READY!\n");
+    printf("RC.nb_RU:%d\n", RC.nb_RU);
+    // once all RUs are ready initialize the rest of the gNBs ((dependence on final RU parameters after configuration)
+    printf("ALL RUs ready - init gNBs\n");
+
+    for (int idx=0;idx<RC.nb_nr_L1_inst;idx++) RC.gNB[idx]->if_inst->sl_ahead = sl_ahead;
+    if(IS_SOFTMODEM_DOSCOPE) {
+      sleep(1);
+      scopeParms_t p;
+      p.argc=&argc;
+      p.argv=argv;
+      p.gNB=RC.gNB[0];
+      p.ru=RC.ru[0];
+      load_softscope("nr",&p);
+    }
+
+    if (NFAPI_MODE != NFAPI_MODE_PNF && NFAPI_MODE != NFAPI_MODE_VNF) {
+      printf("Not NFAPI mode - call init_eNB_afterRU()\n");
+      init_eNB_afterRU();
+    } else {
+      printf("NFAPI mode - DO NOT call init_gNB_afterRU()\n");
+    }
+
+    printf("ALL RUs ready - ALL gNBs ready\n");
+    // connect the TX/RX buffers
+    printf("Sending sync to all threads\n");
+    pthread_mutex_lock(&sync_mutex);
+    sync_var=0;
+    pthread_cond_broadcast(&sync_cond);
+    pthread_mutex_unlock(&sync_mutex);
+  }
+
+  // wait for end of program
+  printf("Entering ITTI signals handler\n");
+  printf("TYPE <CTRL-C> TO TERMINATE\n");
+  itti_wait_tasks_end();
+  printf("Returned from ITTI signal handler\n");
+  oai_exit=1;
+  printf("oai_exit=%d\n",oai_exit);
+
+  // cleanup
+  if (RC.nb_nr_L1_inst > 0)
+    stop_gNB(RC.nb_nr_L1_inst);
+
+  if (RC.nb_RU > 0)
+    stop_RU(RC.nb_RU);
+
+  /* release memory used by the RU/gNB threads (incomplete), after all
+   * threads have been stopped (they partially use the same memory) */
+  for (int inst = 0; inst < RC.nb_RU; inst++) {
+    nr_phy_free_RU(RC.ru[inst]);
+  }
+
+  for (int inst = 0; inst < RC.nb_nr_L1_inst; inst++) {
+    phy_free_nr_gNB(RC.gNB[inst]);
+  }
+
+  pthread_cond_destroy(&sync_cond);
+  pthread_mutex_destroy(&sync_mutex);
+  pthread_cond_destroy(&nfapi_sync_cond);
+  pthread_mutex_destroy(&nfapi_sync_mutex);
+  pthread_mutex_destroy(&ue_pf_po_mutex);
+
+  // *** Handle per CC_id openair0
+
+  for(ru_id = 0; ru_id < RC.nb_RU; ru_id++) {
+    if (RC.ru[ru_id]->ifdevice.trx_end_func)
+      RC.ru[ru_id]->ifdevice.trx_end_func(&RC.ru[ru_id]->ifdevice);
+  }
+
+  logClean();
+  printf("Bye.\n");
+  return 0;
+}
diff --git a/openairinterface5g/openairinterface-conf/run_SIMU_oai_ran.sh b/openairinterface5g/openairinterface-conf/run_SIMU_oai_ran.sh
new file mode 100755
index 0000000000000000000000000000000000000000..310978a4b4fc4123f0fa8994fef48dd4afcabe60
--- /dev/null
+++ b/openairinterface5g/openairinterface-conf/run_SIMU_oai_ran.sh
@@ -0,0 +1,22 @@
+#!/bin/bash
+
+sudo apt-get install tmux -y
+
+session="oai"
+
+## Split into 4 panes
+tmux new-session -d -s $session
+tmux split-window -h \; split-window -d;
+
+## Run OAI RAN
+
+## Run OAI CU
+tmux send-keys -t 0 'cd ~/oai/cmake_targets/ran_build/build/' ENTER \; send-keys -t 0 'sudo RFSIMULATOR=server ./nr-softmodem --rfsim --sa -O ../../../ci-scripts/conf_files/gNB_SA_DU.conf' ENTER;
+
+## Run OAI DU
+tmux send-keys -t 1 'cd ~/oai/cmake_targets/ran_build/build/' ENTER \; send-keys -t 1 'sudo RFSIMULATOR=server ./nr-softmodem --rfsim --sa -O ../../../ci-scripts/conf_files/gNB_SA_CU.conf' ENTER;
+
+## Run FlexRIC
+tmux send-keys -t 2 'cd ~/flexric/' ENTER \; send-keys -t 2 './build/examples/ric/nearRT-RIC' ENTER;
+
+tmux attach-session -t $session
diff --git a/openairinterface5g/openairinterface-conf/run_SIMU_oai_ran_w_UE.sh b/openairinterface5g/openairinterface-conf/run_SIMU_oai_ran_w_UE.sh
new file mode 100755
index 0000000000000000000000000000000000000000..ce3b25b213634940dfdc54498acbbf28c0a12aed
--- /dev/null
+++ b/openairinterface5g/openairinterface-conf/run_SIMU_oai_ran_w_UE.sh
@@ -0,0 +1,27 @@
+#!/bin/bash
+
+sudo apt-get install tmux
+
+session="oai"
+
+## Split into 4 panes
+tmux new-session -d -s $session
+tmux split-window -h \; split-window -d;
+tmux swapp -s 0; 
+tmux split-window -d;
+
+## Run OAI RAN
+
+## Run OAI CU
+tmux send-keys -t 0 'cd ~/oai/cmake_targets/ran_build/build/' ENTER \; send-keys -t 0 'sudo RFSIMULATOR=server ./nr-softmodem --rfsim --sa -O ../../../ci-scripts/conf_files/gNB_SA_CU.conf' ENTER;
+
+## Run OAI DU
+tmux send-keys -t 1 'cd ~/oai/cmake_targets/ran_build/build/' ENTER \; send-keys -t 1 'sudo RFSIMULATOR=server ./nr-softmodem --rfsim --sa -O ../../../ci-scripts/conf_files/gNB_SA_DU.conf' ENTER;
+
+## Run FlexRIC
+tmux send-keys -t 2 'cd ~/flexric/' ENTER \; send-keys -t 2 './build/examples/ric/nearRT-RIC' ENTER;
+
+## Run OAI UE
+tmux send-keys -t 3 'cd ~/oai/cmake_targets/ran_build/build/' ENTER \; send-keys -t 3 'sleep 30' ENTER \; send-keys -t 3 'sudo RFSIMULATOR=10.7.229.69 ./nr-uesoftmodem -r 106 --numerology 1 --band 78 -C 3619200000 --rfsim --sa --nokrnmod -O ../../../targets/PROJECTS/GENERIC-NR-5GC/CONF/ue.conf' ENTER;
+
+tmux attach-session -t $session
diff --git a/openairinterface5g/openairinterface-conf/ue.conf b/openairinterface5g/openairinterface-conf/ue.conf
new file mode 100644
index 0000000000000000000000000000000000000000..73207fcfd5e34cfc767a895fde43c8c2da71b0ec
--- /dev/null
+++ b/openairinterface5g/openairinterface-conf/ue.conf
@@ -0,0 +1,8 @@
+uicc0 = {
+imsi = "001010000000001";
+key = "fec86ba6eb707ed08905757b1bb44b8f";
+opc= "C42449363BBAD02B66D16BC975D77CC1";
+dnn= "oai";
+nssai_sst=1;
+nssai_sd=1;
+}
diff --git a/openairinterface5g/openairinterface-install-scripts/.gitkeep b/openairinterface5g/openairinterface-install-scripts/.gitkeep
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/openairinterface5g/openairinterface-install-scripts/README.md b/openairinterface5g/openairinterface-install-scripts/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..1f44668f77c8c6a7e0011a291e1eb5ebbd696c4b
--- /dev/null
+++ b/openairinterface5g/openairinterface-install-scripts/README.md
@@ -0,0 +1,107 @@
+## Minimum hardware requirements for OAI CN5G and OAI gNB
+    1. Operating System: Ubuntu 20.04.5 LTS
+    3. CPU: 8 cores x86_64 @ 3.5 GHz
+    2. RAM: 32 GB
+
+## Minimum hardware requirements for OAI UE
+    1. CPU: 4 cores x86_64
+    2. RAM: 8 GB
+    
+## 5G Core Installation
+### The following steps can be executed by the file oai_5g_core_install.sh
+    1. First step is to download docker, docker-compose, git and network tools. 
+    2. Following you need to download wireshark
+        A. sudo add-apt-repository ppa:wireshark-dev/stable
+        B. sudo apt update
+        C. sudo apt install wireshark
+    3. Git clone the 5GC
+        A. git clone --branch v1.4.0 https://gitlab.eurecom.fr/oai/cn5g/oai-cn5g-fed.git
+        B. Configuration of the packet forwarding
+            - sudo sysctl net.ipv4.conf.all.forwarding=1
+            - sudo iptables -P FORWARD ACCEPT
+    4. Pulling the images from Docker Hub
+        A. docker pull oaisoftwarealliance/oai-amf:v1.4.0
+        B. docker pull oaisoftwarealliance/oai-nrf:v1.4.0
+        C. docker pull oaisoftwarealliance/oai-smf:v1.4.0 
+        D. docker pull oaisoftwarealliance/oai-spgwu-tiny:v1.4.0
+        E. docker pull oaisoftwarealliance/oai-udr:v1.4.0
+        F. docker pull oaisoftwarealliance/oai-udm:v1.4.0
+        G. docker pull oaisoftwarealliance/oai-ausf:v1.4.0
+        H. docker pull oaisoftwarealliance/oai-upf-vpp:v1.4.0
+        I. docker pull oaisoftwarealliance/oai-nssf:v1.4.0
+        J. docker pull oaisoftwarealliance/trf-gen-cn5g:latest
+    5. Tag docker images
+        A. docker image tag oaisoftwarealliance/oai-amf:v1.4.0 oai-amf:v1.4.0
+        B. docker image tag oaisoftwarealliance/oai-nrf:v1.4.0 oai-nrf:v1.4.0
+        C. docker image tag oaisoftwarealliance/oai-smf:v1.4.0 oai-smf:v1.4.0
+        D. docker image tag oaisoftwarealliance/oai-spgwu-tiny:v1.4.0 oai-spgwu-tiny:v1.4.0
+        E. docker image tag oaisoftwarealliance/oai-udr:v1.4.0 oai-udr:v1.4.0
+        F. docker image tag oaisoftwarealliance/oai-udm:v1.4.0 oai-udm:v1.4.0
+        G. docker image tag oaisoftwarealliance/oai-ausf:v1.4.0 oai-ausf:v1.4.0
+        H. docker image tag oaisoftwarealliance/oai-upf-vpp:v1.4.0 oai-upf-vpp:v1.4.0
+        I. docker image tag oaisoftwarealliance/oai-nssf:v1.4.0 oai-nssf:v1.4.0
+        J. docker image tag oaisoftwarealliance/trf-gen-cn5g:latest trf-gen-cn5g:latest
+    6. Synchronizing the tutorials
+        A. Change the directory for ~/oai-cn5g-fed/
+        B. ./scripts/syncComponents.sh
+        C. git submodule deinit --all --force
+        D. git submodule init
+        F. git submodule update        
+    7. Configure the bridge before deploying 5GC.
+        A. docker network create \ --driver=bridge \ --subnet=192.168.70.128/26 \ -o "com.docker.network.bridge.name"="demo-oai" \ demo-oai-public-net
+    8. Deploy the 5GC
+        A. Change the directory for ~/oai-cn5g-fed/docker-compose
+        B. python3 core-network.py --type start-basic --scenario 1
+
+## FlexRIC, gNB and UE Installation
+### The following steps can be executed by the file flexRIC_oai_gNB_install.sh
+    1. Install the following dependencies
+        A. sudo apt-get install autotools-dev
+        B. sudo apt-get install automake
+        C. sudo apt-get install libpcre2-dev
+        D. sudo apt-get install pcre2-utils
+        E. sudo apt-get install bison
+        F. sudo apt-get install byacc
+        G. sudo apt install g++
+        H. sudo apt install libsctp-dev python3.8 cmake-curses-gui libpcre2-dev python3-dev    
+    2. Configure swig
+        A. git clone https://github.com/swig/swig.git 
+        B. cd path_to_swig
+        C. ./autogen.sh
+        D. ./configure --prefix=/usr/
+        E. sudo make
+        F. sudo make install
+    3. Install FlexRIC
+        A. git clone https://gitlab.eurecom.fr/mosaic5g/flexric.git ~/flexric
+        B. cd path_to_flexric
+        C. git checkout v1.0.0
+        D. mkdir build
+        E. cd build
+        F. sudo cmake ..
+        G. sudo make
+        H. sudo make install
+    4. Install dependencies for OpenAirInterface 5G
+        A. sudo add-apt-repository ppa:ettusresearch/uhd -y
+        B. sudo apt-get update -y
+        C. sudo apt-get install libuhd-dev uhd-host -y
+        D. sudo apt-get install libuhd4.2.0 -y
+        E. sudo dpkg -i --force-overwrite /var/cache/apt/archives/libuhd4.2.0_4.2.0.1-0ubuntu1~focal1_amd64.deb
+    5. Download the OpenAirInterface 5G repository 
+        A. git clone https://gitlab.eurecom.fr/oai/openairinterface5g.git oai
+    6. Change the openairinterface 5G branch for 2022.41
+        A. cd oai/
+        B. git checkout 2022.41
+    7. Apply FlexRIC patch
+        A. git am <pathtoflexricsrc>/flexric/multiRAT/oai/oai.patch --whitespace=nowarn
+    8. Download the OAI configuration files (CU/DU, OAI UE, and gNB configuration)
+        A. sudo wget -O ~/oai/executables/nr-softmodem.c https://projetos.imd.ufrn.br/reginalab/sdran-openairinterface/-/raw/main/OpenAirInterface/OpenAirInterface-Conf/nr-softmodem.c?inline=false
+        B. sudo wget -O ~/oai/ci-scripts/conf_files/gNB_SA_CU.conf https://projetos.imd.ufrn.br/reginalab/sdran-openairinterface/-/raw/main/OpenAirInterface/OpenAirInterface-Conf/gNB_SA_CU.conf?inline=false
+        C. sudo wget -O ~/oai/ci-scripts/conf_files/gNB_SA_DU.conf https://projetos.imd.ufrn.br/reginalab/sdran-openairinterface/-/raw/main/OpenAirInterface/OpenAirInterface-Conf/gNB_SA_DU.conf?inline=false
+        D. sudo wget -O ~/oai/targets/PROJECTS/GENERIC-NR-5GC/CONF/ue.conf https://projetos.imd.ufrn.br/reginalab/sdran-openairinterface/-/raw/main/OpenAirInterface/OpenAirInterface-Conf/ue.conf?inline=false
+
+    9. Install the gNB and UE
+        A. source oaienv
+        B. cd cmake_targets
+        C. ./build_oai -I -w USRP -i  #For OAI first time installation. it will install some dependencies
+        D. ./build_oai --gNB --nrUE -c -C -w USRP --ninja --build-lib all
+
diff --git a/openairinterface5g/openairinterface-install-scripts/flexRIC_oai_gNB_install.sh b/openairinterface5g/openairinterface-install-scripts/flexRIC_oai_gNB_install.sh
new file mode 100755
index 0000000000000000000000000000000000000000..df3c627917ac13c27d8978622f54c9646c2c8342
--- /dev/null
+++ b/openairinterface5g/openairinterface-install-scripts/flexRIC_oai_gNB_install.sh
@@ -0,0 +1,60 @@
+#!/bin/bash
+
+sudo apt update -y
+
+## Install dependencies 
+
+sudo apt-get install -y autotools-dev
+sudo apt-get install -y automake
+sudo apt-get install -y libpcre2-dev
+sudo apt-get install -y pcre2-utils
+sudo apt-get install bison -y
+sudo apt-get install byacc -y
+sudo apt install g++ -y
+sudo apt install libsctp-dev python3.8 cmake-curses-gui libpcre2-dev python3-dev -y
+## Configure swig
+
+git clone https://github.com/swig/swig.git ~/swig
+cd ~/swig
+./autogen.sh
+./configure --prefix=/usr/
+sudo make
+sudo make install
+
+## Install FlexRIC
+
+git clone https://gitlab.eurecom.fr/mosaic5g/flexric.git ~/flexric
+cd ~/flexric
+git checkout v1.0.0
+mkdir ~/flexric/build
+cd ~/flexric/build
+sudo cmake ..
+sudo make
+sudo make install
+
+## Install OAI dependencies
+
+sudo add-apt-repository ppa:ettusresearch/uhd -y
+sudo apt-get update -y
+sudo apt-get install libuhd-dev uhd-host -y
+sudo apt-get install libuhd4.2.0 -y
+sudo dpkg -i --force-overwrite /var/cache/apt/archives/libuhd4.2.0_4.2.0.1-0ubuntu1~focal1_amd64.deb
+
+## Install OAI UE and OAI gNB
+
+git clone https://gitlab.eurecom.fr/oai/openairinterface5g.git  ~/oai
+cd ~/oai
+git checkout 2022.41
+git am ~/flexric/multiRAT/oai/oai.patch --whitespace=nowarn
+
+## Download the OAI configuration files (CU/DU, OAI UE, and gNB configuration)
+
+sudo wget -O ~/oai/executables/nr-softmodem.c https://projetos.imd.ufrn.br/reginalab/sdran-openairinterface/-/raw/main/OpenAirInterface/OpenAirInterface-Conf/nr-softmodem.c?inline=false
+sudo wget -O ~/oai/ci-scripts/conf_files/gNB_SA_CU.conf https://projetos.imd.ufrn.br/reginalab/sdran-openairinterface/-/raw/main/OpenAirInterface/OpenAirInterface-Conf/gNB_SA_CU.conf?inline=false
+sudo wget -O ~/oai/ci-scripts/conf_files/gNB_SA_DU.conf https://projetos.imd.ufrn.br/reginalab/sdran-openairinterface/-/raw/main/OpenAirInterface/OpenAirInterface-Conf/gNB_SA_DU.conf?inline=false
+sudo wget -O ~/oai/targets/PROJECTS/GENERIC-NR-5GC/CONF/ue.conf https://projetos.imd.ufrn.br/reginalab/sdran-openairinterface/-/raw/main/OpenAirInterface/OpenAirInterface-Conf/ue.conf?inline=false
+
+source oaienv
+cd cmake_targets
+sudo ./build_oai -I -w USRP -i
+sudo ./build_oai --gNB --nrUE -c -C -w USRP --ninja --build-lib all
diff --git a/openairinterface5g/openairinterface-install-scripts/oai_5g_core_install.sh b/openairinterface5g/openairinterface-install-scripts/oai_5g_core_install.sh
new file mode 100755
index 0000000000000000000000000000000000000000..9415690b302b37ffad8efe20571e7a44a2c9c5eb
--- /dev/null
+++ b/openairinterface5g/openairinterface-install-scripts/oai_5g_core_install.sh
@@ -0,0 +1,86 @@
+#!/bin/bash
+
+##Install dependencies
+
+sudo apt-get install ca-certificates -y
+sudo apt-get install curl -y
+sudo apt-get install gnupg -y
+sudo apt-get install lsb-release -y
+
+## Installation Wireshark
+
+sudo add-apt-repository ppa:wireshark-dev/stable -y
+sudo apt update -y 
+sudo apt install wireshark -y
+
+## Clone OpenAirInterface 5G Core
+
+sudo rm -r ~/oai-cn5g-fed
+git clone https://gitlab.eurecom.fr/oai/cn5g/oai-cn5g-fed.git ~/oai-cn5g-fed
+
+## Configuration of the packer forwarding
+
+sudo sysctl net.ipv4.conf.all.forwarding=1
+sudo iptables -P FORWARD ACCEPT
+
+## Install docker and docker-compose
+
+sudo rm /etc/apt/sources.list.d/docker.list*
+sudo mkdir -p /etc/apt/keyrings -y
+curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
+sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(. /etc/os-release; echo "$UBUNTU_CODENAME") stable"
+sudo chmod a+r /etc/apt/keyrings/docker.gpg -y
+sudo apt-get update -y
+sudo apt-get install docker-ce docker-ce-cli containerd.io docker-compose-plugin -y
+sudo curl -L https://github.com/docker/compose/releases/download/1.29.2/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
+sudo chmod +x /usr/local/bin/docker-compose
+
+## Pulling the images from Docker Hub
+sudo docker pull oaisoftwarealliance/oai-amf:develop
+sudo docker pull oaisoftwarealliance/oai-nrf:develop
+sudo docker pull oaisoftwarealliance/oai-smf:develop
+sudo docker pull oaisoftwarealliance/oai-udr:develop
+sudo docker pull oaisoftwarealliance/oai-udm:develop
+sudo docker pull oaisoftwarealliance/oai-ausf:develop
+sudo docker pull oaisoftwarealliance/oai-spgwu-tiny:develop
+sudo docker pull oaisoftwarealliance/trf-gen-cn5g:latest
+
+## Tag Docker Images
+
+sudo docker image tag oaisoftwarealliance/trf-gen-cn5g:latest trf-gen-cn5g:latest
+sudo docker image tag oaisoftwarealliance/oai-amf:develop oai-amf:develop
+sudo docker image tag oaisoftwarealliance/oai-nrf:develop oai-nrf:develop
+sudo docker image tag oaisoftwarealliance/oai-smf:develop oai-smf:develop
+sudo docker image tag oaisoftwarealliance/oai-udr:develop oai-udr:develop
+sudo docker image tag oaisoftwarealliance/oai-udm:develop oai-udm:develop
+sudo docker image tag oaisoftwarealliance/oai-ausf:develop oai-ausf:develop
+sudo docker image tag oaisoftwarealliance/oai-spgwu-tiny:develop oai-spgwu-tiny:develop
+
+## OAI CN5G Configuration files
+
+sudo wget -O ~/oai-cn5g-fed/docker-compose/docker-compose-basic-nrf.yaml https://gitlab.eurecom.fr/oai/openairinterface5g/-/raw/develop/doc/tutorial_resources/docker-compose-basic-nrf.yaml?inline=false
+sudo wget -O ~/oai-cn5g-fed/docker-compose/database/oai_db.sql https://gitlab.eurecom.fr/oai/openairinterface5g/-/raw/develop/doc/tutorial_resources/oai_db.sql?inline=false
+sudo chmod +x ~/oai-cn5g-fed/docker-compose/database/oai_db.sql
+
+## Synchronizing the tutorials
+
+cd ~/oai-cn5g-fed
+sudo ./scripts/syncComponents.sh
+git submodule deinit --all --force
+git submodule init
+git submodule update
+
+## Creating the bridge 5GC
+
+sudo docker network create --driver=bridge --subnet=192.168.70.128/26 -o "com.docker.network.bridge.name"="demo-oai" demo-oai-public-net
+
+## Deploy the 5GC
+
+cd ~/oai-cn5g-fed/docker-compose
+sudo python3 core-network.py --type start-basic --scenario 1
+
+## Docker post-installation
+
+sudo groupadd docker
+sudo usermod -aG docker $USER
+newgrp docker