diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..d7126a6224f7009ac511df9e95fbbb32ae0d7365
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,8 @@
+# vim swp
+*.swp
+
+# log and exec file
+log/
+lte_build_oai/
+targets/bin/
+cmake_targets/nas_sim_tools/build/
diff --git a/README.txt b/README.txt
index b0cad5f01129964a21cfba103e0d9c18e67761b8..37f6a865712344caf06f56529945a9021301c272 100644
--- a/README.txt
+++ b/README.txt
@@ -17,7 +17,7 @@ openairinterface5g
 ├── maketags : Script to generate emacs tags
 ├── nfapi : Contains the NFAPI code. A local Readme file provides more details.
 ├── openair1 : 3GPP LTE Rel-10/12 PHY layer + PHY RF simulation. A local Readme file provides more details.
-├── openair2 : 3GPP LTE Rel-10 RLC/MAC/PDCP/RRC/X2AP implementation. 
+├── openair2 : 3GPP LTE Rel-10 RLC/MAC/PDCP/RRC/X2AP implementation.
     ├── COMMON
     ├── DOCS
     ├── ENB_APP
diff --git a/ci-scripts/Jenkinsfile-gitlab b/ci-scripts/Jenkinsfile-gitlab
index 5fa46ddcc0e2064720e4fbaa2a5ec4ec142028f0..cd2d7836387cbd6eef43b149138c5c3f7b73f5f6 100644
--- a/ci-scripts/Jenkinsfile-gitlab
+++ b/ci-scripts/Jenkinsfile-gitlab
@@ -133,6 +133,7 @@ pipeline {
                     script {
                         def message = "OAI " + JOB_NAME + " build (" + BUILD_ID + "): Merge Conflicts -- Cannot perform CI"
                         addGitLabMRComment comment: message
+                        currentBuild.result = 'FAILURE'
                     }
                 }
             }
@@ -283,6 +284,11 @@ pipeline {
                 }
             }
             post {
+                failure {
+                    script {
+                        currentBuild.result = 'FAILURE'
+                    }
+                }
                 always {
                     script {
                         dir ('archives') {
@@ -392,7 +398,7 @@ pipeline {
                         }
                     }
                 }
-                stage ("Test FDD - Band 7 - B210") {
+                stage ("Test MONOLITHIC - FDD - Band 7 - B210") {
                     steps {
                         script {
                             if ("MERGE".equals(env.gitlabActionType)) {
@@ -443,7 +449,7 @@ pipeline {
                         }
                     }
                 }
-                stage ("Test TDD - Band 40 - B210") {
+                stage ("Test MONOLITHIC - TDD - Band 40 - B210") {
                     steps {
                         script {
                             if ("MERGE".equals(env.gitlabActionType)) {
@@ -647,6 +653,57 @@ pipeline {
                         }
                     }
                 }
+                stage ("Test OAI UE Sniffing - FDD - Band 20 - B200") {
+                    steps {
+                        script {
+                            if ("MERGE".equals(env.gitlabActionType)) {
+                                //gitlabCommitStatus(name: "Test-OAI-UE-FDD-Band20") {
+                                    build job: 'UE-CI-FDD-Band20-B200',
+                                       parameters: [
+                                           string(name: 'eNB_Repository', value: String.valueOf(GIT_URL)),
+                                           string(name: 'eNB_Branch', value: String.valueOf(env.gitlabSourceBranch)),
+                                           string(name: 'eNB_CommitID', value: String.valueOf(env.gitlabMergeRequestLastCommit)),
+                                           booleanParam(name: 'eNB_mergeRequest', value: true),
+                                           string(name: 'eNB_TargetBranch', value: String.valueOf(env.gitlabTargetBranch))
+                                       ]
+                                //}
+                            } else {
+                                //gitlabCommitStatus(name: "Test-OAI-UE-FDD-Band20") {
+                                    build job: 'UE-CI-FDD-Band20-B200',
+                                       parameters: [
+                                           string(name: 'eNB_Repository', value: String.valueOf(GIT_URL)),
+                                           string(name: 'eNB_Branch', value: String.valueOf(GIT_BRANCH)),
+                                           string(name: 'eNB_CommitID', value: String.valueOf(GIT_COMMIT)),
+                                           booleanParam(name: 'eNB_mergeRequest', value: false)
+                                       ]
+                                //}
+                            }
+                        }
+                    }
+                    post {
+                        // In case of any non-success, we are retrieving the HTML report of the last completed
+                        // slave job.
+                        // The only drop-back is that we may retrieve the HTML report of a previous build
+                        always {
+                            script {
+                                if (!fileExists('test_results-UE-CI-FDD-Band20-B200.html')) {
+                                    copyArtifacts(projectName: 'UE-CI-FDD-Band20-B200',
+                                                  filter: 'test_results*.html',
+                                                  selector: lastCompleted())
+                                    if (fileExists('test_results-UE-CI-FDD-Band20-B200.html')) {
+                                        sh "sed -i -e 's#TEMPLATE_BUILD_TIME#${JOB_TIMESTAMP}#' test_results-UE-CI-FDD-Band20-B200.html"
+                                        archiveArtifacts artifacts: 'test_results-UE-CI-FDD-Band20-B200.html'
+                                    }
+                                }
+                            }
+                        }
+                        failure {
+                            script {
+                                currentBuild.result = 'FAILURE'
+                            }
+                        }
+                    }
+                }
             }
             post {
                 always {
diff --git a/ci-scripts/Jenkinsfile-tmp-ue b/ci-scripts/Jenkinsfile-tmp-ue
new file mode 100644
index 0000000000000000000000000000000000000000..70fe29879fa3e23c4ff5c75ac62da76341e5b8a0
--- /dev/null
+++ b/ci-scripts/Jenkinsfile-tmp-ue
@@ -0,0 +1,300 @@
+#!/bin/groovy
+/*
+ * 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
+ */
+
+// Template Jenkins Declarative Pipeline script to run Test w/ RF HW
+
+// Location of the python executor node shall be in the same subnet as the others servers
+def pythonExecutor = params.pythonExecutor
+
+// Location of the test XML file to be run
+def testXMLFile = params.pythonTestXmlFile
+def mainPythonAllXmlFiles = ""
+def buildStageStatus = true
+
+// Name of the test stage
+def testStageName = params.pipelineTestStageName
+
+// Name of the phone resource
+def ciSmartPhoneResource = params.smartphonesResource
+
+// Terminate Status
+def termUE = 0
+def termENB = 1
+def termSPGW = 2
+def termMME = 3
+def termHSS = 4
+def termStatusArray = new Boolean[termHSS + 1]
+termStatusArray[termUE] = false
+termStatusArray[termENB] = false
+termStatusArray[termSPGW] = false
+termStatusArray[termMME] = false
+termStatusArray[termHSS] = false
+
+// Global Parameters. Normally they should be populated when the master job
+// triggers the slave job with parameters
+def eNB_Repository
+def eNB_Branch
+def eNB_CommitID
+def eNB_AllowMergeRequestProcess = false
+def eNB_TargetBranch
+
+pipeline {
+    agent {
+        label pythonExecutor
+    }
+    options {
+        disableConcurrentBuilds()
+        ansiColor('xterm')
+        lock (ciSmartPhoneResource)
+    }
+    // the following parameter options are commented out so it shows the ones
+    // that you SHALL have to run the job.
+    // You can use them as template
+    /*
+    parameters {
+        //node-test parameters
+        string(name: 'pythonExecutor', defaultValue: 'nodea', description: 'Node where the pipeline - python scripts will be executed')
+        string(name: 'pythonTestXmlFile', defaultValue: 'enb_usrpB210_band7_50PRB.xml', description: 'Location of the Test XML to be run')
+        string(name: 'pipelineTestStageName', defaultValue: 'Test COTS-UE - OAI eNB - LTEBOX EPC', description: 'Naming of the Test Stage')
+        booleanParam(name: 'pipelineZipsConsoleLog', defaultValue: 'True', description: 'If true, the pipeline script retrieves the job console log, zips it and archives it as artifact')
+        string(name: 'smartphonesResource', defaultValue: 'CI-Bench-1-Phones', description: 'Lockeable Resource to prevent multiple jobs to run simultaneously with the same resource')
+
+        //eNB parameters
+        string(name: 'eNB_IPAddress', defaultValue: '192.168.XX.XX', description: 'IP Address of eNB')
+        credentials(name: 'eNB_Credentials', defaultValue: 'XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX', credentialType: "Username with password", required: true, description: 'Credentials for eNB')
+        string(name: 'eNB_SourceCodePath', defaultValue: '/tmp/CI-enb', description: 'Full path of eNB source code')
+
+        //EPC parameters
+        string(name: 'EPC_IPAddress', defaultValue: '192.168.XX.XX', description: 'IP Address of EPC')
+        string(name: 'EPC_Type', defaultValue: 'ltebox', description: 'EPC type: OAI or ltebox')
+        credentials(name: 'EPC_Credentials', defaultValue: 'XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX', credentialType: "Username with password", required: true, description: 'Credentials for EPC')
+        string(name: 'EPC_SourceCodePath', defaultValue: '/tmp/CI-enb', description: 'Full path of EPC source code')
+
+        //ADB server parameters
+        string(name: 'ADB_IPAddress', defaultValue: '192.168.XX.XX', description: 'IP Address of ADB server')
+        credentials(name: 'ADB_Credentials', defaultValue: 'XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX', credentialType: "Username with password", required: true, description: 'Credentials for ADB')
+    }
+    */
+
+    stages {
+        stage ("Verify Parameters") {
+            steps {
+                script {
+                    echo '\u2705 \u001B[32mVerify Parameters\u001B[0m'
+                    def allParametersPresent = true
+
+                    // It is already to late to check it
+                    if (params.pythonExecutor != null) {
+                        echo "eNB CI executor node  :   ${pythonExecutor}"
+                    }
+                    // If not present picking a default XML file
+                    if (params.pythonTestXmlFile == null) {
+                        // picking default
+                        testXMLFile = 'xml_files/enb_usrpB210_band7_50PRB.xml'
+                        echo "Test XML file(default):   ${testXMLFile}"
+                        mainPythonAllXmlFiles += "--XMLTestFile=" + testXMLFile + " "
+                    } else {
+                        String[] myXmlTestSuite = testXMLFile.split("\\r?\\n")
+                        for (xmlFile in myXmlTestSuite) {
+                            if (fileExists("ci-scripts/" + xmlFile)) {
+                                mainPythonAllXmlFiles += "--XMLTestFile=" + xmlFile + " "
+                                echo "Test XML file         :   ${xmlFile}"
+                            }
+                        }
+                    }
+                    // If not present picking a default Stage Name
+                    if (params.pipelineTestStageName == null) {
+                        // picking default
+                        testStageName = 'Template Test Stage'
+                    }
+
+                    if (params.smartphonesResource == null) {
+                        allParametersPresent = false
+                    }
+                    if (params.UE_IPAddress == null) {
+                        allParametersPresent = false
+                    }
+                    if (params.UE_SourceCodePath == null) {
+                        allParametersPresent = false
+                    }
+                    if (params.UE_Credentials == null) {
+                        allParametersPresent = false
+                    }
+                    // the following 4 parameters should be pushed by the master trigger
+                    // if not present, take the job GIT variables (used for developing)
+                    if (params.eNB_Repository == null) {
+                        eNB_Repository = env.GIT_URL
+                    } else {
+                        eNB_Repository = params.eNB_Repository
+                    }
+                    echo "eNB_Repository        :   ${eNB_Repository}"
+                    if (params.eNB_Branch == null) {
+                        eNB_Branch = env.GIT_BRANCH
+                    } else {
+                        eNB_Branch = params.eNB_Branch
+                    }
+                    echo "eNB_Branch            :   ${eNB_Branch}"
+                    if (params.eNB_CommitID == null) {
+                        eNB_CommitID = env.GIT_COMMIT
+                    } else {
+                        eNB_CommitID = params.eNB_CommitID
+                    }
+                    echo "eNB_CommitID          :   ${eNB_CommitID}"
+                    if (params.eNB_mergeRequest != null) {
+                        eNB_AllowMergeRequestProcess = params.eNB_mergeRequest
+                        if (eNB_AllowMergeRequestProcess) {
+                            if (params.eNB_TargetBranch != null) {
+                                eNB_TargetBranch = params.eNB_TargetBranch
+                            } else {
+                                eNB_TargetBranch = 'develop'
+                            }
+                            echo "eNB_TargetBranch      :   ${eNB_TargetBranch}"
+                        }
+                    }
+/*
+                    if (params.EPC_IPAddress == null) {
+                        allParametersPresent = false
+                    }
+                    if (params.EPC_Type == null) {
+                        allParametersPresent = false
+                    }
+                    if (params.EPC_SourceCodePath == null) {
+                        allParametersPresent = false
+                    }
+                    if (params.EPC_Credentials == null) {
+                        allParametersPresent = false
+                    }
+*/
+                    if (params.ADB_IPAddress == null) {
+                        allParametersPresent = false
+                    }
+                    if (params.ADB_Credentials == null) {
+                        allParametersPresent = false
+                    }
+
+                    if (allParametersPresent) {
+                        echo "All parameters are present"
+                        if (eNB_AllowMergeRequestProcess) {
+                            sh "git fetch"
+                            sh "./ci-scripts/doGitLabMerge.sh --src-branch ${eNB_Branch} --src-commit ${eNB_CommitID} --target-branch ${eNB_TargetBranch} --target-commit latest"
+                        } else {
+                            sh "git fetch"
+                            sh "git checkout -f ${eNB_CommitID}"
+                        }
+                    } else {
+                        echo "Some parameters are missing"
+                        sh "./ci-scripts/fail.sh"
+                    }
+                }
+            }
+        }
+        stage ("Build and Test") {
+            steps {
+                script {
+                    dir ('ci-scripts') {
+                        echo "\u2705 \u001B[32m${testStageName}\u001B[0m"
+                        withCredentials([
+                            [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.UE_Credentials}", usernameVariable: 'UE_Username', passwordVariable: 'UE_Password'],
+                            [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.ADB_Credentials}", usernameVariable: 'ADB_Username', passwordVariable: 'ADB_Password']
+                        ]) {
+                            sh "python3 main.py --mode=InitiateHtml --eNBRepository=${eNB_Repository} --eNBBranch=${eNB_Branch} --eNBCommitID=${eNB_CommitID} --eNB_AllowMerge=${eNB_AllowMergeRequestProcess} --eNBTargetBranch=${eNB_TargetBranch} --ADBIPAddress=${params.ADB_IPAddress} --ADBUserName=${ADB_Username} --ADBPassword=${ADB_Password} ${mainPythonAllXmlFiles}"
+                            String[] myXmlTestSuite = testXMLFile.split("\\r?\\n")
+                            for (xmlFile in myXmlTestSuite) {
+                            if (fileExists(xmlFile)) {
+                                try {
+                                    sh "python3 main.py --mode=TestUE --UEIPAddress=${params.UE_IPAddress} --eNBRepository=${eNB_Repository} --eNBBranch=${eNB_Branch} --eNBCommitID=${eNB_CommitID} --eNB_AllowMerge=${eNB_AllowMergeRequestProcess} --eNBTargetBranch=${eNB_TargetBranch} --UEUserName=${UE_Username} --UEPassword=${UE_Password} --UESourceCodePath=${params.UE_SourceCodePath} --ADBIPAddress=${params.ADB_IPAddress} --ADBUserName=${ADB_Username} --ADBPassword=${ADB_Password} --XMLTestFile=${xmlFile}"
+                                } catch (Exception e) {
+                                    currentBuild.result = 'FAILURE'
+                                    buildStageStatus = false
+                                }
+                            }
+                            }
+                            sh "python3 main.py --mode=FinalizeHtml --finalStatus=${buildStageStatus} --UEIPAddress=${params.UE_IPAddress} --UEUserName=${UE_Username} --UEPassword=${UE_Password}"
+                        }
+                    }
+                }
+            }
+        }
+        stage('Log Collection') {
+            parallel {
+                stage('Log Collection (OAI UE - Build)') {
+                    steps {
+                        echo '\u2705 \u001B[32mLog Collection (OAI UE - Build)\u001B[0m'
+                        withCredentials([
+                             [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.UE_Credentials}", usernameVariable: 'UE_Username', passwordVariable: 'UE_Password']
+                        ]) {
+                            sh "python3 ci-scripts/main.py --mode=LogCollectBuild --UEIPAddress=${params.UE_IPAddress} --UEUserName=${UE_Username} --UEPassword=${UE_Password} --UESourceCodePath=${params.UE_SourceCodePath}"
+
+                            echo '\u2705 \u001B[32mLog Transfer (UE - Build)\u001B[0m'
+                            sh "sshpass -p \'${UE_Password}\' scp -o 'StrictHostKeyChecking no' -o 'ConnectTimeout 10' ${UE_Username}@${params.UE_IPAddress}:${UE_SourceCodePath}/cmake_targets/build.log.zip ./build.log.${env.BUILD_ID}.zip || true"
+                        }
+                        script {
+                            if(fileExists("build.log.${env.BUILD_ID}.zip")) {
+                                archiveArtifacts "build.log.${env.BUILD_ID}.zip"
+                            }
+                        }
+                    }
+                }
+                stage('Log Collection (OAI UE - Run)') {
+                    steps {
+                        echo '\u2705 \u001B[32mLog Collection (OAI UE - Run)\u001B[0m'
+                        withCredentials([
+                             [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.UE_Credentials}", usernameVariable: 'UE_Username', passwordVariable: 'UE_Password']
+                        ]) {
+                            sh "python3 ci-scripts/main.py --mode=LogCollectOAIUE --UEIPAddress=${params.UE_IPAddress} --UEUserName=${UE_Username} --UEPassword=${UE_Password} --UESourceCodePath=${params.UE_SourceCodePath}"
+
+                            echo '\u2705 \u001B[32mLog Transfer (UE - Run)\u001B[0m'
+                            sh "sshpass -p \'${UE_Password}\' scp -o 'StrictHostKeyChecking no' -o 'ConnectTimeout 10' ${UE_Username}@${params.UE_IPAddress}:${UE_SourceCodePath}/cmake_targets/ue.log.zip ./ue.log.${env.BUILD_ID}.zip || true"
+                        }
+                        script {
+                            if(fileExists("ue.log.${env.BUILD_ID}.zip")) {
+                                archiveArtifacts "ue.log.${env.BUILD_ID}.zip"
+                            }
+                            if(fileExists("ci-scripts/test_results.html")) {
+                                sh "mv ci-scripts/test_results.html test_results-${JOB_NAME}.html"
+                                sh "sed -i -e 's#TEMPLATE_JOB_NAME#${JOB_NAME}#' -e 's@build #TEMPLATE_BUILD_ID@build #${BUILD_ID}@' -e 's#Build-ID: TEMPLATE_BUILD_ID#Build-ID: <a href=\"${BUILD_URL}\">${BUILD_ID}</a>#' -e 's#TEMPLATE_STAGE_NAME#${testStageName}#' test_results-${JOB_NAME}.html"
+                                archiveArtifacts "test_results-${JOB_NAME}.html"
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    post {
+        always {
+            script {
+                if (params.pipelineZipsConsoleLog != null) {
+                    if (params.pipelineZipsConsoleLog) {
+                        echo "Archiving Jenkins console log"
+                        sh "wget --no-check-certificate --no-proxy ${env.JENKINS_URL}/job/${env.JOB_NAME}/${env.BUILD_ID}/consoleText -O consoleText.log || true"
+                        sh "zip -m consoleText.log.${env.BUILD_ID}.zip consoleText.log || true"
+                        if(fileExists("consoleText.log.${env.BUILD_ID}.zip")) {
+                            archiveArtifacts "consoleText.log.${env.BUILD_ID}.zip"
+                        }
+                    }
+                }
+            }
+        }
+    }
+}
diff --git a/ci-scripts/buildOnVM.sh b/ci-scripts/buildOnVM.sh
index ad77d39eb785d39462d3b34a822843babdbe5b97..d4ee84701cdbebe478fc16bc1b1d78a2fc4d57ae 100755
--- a/ci-scripts/buildOnVM.sh
+++ b/ci-scripts/buildOnVM.sh
@@ -111,7 +111,7 @@ function build_on_vm {
     fi
 
     echo "############################################################"
-    echo "Copying GIT repo into VM ($VM_NAME)" 
+    echo "Copying GIT repo into VM ($VM_NAME)"
     echo "############################################################"
     if [[ "$VM_NAME" == *"-flexran-rtc"* ]]
     then
diff --git a/ci-scripts/conf_files/enb.band13.tm1.50PRB.emtc.conf b/ci-scripts/conf_files/enb.band13.tm1.50PRB.emtc.conf
index f69c5a420f71a81652a6f08ba0d92f256b6cfcf9..ea8a56e38571e452792402c54b193598e3509b18 100644
--- a/ci-scripts/conf_files/enb.band13.tm1.50PRB.emtc.conf
+++ b/ci-scripts/conf_files/enb.band13.tm1.50PRB.emtc.conf
@@ -49,22 +49,22 @@ eNBs =
       prach_freq_offset                         = 1;
       pucch_delta_shift                         = 1;
       pucch_nRB_CQI                             = 0;
-      pucch_nCS_AN                              = 0;    
+      pucch_nCS_AN                              = 0;
       pucch_n1_AN                               = 0;
       pdsch_referenceSignalPower                = -24;
       pdsch_p_b                                 = 0;
       pusch_n_SB                                = 1;
       pusch_enable64QAM                         = "DISABLE";
       pusch_hoppingMode                         = "interSubFrame";
-      pusch_hoppingOffset                       = 0; 
+      pusch_hoppingOffset                       = 0;
       pusch_groupHoppingEnabled                 = "ENABLE";
       pusch_groupAssignment                     = 0;
       pusch_sequenceHoppingEnabled              = "DISABLE";
       pusch_nDMRS1                              = 1;
       phich_duration                            = "NORMAL";
       phich_resource                            = "ONESIXTH";
-      srs_enable                                = "DISABLE"; 
-      /*  srs_BandwidthConfig                   =; 
+      srs_enable                                = "DISABLE";
+      /*  srs_BandwidthConfig                   =;
       srs_SubframeConfig                        =;
       srs_ackNackST                             =;
       srs_MaxUpPts                              =;*/
@@ -73,14 +73,14 @@ eNBs =
       pusch_alpha                               = "AL1";
       pucch_p0_Nominal                          = -104;
       msg3_delta_Preamble                       = 6;
-      pucch_deltaF_Format1                      = "deltaF2";             
-      pucch_deltaF_Format1b                     = "deltaF3";            
-      pucch_deltaF_Format2                      = "deltaF0";            
-      pucch_deltaF_Format2a                     = "deltaF0";            
-      pucch_deltaF_Format2b                     = "deltaF0";            
-
-      rach_numberOfRA_Preambles                 = "n64"; #64 
-      rach_preamblesGroupAConfig                = "DISABLE"; 
+      pucch_deltaF_Format1                      = "deltaF2";
+      pucch_deltaF_Format1b                     = "deltaF3";
+      pucch_deltaF_Format2                      = "deltaF0";
+      pucch_deltaF_Format2a                     = "deltaF0";
+      pucch_deltaF_Format2b                     = "deltaF0";
+
+      rach_numberOfRA_Preambles                 = "n64"; #64
+      rach_preamblesGroupAConfig                = "DISABLE";
       /*
       rach_sizeOfRA_PreamblesGroupA             = ;
       rach_messageSizeGroupA                    = ;
@@ -105,7 +105,7 @@ eNBs =
       ue_TransmissionMode                       = "tm1";
 
       # eMTC Parameters
-      emtc_parameters : 
+      emtc_parameters :
       {
           eMTC_configured                       = 1;
           #hyperSFN_r13                               = 0;
@@ -115,7 +115,7 @@ eNBs =
           #SIB1
           schedulingInfoSIB1_BR_r13                   = 4;
 
-          #system_info_value_tag_SI = 
+          #system_info_value_tag_SI =
           #(
           #    {
           #        systemInfoValueTagSi_r13 = 0;
@@ -124,7 +124,7 @@ eNBs =
 
           cellSelectionInfoCE_r13                     = "ENABLE";
           q_RxLevMinCE_r13                            = -70;
-          bandwidthReducedAccessRelatedInfo_r13       = "ENABLE"   
+          bandwidthReducedAccessRelatedInfo_r13       = "ENABLE"
           si_WindowLength_BR_r13                      = "ms20";    #0
           si_RepetitionPattern_r13                    = "everyRF"; #0
 
@@ -136,7 +136,7 @@ eNBs =
               }
          );
 
-          fdd_DownlinkOrTddSubframeBitmapBR_r13     = "subframePattern40-r13"; 
+          fdd_DownlinkOrTddSubframeBitmapBR_r13     = "subframePattern40-r13";
           fdd_DownlinkOrTddSubframeBitmapBR_val_r13 = 0xFFFFFFFFFF;
           startSymbolBR_r13                           = 2;
           si_HoppingConfigCommon_r13                  = "off"; #1; # Note: 1==OFF !
@@ -157,14 +157,14 @@ eNBs =
 
           rach_numberOfRA_Preambles                 = 60; #14
           rach_powerRampingStep                     = 4;
-          rach_preambleInitialReceivedTargetPower   = -110;           
+          rach_preambleInitialReceivedTargetPower   = -110;
           rach_preambleTransMax                     = 10;
           rach_raResponseWindowSize                 = 10;
           rach_macContentionResolutionTimer         = 64;
           rach_maxHARQ_Msg3Tx                       = 4;
 
           # max size for this array is 4
-          rach_CE_LevelInfoList_r13 = 
+          rach_CE_LevelInfoList_r13 =
           (
               {
                   firstPreamble_r13                 = 60;
@@ -175,7 +175,7 @@ eNBs =
               }
           );
 
-          # BCCH CONFIG          
+          # BCCH CONFIG
           bcch_modificationPeriodCoeff              = 2;
 
           #PCCH Config
@@ -189,7 +189,7 @@ eNBs =
           prach_zero_correlation                    = 1;
           prach_freq_offset                         = 1;
 
-          #PDSCH Config Common          
+          #PDSCH Config Common
           pdsch_referenceSignalPower                = -24
           pdsch_p_b                                 = 0;
 
@@ -213,22 +213,22 @@ eNBs =
           pusch_p0_Nominal                          = -96;
           pusch_alpha                               = "AL1";
           pucch_p0_Nominal                          = -104;
-          pucch_deltaF_Format1                      = "deltaF0"; 
-          pucch_deltaF_Format1b                     = "deltaF3";            
-          pucch_deltaF_Format2                      = "deltaF0";           
-          pucch_deltaF_Format2a                     = "deltaF0";            
+          pucch_deltaF_Format1                      = "deltaF0";
+          pucch_deltaF_Format1b                     = "deltaF3";
+          pucch_deltaF_Format2                      = "deltaF0";
+          pucch_deltaF_Format2a                     = "deltaF0";
           pucch_deltaF_Format2b                     = "deltaF0";
 
           msg3_delta_Preamble                       = 6;
 
 
           prach_ConfigCommon_v1310                  = "ENABLE";
- 
+
           mpdcch_startSF_CSS_RA_r13                 = "fdd-r13";
           mpdcch_startSF_CSS_RA_r13_val             = "v1"; #0
           prach_HoppingOffset_r13                   = 0;
 
-         
+
           pdsch_maxNumRepetitionCEmodeA_r13         = "r16"; #0
           #pdsch_maxNumRepetitionCEmodeB_r13         = "r384"; # NULL - 2
 
@@ -245,7 +245,7 @@ eNBs =
           );
 
           # max size for this array is 4
-          prach_parameters_ce_r13 = 
+          prach_parameters_ce_r13 =
           (
               {
                   prach_config_index_br                     = 3;
@@ -255,17 +255,17 @@ eNBs =
                   numRepetitionPerPreambleAttempt_r13       = 1;  #0
                   mpdcch_NumRepetition_RA_r13               = 1;  #0
                   prach_HoppingConfig_r13                   = 0;  #1
-                  max_available_narrow_band                 = [3]; 
+                  max_available_narrow_band                 = [3];
              }
           );
 
-          n1PUCCH_AN_InfoList_r13 = 
+          n1PUCCH_AN_InfoList_r13 =
           (
               {
                   pucch_info_value = 33;
               }
           );
-          
+
 
           ue_TimersAndConstants_t300                = "ms1000";
           ue_TimersAndConstants_t301                = "ms400";
@@ -283,21 +283,21 @@ eNBs =
           }
 
 
-          pucch_NumRepetitionCE_Msg4_Level0_r13      = "n1";  #0 
+          pucch_NumRepetitionCE_Msg4_Level0_r13      = "n1";  #0
           #pucch_NumRepetitionCE_Msg4_Level1_r13     = "n2";  #1
           #pucch_NumRepetitionCE_Msg4_Level2_r13     = "n16"; #2
           #pucch_NumRepetitionCE_Msg4_Level3_r13     = "n32"; #3
 
-          sib2_freq_hoppingParameters_r13 : 
+          sib2_freq_hoppingParameters_r13 :
           {
              #sib2_mpdcch_pdsch_hoppingNB_r13                   = "nb2"; #0
              #sib2_interval_DLHoppingConfigCommonModeA_r13      = "FDD"; # choice -> (0, FDD) (1, TDD)
-             #sib2_interval_DLHoppingConfigCommonModeA_r13_val  = "int1";          
+             #sib2_interval_DLHoppingConfigCommonModeA_r13_val  = "int1";
              #sib2_interval_DLHoppingConfigCommonModeB_r13      = "FDD"; # choice -> (0, FDD) (1, TDD)
-             #sib2_interval_DLHoppingConfigCommonModeB_r13_val  = "int2";        
+             #sib2_interval_DLHoppingConfigCommonModeB_r13_val  = "int2";
 
              sib2_interval_ULHoppingConfigCommonModeA_r13      = "FDD";  # choice -> (0, FDD) (1, TDD)
-             sib2_interval_ULHoppingConfigCommonModeA_r13_val  = "int4"; #2          
+             sib2_interval_ULHoppingConfigCommonModeA_r13_val  = "int4"; #2
 #            sib2_interval_ULHoppingConfigCommonModeB_r13      = "FDD";  # choice -> (0, FDD) (1, TDD)
 #            sib2_interval_ULHoppingConfigCommonModeB_r13_val  = "int2"; #0
 
@@ -305,11 +305,11 @@ eNBs =
           }
 
           rach_preamblesGroupAConfig                = "DISABLE";
-          
+
           phich_duration                            = "NORMAL";
           phich_resource                            = "ONESIXTH";
           srs_enable                                = "DISABLE";
-          
+
       }
 
 
@@ -397,14 +397,14 @@ eNBs =
 );
 
 MACRLCs = (
-        {	
+        {
         num_cc	 = 1;
         tr_s_preference = "local_L1";
         tr_n_preference = "local_RRC";
 	phy_test_mode = 0;
         puSch10xSnr     =  200;
         puCch10xSnr     =  200;
-        }  
+        }
 );
 
 L1s = (
@@ -412,11 +412,11 @@ L1s = (
       num_cc = 1;
       tr_n_preference = "local_mac";
       prach_dtx_threshold = 200;
-      }  
+      }
 );
 
 RUs = (
-    {     
+    {
         local_rf       = "yes"
         nb_tx          = 1
         nb_rx          = 1
@@ -427,7 +427,7 @@ RUs = (
         max_rxgain                    = 110;
         eNB_instances  = [0];
     }
-);  
+);
 
 THREAD_STRUCT = (
   {
@@ -465,4 +465,3 @@ log_config :
        rrc_log_level                         ="info";
        rrc_log_verbosity                     ="medium";
     };
-
diff --git a/ci-scripts/conf_files/enb.band7.tm2.25PRB.usrpb210.conf b/ci-scripts/conf_files/enb.band7.tm2.25PRB.usrpb210.conf
index 5097a4f1457c56b71da4c20e7b6165f3c5ad899b..b006e04e91beb7356d5ca300d3a7ed40cfb3d7d1 100644
--- a/ci-scripts/conf_files/enb.band7.tm2.25PRB.usrpb210.conf
+++ b/ci-scripts/conf_files/enb.band7.tm2.25PRB.usrpb210.conf
@@ -207,18 +207,18 @@ MACRLCs = (
     phy_test_mode   = 0;
     puSch10xSnr     = 200;
     puCch10xSnr     = 200;
-    }  
+    }
 );
 
 L1s = (
     {
     num_cc = 1;
     tr_n_preference = "local_mac";
-    }  
+    }
 );
 
 RUs = (
-    {          
+    {
     local_rf                      = "yes"
     nb_tx                         = 2
     nb_rx                         = 2
@@ -229,7 +229,7 @@ RUs = (
     max_rxgain                    = 115;
     eNB_instances                 = [0];
     }
-);  
+);
 
 THREAD_STRUCT = (
   {
@@ -267,4 +267,3 @@ log_config :
        rrc_log_level                         ="info";
        rrc_log_verbosity                     ="medium";
     };
-
diff --git a/ci-scripts/conf_files/lte-fdd-basic-sim.conf b/ci-scripts/conf_files/lte-fdd-basic-sim.conf
index 22bb6608e0182280be32305b97b6511f2b1ac231..cabbed871a49bd74bdc7d3a649675a44c10e207a 100644
--- a/ci-scripts/conf_files/lte-fdd-basic-sim.conf
+++ b/ci-scripts/conf_files/lte-fdd-basic-sim.conf
@@ -205,18 +205,18 @@ MACRLCs = (
 	phy_test_mode = 0;
         puSch10xSnr     =  200;
         puCch10xSnr     =  200;
-        }  
+        }
 );
 
 L1s = (
-    	{
+      {
 	num_cc = 1;
 	tr_n_preference = "local_mac";
-        }  
+      }
 );
 
 RUs = (
-    {		  
+    {
        local_rf       = "yes"
          nb_tx          = 1
          nb_rx          = 1
@@ -228,7 +228,7 @@ RUs = (
          eNB_instances  = [0];
 
     }
-);  
+);
 
 THREAD_STRUCT = (
   {
@@ -266,4 +266,3 @@ NETWORK_CONTROLLER :
        rrc_log_level                         ="info";
        rrc_log_verbosity                     ="medium";
     };
-
diff --git a/ci-scripts/conf_files/rcc.band7.tm1.if4p5.lo.100PRB.usrpb210.conf b/ci-scripts/conf_files/rcc.band7.tm1.if4p5.lo.100PRB.usrpb210.conf
index 393588064b574e6363189c47794f0a6f705c0490..6f6aa987881ffb9905f68bca0d0a64a1ac0b6cb6 100644
--- a/ci-scripts/conf_files/rcc.band7.tm1.if4p5.lo.100PRB.usrpb210.conf
+++ b/ci-scripts/conf_files/rcc.band7.tm1.if4p5.lo.100PRB.usrpb210.conf
@@ -7,7 +7,7 @@ eNBs =
  {
     # real_time choice in {hard, rt-preempt, no}
     real_time       =  "no";
- 
+
     ////////// Identification parameters:
     eNB_ID    =  0xe00;
 
@@ -207,18 +207,18 @@ MACRLCs = (
 	phy_test_mode = 0;
         puSch10xSnr     =  160;
         puCch10xSnr     =  160;
-        }  
+        }
 );
 
 L1s = (
-    	{
+      {
 	num_cc = 1;
 	tr_n_preference = "local_mac";
-        }  
+      }
 );
 
 RUs = (
-    {		  
+    {
         local_if_name  = "lo";
         remote_address = "127.0.0.2";
         local_address  = "127.0.0.1";
@@ -234,7 +234,7 @@ RUs = (
         att_rx         = 0;
         eNB_instances  = [0];
     }
-);  
+);
 
 THREAD_STRUCT = (
   {
@@ -272,4 +272,3 @@ NETWORK_CONTROLLER :
        rrc_log_level                         ="info";
        rrc_log_verbosity                     ="medium";
     };
-
diff --git a/ci-scripts/conf_files/rcc.band7.tm1.if4p5.lo.25PRB.usrpb210.conf b/ci-scripts/conf_files/rcc.band7.tm1.if4p5.lo.25PRB.usrpb210.conf
index 7c2ab85186073b54d854bb7f49935ace48b0d51f..ec7fce3dbf9d3f69361903df61ea688b0fd84734 100644
--- a/ci-scripts/conf_files/rcc.band7.tm1.if4p5.lo.25PRB.usrpb210.conf
+++ b/ci-scripts/conf_files/rcc.band7.tm1.if4p5.lo.25PRB.usrpb210.conf
@@ -7,7 +7,7 @@ eNBs =
  {
     # real_time choice in {hard, rt-preempt, no}
     real_time       =  "no";
- 
+
     ////////// Identification parameters:
     eNB_ID    =  0xe00;
 
@@ -207,18 +207,18 @@ MACRLCs = (
 	phy_test_mode = 0;
         puSch10xSnr     =  160;
         puCch10xSnr     =  160;
-        }  
+        }
 );
 
 L1s = (
-    	{
+      {
 	num_cc = 1;
 	tr_n_preference = "local_mac";
-        }  
+      }
 );
 
 RUs = (
-    {		  
+    {
         local_if_name  = "lo";
         remote_address = "127.0.0.2";
         local_address  = "127.0.0.1";
@@ -234,7 +234,7 @@ RUs = (
         att_rx         = 0;
         eNB_instances  = [0];
     }
-);  
+);
 
 THREAD_STRUCT = (
   {
@@ -272,4 +272,3 @@ NETWORK_CONTROLLER :
        rrc_log_level                         ="info";
        rrc_log_verbosity                     ="medium";
     };
-
diff --git a/ci-scripts/conf_files/rcc.band7.tm1.if4p5.lo.50PRB.usrpb210.conf b/ci-scripts/conf_files/rcc.band7.tm1.if4p5.lo.50PRB.usrpb210.conf
index 77019a466e4156303ceca92b727551fd13c7e0ba..4ebbff4bdab963f049e6737772cca618eae409f4 100644
--- a/ci-scripts/conf_files/rcc.band7.tm1.if4p5.lo.50PRB.usrpb210.conf
+++ b/ci-scripts/conf_files/rcc.band7.tm1.if4p5.lo.50PRB.usrpb210.conf
@@ -7,7 +7,7 @@ eNBs =
  {
     # real_time choice in {hard, rt-preempt, no}
     real_time       =  "no";
- 
+
     ////////// Identification parameters:
     eNB_ID    =  0xe00;
 
@@ -207,18 +207,18 @@ MACRLCs = (
 	phy_test_mode = 0;
         puSch10xSnr     =  160;
         puCch10xSnr     =  160;
-        }  
+        }
 );
 
 L1s = (
-    	{
+      {
 	num_cc = 1;
 	tr_n_preference = "local_mac";
-        }  
+      }
 );
 
 RUs = (
-    {		  
+    {
         local_if_name  = "lo";
         remote_address = "127.0.0.2";
         local_address  = "127.0.0.1";
@@ -234,7 +234,7 @@ RUs = (
         att_rx         = 0;
         eNB_instances  = [0];
     }
-);  
+);
 
 THREAD_STRUCT = (
   {
@@ -272,4 +272,3 @@ NETWORK_CONTROLLER :
        rrc_log_level                         ="info";
        rrc_log_verbosity                     ="medium";
     };
-
diff --git a/ci-scripts/conf_files/rru.fdd.band7.conf b/ci-scripts/conf_files/rru.fdd.band7.conf
index dab69e1f1ed4c5833f843ef3d9cdd90e4f6b740b..ea923ae3718a6a61ed08481d16e1f91df8f1db5b 100644
--- a/ci-scripts/conf_files/rru.fdd.band7.conf
+++ b/ci-scripts/conf_files/rru.fdd.band7.conf
@@ -42,4 +42,3 @@ log_config = {
       rrc_log_level                         ="error";
       rrc_log_verbosity                     ="medium";
 };
-
diff --git a/ci-scripts/conf_files/rru.tdd.band40.conf b/ci-scripts/conf_files/rru.tdd.band40.conf
index 775a2fbc67076b6999f02a84e1e1afd7365ede10..fb2b9399e23551a3281915a8ca7a551fb05f30b0 100644
--- a/ci-scripts/conf_files/rru.tdd.band40.conf
+++ b/ci-scripts/conf_files/rru.tdd.band40.conf
@@ -42,4 +42,3 @@ log_config = {
       rrc_log_level                         ="error";
       rrc_log_verbosity                     ="medium";
 };
-
diff --git a/ci-scripts/conf_files/ue.nfapi.conf b/ci-scripts/conf_files/ue.nfapi.conf
index ea0236cab4e97b640b0c8ac17601ccb184c22c25..355b70326b7c749a0ae8c7ef11c5f0c2fd79ad28 100644
--- a/ci-scripts/conf_files/ue.nfapi.conf
+++ b/ci-scripts/conf_files/ue.nfapi.conf
@@ -17,21 +17,21 @@ log_config = {
 
 
 L1s = (
-    	{
+        {
 	num_cc = 1;
 	tr_n_preference = "nfapi";
-    	local_n_if_name  = "lo";
-      	remote_n_address = "127.0.0.2";
-    	local_n_address  = "127.0.0.1";
-    	local_n_portc    = 50000;
-    	remote_n_portc   = 50001;
-    	local_n_portd    = 50010;
-    	remote_n_portd   = 50011;
-        }  
+        local_n_if_name  = "lo";
+        remote_n_address = "127.0.0.2";
+        local_n_address  = "127.0.0.1";
+        local_n_portc    = 50000;
+        remote_n_portc   = 50001;
+        local_n_portd    = 50010;
+        remote_n_portd   = 50011;
+        }
 );
 
 RUs = (
-    {		  
+    {
        local_rf       = "yes"
        nb_tx          = 1
        nb_rx          = 1
@@ -40,5 +40,5 @@ RUs = (
        bands          = [7,38,42,43];
        max_pdschReferenceSignalPower = -27;
        max_rxgain                    = 125;
-    }		      
+    }
 );
diff --git a/ci-scripts/cppcheck_suppressions.list b/ci-scripts/cppcheck_suppressions.list
index 007d8555e2a1f427d3e59b39948768bc2f0a9643..4536f5731561dcca5ba7a39fef6f56e14689e91d 100644
--- a/ci-scripts/cppcheck_suppressions.list
+++ b/ci-scripts/cppcheck_suppressions.list
@@ -24,26 +24,26 @@
 // section for "valid" memory leaks: the related functions are allocators and
 // the caller is responsible of freeing the memory. cppcheck has a mechanism
 // to check more accuretaly this, by defining callers responsible of freeing
-// but tools like valgring might be more suitable 
+// but tools like valgring might be more suitable
 //
 //-----------------------------------------------------------------------------
-//    suppress error about keysP memory leak, free must be done by calling func 
+//    suppress error about keysP memory leak, free must be done by calling func
 memleak:common/utils/hashtable/obj_hashtable.c
 //-----------------------------------------------------------------------------
-//    suppress error about keys memory leak, free must be done by calling func 
+//    suppress error about keys memory leak, free must be done by calling func
 memleak:openair2/UTIL/OMG/omg_hashtable.c
 //-----------------------------------------------------------------------------
-//     suppress error about data memory leak. This is the buffer where 
+//     suppress error about data memory leak. This is the buffer where
 //    _emm_as_encode function creates the encoded buffer
 //
 memleak:openair3/NAS/UE/EMM/SAP/emm_as.c
 //-----------------------------------------------------------------------------
 //*****************************************************************************
-// section for files not used in oai exec's included in CI. 
+// section for files not used in oai exec's included in CI.
 // Possibly candidates for removal otherwise should be documented and updated
 // for project rules enforcement
 // ----------------------------------------------------------------------------
-// likely sources for test programs, maintained? 
+// likely sources for test programs, maintained?
 invalidPrintfArgType_sint:openair1/PHY/CODING/TESTBENCH/ltetest.c
 memleak:openair1/PHY/CODING/TESTBENCH/ltetest.c
 invalidPrintfArgType_sint:openair1/PHY/CODING/TESTBENCH/pdcch_test.c
@@ -72,14 +72,14 @@ uninitvar:openair2/UTIL/OTG/otg_rx_socket.c
 // iteration of the loop.
 nullPointer:common/utils/T/local_tracer.c:243
 //-----------------------------------------------------------------------------
-// once again cppcheck is not to understand that fds is initialized in the
+// once again cppcheck does not understand that fds is initialized in the
 // first iteration of the loop
 nullPointer:common/utils/T/tracer/multi.c:264
 nullPointer:common/utils/T/tracer/multi.c:265
 //
 //*****************************************************************************
-// 
-// True problems we don't know how to fix, Suppression is commented out, 
+//
+// True problems we don't know how to fix, Suppression is commented out,
 // as these kind of problem need either to be fixed or can be suppressed
 // when fully uderstood
 //-----------------------------------------------------------------------------
@@ -89,13 +89,13 @@ nullPointer:common/utils/T/tracer/multi.c:265
 // memleak:nfapi/open-nFAPI/pnf/src/pnf_p7_interface.c
 // memleak:nfapi/open-nFAPI/vnf/src/vnf_p7_interface.c
 //-----------------------------------------------------------------------------
-// may be security_data->kenb.value is released from calling functions. But even 
-// when, for test, freeing it before returning from emm_proc_security_mode_command 
+// may be security_data->kenb.value is released from calling functions. But even
+// when, for test, freeing it before returning from emm_proc_security_mode_command
 // which does the allocation, cppcheck complains. So something might be wrong...
 // memleak:openair3/NAS/UE/EMM/SecurityModeControl.c
 //-----------------------------------------------------------------------------
 // when used, nobody but the original developer can guess if sn_data_cnf is set or not
-// cppcheck found that in some cases it is not, code needs cleanup before fixing that...  
+// cppcheck found that in some cases it is not, code needs cleanup before fixing that...
 // uninitvar:openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_status_report.c
 //*****************************************************************************
 // *INDENT-ON*
diff --git a/ci-scripts/main.py b/ci-scripts/main.py
index 5f737361ac4003152a18073b7f35177f8cf234a0..ad8daa7b5e7adc78595e1bfe381ac083db35c20d 100644
--- a/ci-scripts/main.py
+++ b/ci-scripts/main.py
@@ -1,4 +1,3 @@
-#/*
 # * 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.
@@ -43,6 +42,9 @@ ENB_PROCESS_SEG_FAULT = -11
 ENB_PROCESS_ASSERTION = -12
 ENB_PROCESS_REALTIME_ISSUE = -13
 ENB_PROCESS_NOLOGFILE_TO_ANALYZE = -14
+UE_PROCESS_NOLOGFILE_TO_ANALYZE = -20
+UE_PROCESS_COULD_NOT_SYNC = -21
+UE_PROCESS_ASSERTION = -22
 HSS_PROCESS_FAILED = -2
 HSS_PROCESS_OK = +2
 MME_PROCESS_FAILED = -3
@@ -122,13 +124,20 @@ class SSHConnection():
 		self.htmlTabNames = []
 		self.htmlTabIcons = []
 		self.finalStatus = False
-		self.eNBOsVersion = ''
-		self.eNBKernelVersion = ''
-		self.eNBUhdVersion = ''
-		self.eNBUsrpBoard = ''
-		self.eNBCpuNb = ''
-		self.eNBCpuModel = ''
-		self.eNBCpuMHz = ''
+		self.OsVersion = ''
+		self.KernelVersion = ''
+		self.UhdVersion = ''
+		self.UsrpBoard = ''
+		self.CpuNb = ''
+		self.CpuModel = ''
+		self.CpuMHz = ''
+		self.UEIPAddress = ''
+		self.UEUserName = ''
+		self.UEPassword = ''
+		self.UE_instance = ''
+		self.UESourceCodePath = ''
+		self.Build_OAI_UE_args = ''
+		self.Initialize_OAI_UE_args = ''
 		self.flexranCtrlInstalled = False
 		self.flexranCtrlStarted = False
 		self.expectedNbOfConnectedUEs = 0
@@ -327,11 +336,46 @@ class SSHConnection():
 		self.command('mkdir -p build_log_' + self.testCase_id, '\$', 5)
 		self.command('mv log/* ' + 'build_log_' + self.testCase_id, '\$', 5)
 		self.command('mv compile_oai_enb.log ' + 'build_log_' + self.testCase_id, '\$', 5)
-		# Workaround to run with develop-nr
-		self.command('if [ -e ran_build ]; then cp -rf ran_build lte_build_oai; fi', '\$', 30)
 		self.close()
 		self.CreateHtmlTestRow(self.Build_eNB_args, 'OK', ALL_PROCESSES_OK)
 
+	def BuildOAIUE(self):
+		if self.UEIPAddress == '' or self.eNBRepository == '' or self.eNBBranch == '' or self.UEUserName == '' or self.UEPassword == '' or self.UESourceCodePath == '':
+			Usage()
+			sys.exit('Insufficient Parameter')
+		self.open(self.UEIPAddress, self.UEUserName, self.UEPassword)
+		self.command('mkdir -p ' + self.UESourceCodePath, '\$', 5)
+		self.command('cd ' + self.UESourceCodePath, '\$', 5)
+		self.command('if [ ! -e .git ]; then stdbuf -o0 git clone ' + self.eNBRepository + ' .; else stdbuf -o0 git fetch; fi', '\$', 600)
+		# here add a check if git clone or git fetch went smoothly
+		self.command('git config user.email "jenkins@openairinterface.org"', '\$', 5)
+		self.command('git config user.name "OAI Jenkins"', '\$', 5)
+		self.command('echo ' + self.UEPassword + ' | sudo -S git clean -x -d -ff', '\$', 30)
+		# if the commit ID is provided use it to point to it
+		if self.eNBCommitID != '':
+			self.command('git checkout -f ' + self.eNBCommitID, '\$', 5)
+		# if the branch is not develop, then it is a merge request and we need to do 
+		# the potential merge. Note that merge conflicts should already been checked earlier
+		if (self.eNB_AllowMerge):
+			if self.eNBTargetBranch == '':
+				if (self.eNBBranch != 'develop') and (self.eNBBranch != 'origin/develop'):
+					self.command('git merge --ff origin/develop -m "Temporary merge for CI"', '\$', 5)
+			else:
+				logging.debug('Merging with the target branch: ' + self.eNBTargetBranch)
+				self.command('git merge --ff origin/' + self.eNBTargetBranch + ' -m "Temporary merge for CI"', '\$', 5)
+		self.command('source oaienv', '\$', 5)
+		self.command('cd cmake_targets', '\$', 5)
+		self.command('mkdir -p log', '\$', 5)
+		self.command('chmod 777 log', '\$', 5)
+		# no need to remove in log (git clean did the trick)
+		self.command('stdbuf -o0 ./build_oai ' + self.Build_OAI_UE_args + ' 2>&1 | stdbuf -o0 tee -a compile_oai_ue.log', 'Bypassing the Tests', 600)
+		self.command('mkdir -p build_log_' + self.testCase_id, '\$', 5)
+		self.command('mv log/* ' + 'build_log_' + self.testCase_id, '\$', 5)
+		self.command('mv compile_oai_ue.log ' + 'build_log_' + self.testCase_id, '\$', 5)
+		self.close()
+		self.CreateHtmlTestRow(self.Build_OAI_UE_args, 'OK', ALL_PROCESSES_OK, 'OAI UE')
+
+
 	def InitializeHSS(self):
 		if self.EPCIPAddress == '' or self.EPCUserName == '' or self.EPCPassword == '' or self.EPCSourceCodePath == '' or self.EPCType == '':
 			Usage()
@@ -488,8 +532,8 @@ class SSHConnection():
 		# Launch eNB with the modified config file
 		self.command('source oaienv', '\$', 5)
 		self.command('cd cmake_targets', '\$', 5)
-		self.command('echo "ulimit -c unlimited && ./lte_build_oai/build/lte-softmodem -O ' + self.eNBSourceCodePath + '/' + ci_full_config_file + extra_options + '" > ./my-lte-softmodem-run' + str(self.eNB_instance) + '.sh ', '\$', 5)
-		self.command('chmod 775 ./my-lte-softmodem-run' + str(self.eNB_instance) + '.sh ', '\$', 5)
+		self.command('echo "ulimit -c unlimited && ./lte_build_oai/build/lte-softmodem -O ' + self.eNBSourceCodePath + '/' + ci_full_config_file + extra_options + '" > ./my-lte-softmodem-run' + str(self.eNB_instance) + '.sh', '\$', 5)
+		self.command('chmod 775 ./my-lte-softmodem-run' + str(self.eNB_instance) + '.sh', '\$', 5)
 		self.command('echo ' + self.eNBPassword + ' | sudo -S rm -Rf enb_' + self.testCase_id + '.log', '\$', 5)
 		self.command('echo ' + self.eNBPassword + ' | sudo -S -E daemon --inherit --unsafe --name=enb' + str(self.eNB_instance) + '_daemon --chdir=' + self.eNBSourceCodePath + '/cmake_targets -o ' + self.eNBSourceCodePath + '/cmake_targets/enb_' + self.testCase_id + '.log ./my-lte-softmodem-run' + str(self.eNB_instance) + '.sh', '\$', 5)
 		if not rruCheck:
@@ -574,6 +618,99 @@ class SSHConnection():
 			job.join()
 		self.CreateHtmlTestRow('N/A', 'OK', ALL_PROCESSES_OK)
 
+	def InitializeOAIUE(self):
+		if self.UEIPAddress == '' or self.UEUserName == '' or self.UEPassword == '' or self.UESourceCodePath == '':
+			Usage()
+			sys.exit('Insufficient Parameter')
+		#initialize_OAI_UE_flag = True
+		#pStatus = self.CheckOAIUEProcessExist(initialize_OAI_UE_flag)
+		#if (pStatus < 0):
+		#	self.CreateHtmlTestRow(self.Initialize_OAI_UE_args, 'KO', pStatus)
+		#	self.CreateHtmlTabFooter(False)
+		#	sys.exit(1)
+		self.open(self.UEIPAddress, self.UEUserName, self.UEPassword)
+		# b2xx_fx3_utils reset procedure
+		self.command('echo ' + self.UEPassword + ' | sudo -S uhd_find_devices', '\$', 5)
+		result = re.search('type: b200', str(self.ssh.before))
+		if result is not None:
+			logging.debug('Found a B2xx device --> resetting it')
+			self.command('echo ' + self.UEPassword + ' | sudo -S sudo b2xx_fx3_utils --reset-device', '\$', 5)
+			# Reloading FGPA bin firmware
+			self.command('echo ' + self.UEPassword + ' | sudo -S uhd_find_devices', '\$', 5)
+		else:
+			logging.debug('Did not find any B2xx device')
+		self.command('cd ' + self.UESourceCodePath, '\$', 5)
+		# Initialize_OAI_UE_args usually start with -C and followed by the location in repository
+		#full_config_file = self.Initialize_OAI_UE_args.replace('-O ','')
+		#extIdx = full_config_file.find('.conf')
+		#if (extIdx > 0):
+		#	extra_options = full_config_file[extIdx + 5:]
+		#	# if tracer options is on, compiling and running T Tracer
+		#	result = re.search('T_stdout', str(extra_options))
+		##	if result is not None:
+		#		logging.debug('\u001B[1m Compiling and launching T Tracer\u001B[0m')
+		#		self.command('cd common/utils/T/tracer', '\$', 5)
+		#		self.command('make', '\$', 10)
+		#		self.command('echo $USER; nohup ./record -d ../T_messages.txt -o ' + self.UESourceCodePath + '/cmake_targets/ue_' + self.testCase_id + '_record.raw -ON -off VCD -off HEAVY -off LEGACY_GROUP_TRACE -off LEGACY_GROUP_DEBUG > ' + self.UESourceCodePath + '/cmake_targets/enb_' + self.testCase_id + '_record.log 2>&1 &', self.UEUserName, 5)
+		#		self.command('cd ' + self.UESourceCodePath, '\$', 5)
+		#	full_config_file = full_config_file[:extIdx + 5]
+		#	config_path, config_file = os.path.split(full_config_file)
+		#ci_full_config_file = config_path + '/ci-' + config_file
+		#rruCheck = False
+		#result = re.search('rru', str(config_file))
+		#if result is not None:
+		#	rruCheck = True
+		## Make a copy and adapt to EPC / UE IP addresses
+		#self.command('cp ' + full_config_file + ' ' + ci_full_config_file, '\$', 5)
+		#self.command('sed -i -e \'s/CI_UE_IP_ADDR/' + self.UEIPAddress + '/\' ' + ci_full_config_file, '\$', 2);
+		# Launch UE with the modified config file
+		self.command('source oaienv', '\$', 5)
+		self.command('cd cmake_targets/lte_build_oai/build', '\$', 5)
+		self.command('echo "ulimit -c unlimited && ./lte-uesoftmodem ' + self.Initialize_OAI_UE_args + '" > ./my-lte-uesoftmodem-run' + str(self.UE_instance) + '.sh', '\$', 5)
+		self.command('chmod 775 ./my-lte-uesoftmodem-run' + str(self.UE_instance) + '.sh', '\$', 5)
+		self.command('echo ' + self.UEPassword + ' | sudo -S rm -Rf ' + self.UESourceCodePath + '/cmake_targets/ue_' + self.testCase_id + '.log', '\$', 5)
+		self.command('echo ' + self.UEPassword + ' | sudo -S -E daemon --inherit --unsafe --name=ue' + str(self.UE_instance) + '_daemon --chdir=' + self.UESourceCodePath + '/cmake_targets/lte_build_oai/build -o ' + self.UESourceCodePath + '/cmake_targets/ue_' + self.testCase_id + '.log ./my-lte-uesoftmodem-run' + str(self.UE_instance) + '.sh', '\$', 5)
+		self.UELogFile = 'ue_' + self.testCase_id + '.log'
+		time.sleep(6)
+		self.command('cd ../..', '\$', 5)
+		doLoop = True
+		loopCounter = 10
+		while (doLoop):
+			loopCounter = loopCounter - 1
+			if (loopCounter == 0):
+				# In case of T tracer recording, we may need to kill it
+				#result = re.search('T_stdout', str(self.Initialize_OAI_UE_args))
+				#if result is not None:
+				#	self.command('killall --signal SIGKILL record', '\$', 5)
+				self.close()
+				doLoop = False
+				logging.error('\u001B[1;37;41m UE logging system did not show got sync! \u001B[0m')
+				self.CreateHtmlTestRow(self.Initialize_OAI_UE_args, 'KO', ALL_PROCESSES_OK, 'OAI UE')
+				self.CreateHtmlTabFooter(False)
+				## In case of T tracer recording, we need to kill tshark on EPC side
+				#result = re.search('T_stdout', str(self.Initialize_OAI_UE_args))
+				#if result is not None:
+				#	self.open(self.EPCIPAddress, self.EPCUserName, self.EPCPassword)
+				#	logging.debug('\u001B[1m Stopping tshark \u001B[0m')
+				#	self.command('echo ' + self.EPCPassword + ' | sudo -S killall --signal SIGKILL tshark', '\$', 5)
+				#	self.close()
+				#	time.sleep(1)
+				#	pcap_log_file = 'enb_' + self.testCase_id + '_s1log.pcap'
+				#	copyin_res = self.copyin(self.EPCIPAddress, self.EPCUserName, self.EPCPassword, '/tmp/' + pcap_log_file, '.')
+				#	if (copyin_res == 0):
+				#		self.copyout(self.UEIPAddress, self.UEUserName, self.UEPassword, pcap_log_file, self.UESourceCodePath + '/cmake_targets/.')
+				sys.exit(1)
+			else:
+				self.command('stdbuf -o0 cat ue_' + self.testCase_id + '.log | egrep --text --color=never -i "wait|sync"', '\$', 4)
+				result = re.search('got sync', str(self.ssh.before))
+				if result is None:
+					time.sleep(6)
+				else:
+					doLoop = False
+					self.CreateHtmlTestRow(self.Initialize_OAI_UE_args, 'OK', ALL_PROCESSES_OK, 'OAI UE')
+					logging.debug('\u001B[1m Initialize OAI UE Completed\u001B[0m')
+		self.close()
+
 	def checkDevTTYisUnlocked(self):
 		self.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword)
 		count = 0
@@ -1873,6 +2010,48 @@ class SSHConnection():
 					self.TerminateFlexranCtrl()
 			return result
 
+	def CheckOAIUEProcessExist(self, initialize_OAI_UE_flag):
+		multi_jobs = []
+		status_queue = SimpleQueue()
+		if initialize_OAI_UE_flag == False:
+			p = Process(target = SSH.CheckOAIUEProcess, args = (status_queue,))
+			p.daemon = True
+			p.start()
+			multi_jobs.append(p)
+		for job in multi_jobs:
+			job.join()
+
+		if (status_queue.empty()):
+			return -15
+		else:
+			result = 0
+			while (not status_queue.empty()):
+				status = status_queue.get()
+				if (status < 0):
+					result = status
+			if result == OAI_UE_PROCESS_FAILED:
+				fileCheck = re.search('enb_', str(self.UELogFile))
+				if fileCheck is not None:
+					self.copyin(self.UEIPAddress, self.UEUserName, self.UEPassword, self.UESourceCodePath + '/cmake_targets/' + self.UELogFile, '.')
+					logStatus = self.AnalyzeLogFile_UE(self.UELogFile)
+					if logStatus < 0:
+						result = logStatus
+			return result
+
+	def CheckOAIUEProcess(self, status_queue):
+		try:
+			self.open(self.OAIUEIPAddress, self.OAIUEUserName, self.OAIUEPassword)
+			self.command('stdbuf -o0 ps -aux | grep -v grep | grep --color=never lte-uesoftmodem', '\$', 5)
+			result = re.search('lte-uesoftmodem', str(self.ssh.before))
+			if result is None:
+				logging.debug('\u001B[1;37;41m OAI UE Process Not Found! \u001B[0m')
+				status_queue.put(OAI_UE_PROCESS_FAILED)
+			else:
+				status_queue.put(OAI_UE_PROCESS_OK)
+			self.close()
+		except:
+			os.kill(os.getppid(),signal.SIGUSR1)
+
 	def CheckeNBProcess(self, status_queue):
 		try:
 			self.open(self.eNBIPAddress, self.eNBUserName, self.eNBPassword)
@@ -2090,6 +2269,156 @@ class SSHConnection():
 			return ENB_PROCESS_REALTIME_ISSUE
 		return 0
 
+	def AnalyzeLogFile_UE(self, UElogFile):
+		if (not os.path.isfile('./' + UElogFile)):
+			return -1
+		ue_log_file = open('./' + UElogFile, 'r')
+		foundAssertion = False
+		msgAssertion = ''
+		msgLine = 0
+		foundSegFault = False
+		foundRealTimeIssue = False
+		rlcDiscardBuffer = 0
+		rachCanceledProcedure = 0
+		uciStatMsgCount = 0
+		pdcpFailure = 0
+		ulschFailure = 0
+		no_cell_sync_found = False
+		mib_found = False
+		frequency_found = False
+		self.htmlUEFailureMsg = ''
+		for line in ue_log_file.readlines():
+			result = re.search('[Ss]egmentation [Ff]ault', str(line))
+			if result is not None:
+				foundSegFault = True
+			result = re.search('[Cc]ore [dD]ump', str(line))
+			if result is not None:
+				foundSegFault = True
+			result = re.search('[Aa]ssertion', str(line))
+			if result is not None:
+				foundAssertion = True
+			result = re.search('LLL', str(line))
+			if result is not None:
+				foundRealTimeIssue = True
+			if foundAssertion and (msgLine < 3):
+				msgLine += 1
+				msgAssertion += str(line)
+			result = re.search('uci->stat', str(line))
+			if result is not None:
+				uciStatMsgCount += 1
+			# No cell synchronization found, abandoning
+			result = re.search('No cell synchronization found, abandoning', str(line))
+			if result is not None:
+				no_cell_sync_found = True
+			result = re.search("MIB Information => ([a-zA-Z]{1,10}), ([a-zA-Z]{1,10}), NidCell (?P<nidcell>\d{1,3}), N_RB_DL (?P<n_rb_dl>\d{1,3}), PHICH DURATION (?P<phich_duration>\d), PHICH RESOURCE (?P<phich_resource>.{1,4}), TX_ANT (?P<tx_ant>\d)", str(line))
+			if result is not None and (not mib_found):
+				try:
+					mibMsg = "MIB Information: " + result.group(1) + ', ' + result.group(2)
+					self.htmlUEFailureMsg += mibMsg + '\n'
+					logging.debug('\033[94m' + mibMsg + '\033[0m')
+					mibMsg = "    nidcell = " + result.group('nidcell')
+					self.htmlUEFailureMsg += mibMsg
+					logging.debug('\033[94m' + mibMsg + '\033[0m')
+					mibMsg = "    n_rb_dl = " + result.group('n_rb_dl')
+					self.htmlUEFailureMsg += mibMsg + '\n'
+					logging.debug('\033[94m' + mibMsg + '\033[0m')
+					mibMsg = "    phich_duration = " + result.group('phich_duration')
+					self.htmlUEFailureMsg += mibMsg
+					logging.debug('\033[94m' + mibMsg + '\033[0m')
+					mibMsg = "    phich_resource = " + result.group('phich_resource')
+					self.htmlUEFailureMsg += mibMsg + '\n'
+					logging.debug('\033[94m' + mibMsg + '\033[0m')
+					mibMsg = "    tx_ant = " + result.group('tx_ant')
+					self.htmlUEFailureMsg += mibMsg + '\n'
+					logging.debug('\033[94m' + mibMsg + '\033[0m')
+					mib_found = True
+				except Exception as e:
+					logging.error('\033[91m' + "MIB marker was not found" + '\033[0m')
+			result = re.search("Measured Carrier Frequency (?P<measured_carrier_frequency>\d{1,15}) Hz", str(line))
+			if result is not None and (not frequency_found):
+				try:
+					mibMsg = "Measured Carrier Frequency = " + result.group('measured_carrier_frequency') + ' Hz'
+					self.htmlUEFailureMsg += mibMsg + '\n'
+					logging.debug('\033[94m' + mibMsg + '\033[0m')
+					frequency_found = True
+				except Exception as e:
+					logging.error('\033[91m' + "Measured Carrier Frequency not found" + '\033[0m')
+			result = re.search("Found (?P<operator>[\w,\s]{1,15}) \(name from internal table\)", str(line))
+			if result is not None:
+				try:
+					mibMsg = "The operator is: " + result.group('operator')
+					self.htmlUEFailureMsg += mibMsg + '\n'
+					logging.debug('\033[94m' + mibMsg + '\033[0m')
+				except Exception as e:
+					logging.error('\033[91m' + "Operator name not found" + '\033[0m')
+			result = re.search("SIB5 InterFreqCarrierFreq element (.{1,4})/(.{1,4})", str(line))
+			if result is not None:
+				try:
+					mibMsg = "SIB5 InterFreqCarrierFreq element " + result.group(1) + '/' + result.group(2)
+					self.htmlUEFailureMsg += mibMsg + ' -> '
+					logging.debug('\033[94m' + mibMsg + '\033[0m')
+				except Exception as e:
+					logging.error('\033[91m' + "SIB5 InterFreqCarrierFreq element not found" + '\033[0m')
+			result = re.search("DL Carrier Frequency/ARFCN : (?P<carrier_frequency>\d{1,15}/\d{1,4})", str(line))
+			if result is not None:
+				try:
+					freq = result.group('carrier_frequency')
+					new_freq = re.sub('/[0-9]+','',freq)
+					float_freq = float(new_freq) / 1000000
+					self.htmlUEFailureMsg += 'DL Freq: ' + ('%.1f' % float_freq) + ' MHz'
+					logging.debug('\033[94m' + "    DL Carrier Frequency is: " + freq + '\033[0m')
+				except Exception as e:
+					logging.error('\033[91m' + "    DL Carrier Frequency not found" + '\033[0m')
+			result = re.search("AllowedMeasBandwidth : (?P<allowed_bandwidth>\d{1,7})", str(line))
+			if result is not None:
+				try:
+					prb = result.group('allowed_bandwidth')
+					self.htmlUEFailureMsg += ' -- PRB: ' + prb + '\n'
+					logging.debug('\033[94m' + "    AllowedMeasBandwidth: " + prb + '\033[0m')
+				except Exception as e:
+					logging.error('\033[91m' + "    AllowedMeasBandwidth not found" + '\033[0m')
+		ue_log_file.close()
+		if uciStatMsgCount > 0:
+			statMsg = 'UE showed ' + str(uciStatMsgCount) + ' "uci->stat" message(s)'
+			logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m')
+			self.htmlUEFailureMsg += statMsg + '\n'
+		if pdcpFailure > 0:
+			statMsg = 'UE showed ' + str(pdcpFailure) + ' "PDCP Out of Resources" message(s)'
+			logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m')
+			self.htmlUEFailureMsg += statMsg + '\n'
+		if ulschFailure > 0:
+			statMsg = 'UE showed ' + str(ulschFailure) + ' "ULSCH in error in round" message(s)'
+			logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m')
+			self.htmlUEFailureMsg += statMsg + '\n'
+		if rachCanceledProcedure > 0:
+			rachMsg = 'UE cancelled ' + str(rachCanceledProcedure) + ' RA procedure(s)'
+			logging.debug('\u001B[1;30;43m ' + rachMsg + ' \u001B[0m')
+			self.htmlUEFailureMsg += rachMsg + '\n'
+		if foundSegFault:
+			logging.debug('\u001B[1;37;41m UE ended with a Segmentation Fault! \u001B[0m')
+			return ENB_PROCESS_SEG_FAULT
+		if foundAssertion:
+			logging.debug('\u001B[1;37;43m UE ended with an assertion! \u001B[0m')
+			# removed for esthetics
+			#self.htmlUEFailureMsg += msgAssertion
+			self.htmlUEFailureMsg += 'UE ended with an assertion!\n'
+			if not mib_found or not frequency_found:
+				return UE_PROCESS_ASSERTION
+		if foundRealTimeIssue:
+			logging.debug('\u001B[1;37;41m UE faced real time issues! \u001B[0m')
+			self.htmlUEFailureMsg += 'UE faced real time issues!\n'
+			#return ENB_PROCESS_REALTIME_ISSUE
+		if no_cell_sync_found and not mib_found:
+			logging.debug('\u001B[1;37;41m UE could not synchronize ! \u001B[0m')
+			self.htmlUEFailureMsg += 'UE could not synchronize!\n'
+			return UE_PROCESS_COULD_NOT_SYNC
+		if rlcDiscardBuffer > 0:
+			rlcMsg = 'UE RLC discarded ' + str(rlcDiscardBuffer) + ' buffer(s)'
+			logging.debug('\u001B[1;37;41m ' + rlcMsg + ' \u001B[0m')
+			self.htmlUEFailureMsg += rlcMsg + '\n'
+			return ENB_PROCESS_REALTIME_ISSUE
+		return 0
+
 	def TerminateeNB(self):
 		self.open(self.eNBIPAddress, self.eNBUserName, self.eNBPassword)
 		self.command('cd ' + self.eNBSourceCodePath + '/cmake_targets', '\$', 5)
@@ -2245,6 +2574,75 @@ class SSHConnection():
 			job.join()
 		self.CreateHtmlTestRow('N/A', 'OK', ALL_PROCESSES_OK)
 
+	def TerminateOAIUE(self):
+		self.open(self.UEIPAddress, self.UEUserName, self.UEPassword)
+		self.command('cd ' + self.UESourceCodePath + '/cmake_targets', '\$', 5)
+		self.command('echo ' + self.UEPassword + ' | sudo -S daemon --name=ue' + str(self.UE_instance) + '_daemon --stop', '\$', 5)
+		self.command('rm -f my-lte-uesoftmodem-run' + str(self.UE_instance) + '.sh', '\$', 5)
+		self.command('echo ' + self.UEPassword + ' | sudo -S killall --signal SIGINT lte-uesoftmodem || true', '\$', 5)
+		time.sleep(5)
+		self.command('stdbuf -o0  ps -aux | grep -v grep | grep lte-uesoftmodem', '\$', 5)
+		result = re.search('lte-uesoftmodem', str(self.ssh.before))
+		if result is not None:
+			self.command('echo ' + self.UEPassword + ' | sudo -S killall --signal SIGKILL lte-uesoftmodem || true', '\$', 5)
+			time.sleep(5)
+		self.close()
+		# If tracer options is on, stopping tshark on EPC side
+		result = re.search('T_stdout', str(self.Initialize_OAI_UE_args))
+		if result is not None:
+			self.open(self.UEIPAddress, self.UEUserName, self.UEPassword)
+			logging.debug('\u001B[1m Stopping tshark \u001B[0m')
+			self.command('echo ' + self.UEPassword + ' | sudo -S killall --signal SIGKILL tshark', '\$', 5)
+			time.sleep(1)
+			pcap_log_file = self.UELogFile.replace('.log', '_s1log.pcap')
+			self.command('echo ' + self.UEPassword + ' | sudo -S chmod 666 /tmp/' + pcap_log_file, '\$', 5)
+			self.copyin(self.UEIPAddress, self.UEUserName, self.UEPassword, '/tmp/' + pcap_log_file, '.')
+			self.copyout(self.UEIPAddress, self.UEUserName, self.UEPassword, pcap_log_file, self.UESourceCodePath + '/cmake_targets/.')
+			self.close()
+			logging.debug('\u001B[1m Replaying RAW record file\u001B[0m')
+			self.open(self.UEIPAddress, self.UEUserName, self.UEPassword)
+			self.command('cd ' + self.UESourceCodePath + '/common/utils/T/tracer/', '\$', 5)
+			raw_record_file = self.UELogFile.replace('.log', '_record.raw')
+			replay_log_file = self.UELogFile.replace('.log', '_replay.log')
+			extracted_txt_file = self.UELogFile.replace('.log', '_extracted_messages.txt')
+			extracted_log_file = self.UELogFile.replace('.log', '_extracted_messages.log')
+			self.command('./extract_config -i ' + self.UESourceCodePath + '/cmake_targets/' + raw_record_file + ' > ' + self.UESourceCodePath + '/cmake_targets/' + extracted_txt_file, '\$', 5)
+			self.command('echo $USER; nohup ./replay -i ' + self.UESourceCodePath + '/cmake_targets/' + raw_record_file + ' > ' + self.UESourceCodePath + '/cmake_targets/' + replay_log_file + ' 2>&1 &', self.UEUserName, 5)
+			self.command('./textlog -d ' +  self.UESourceCodePath + '/cmake_targets/' + extracted_txt_file + ' -no-gui -ON -full > ' + self.UESourceCodePath + '/cmake_targets/' + extracted_log_file, '\$', 5)
+			self.close()
+			self.copyin(self.UEIPAddress, self.UEUserName, self.UEPassword, self.UESourceCodePath + '/cmake_targets/' + extracted_log_file, '.')
+			logging.debug('\u001B[1m Analyzing UE replay logfile \u001B[0m')
+			logStatus = self.AnalyzeLogFile_UE(extracted_log_file)
+			self.CreateHtmlTestRow(html_queue, 'OK', ALL_PROCESSES_OK)
+			self.UELogFile = ''
+		else:
+			result = re.search('ue_', str(self.UELogFile))
+			if result is not None:
+				copyin_res = self.copyin(self.UEIPAddress, self.UEUserName, self.UEPassword, self.UESourceCodePath + '/cmake_targets/' + self.UELogFile, '.')
+				if (copyin_res == -1):
+					logging.debug('\u001B[1;37;41m Could not copy UE logfile to analyze it! \u001B[0m')
+					optionsMsg = '<pre style="background-color:white">Could not copy UE logfile to analyze it!</pre>'
+					self.CreateHtmlTestRow(optionsMsg, 'KO', UE_PROCESS_NOLOGFILE_TO_ANALYZE, 'UE')
+					self.UELogFile = ''
+					return
+				logging.debug('\u001B[1m Analyzing UE logfile \u001B[0m')
+				logStatus = self.AnalyzeLogFile_UE(self.UELogFile)
+				if (logStatus < 0):
+					optionsMsg = '<pre style="background-color:white"><b>Sniffing Unsuccessful</b>\n'
+					optionsMsg += self.htmlUEFailureMsg
+					optionsMsg += '</pre>'
+					self.CreateHtmlTestRow(optionsMsg, 'KO', logStatus, 'UE')
+					self.CreateHtmlTabFooter(False)
+					sys.exit(1)
+				else:
+					optionsMsg = '<pre style="background-color:white"><b>Sniffing Successful</b>\n'
+					optionsMsg += self.htmlUEFailureMsg
+					optionsMsg += '</pre>'
+					self.CreateHtmlTestRow(optionsMsg, 'OK', ALL_PROCESSES_OK)
+				self.UELogFile = ''
+			else:
+				self.CreateHtmlTestRow('<pre style="background-color:white">No Log File to analyze</pre>', 'OK', ALL_PROCESSES_OK)
+
 	def AutoTerminateUEandeNB(self):
 		self.testCase_id = 'AUTO-KILL-UE'
 		self.desc = 'Automatic Termination of UE'
@@ -2261,12 +2659,24 @@ class SSHConnection():
 		self.CreateHtmlTestRow(str(self.idle_sleep_time) + ' sec', 'OK', ALL_PROCESSES_OK)
 
 	def LogCollectBuild(self):
-		self.open(self.eNBIPAddress, self.eNBUserName, self.eNBPassword)
-		self.command('cd ' + self.eNBSourceCodePath, '\$', 5)
+		if (self.eNBIPAddress != '' and self.eNBUserName != '' and self.eNBPassword != ''):
+			IPAddress = self.eNBIPAddress
+			UserName = self.eNBUserName
+			Password = self.eNBPassword
+			SourceCodePath = self.eNBSourceCodePath
+		elif (self.UEIPAddress != '' and self.UEUserName != '' and self.UEPassword != ''):
+			IPAddress = self.UEIPAddress
+			UserName = self.UEUserName
+			Password = self.UEPassword
+			SourceCodePath = self.UESourceCodePath
+		else:
+			sys.exit('Insufficient Parameter')
+		self.open(IPAddress, UserName, Password)
+		self.command('cd ' + SourceCodePath, '\$', 5)
 		self.command('cd cmake_targets', '\$', 5)
 		self.command('rm -f build.log.zip', '\$', 5)
 		self.command('zip build.log.zip build_log_*/*', '\$', 60)
-		self.command('echo ' + self.eNBPassword + ' | sudo -S rm -rf build_log_*', '\$', 5)
+		self.command('echo ' + Password + ' | sudo -S rm -rf build_log_*', '\$', 5)
 		self.close()
 
 	def LogCollecteNB(self):
@@ -2335,49 +2745,69 @@ class SSHConnection():
 			self.command('zip spgw.log.zip xGwLog.0', '\$', 60)
 		self.close()
 
+	def LogCollectOAIUE(self):
+		self.open(self.UEIPAddress, self.UEUserName, self.UEPassword)
+		self.command('cd ' + self.UESourceCodePath, '\$', 5)
+		self.command('cd cmake_targets', '\$', 5)
+		self.command('echo ' + self.UEPassword + ' | sudo -S rm -f ue.log.zip', '\$', 5)
+		self.command('echo ' + self.UEPassword + ' | sudo -S zip ue.log.zip ue*.log core* ue_*record.raw ue_*.pcap ue_*txt', '\$', 60)
+		self.command('echo ' + self.UEPassword + ' | sudo -S rm ue*.log core* ue_*record.raw ue_*.pcap ue_*txt', '\$', 5)
+		self.close()
+
 	def RetrieveSystemVersion(self):
 		if self.eNBIPAddress == 'none':
-			self.eNBOsVersion = 'Ubuntu 16.04.5 LTS'
-			self.eNBKernelVersion = '4.15.0-45-generic'
-			self.eNBUhdVersion = '3.13.0.1-0'
-			self.eNBUsrpBoard = 'B210'
-			self.eNBCpuNb = '4'
-			self.eNBCpuModel = 'Intel(R) Core(TM) i5-6200U'
-			self.eNBCpuMHz = '2399.996 MHz'
+			self.OsVersion = 'Ubuntu 16.04.5 LTS'
+			self.KernelVersion = '4.15.0-45-generic'
+			self.UhdVersion = '3.13.0.1-0'
+			self.UsrpBoard = 'B210'
+			self.CpuNb = '4'
+			self.CpuModel = 'Intel(R) Core(TM) i5-6200U'
+			self.CpuMHz = '2399.996 MHz'
 			return
-		if self.eNBIPAddress == '' or self.eNBUserName == '' or self.eNBPassword == '':
+		machine = None
+		if self.eNBIPAddress != '' and self.eNBUserName != '' and self.eNBPassword != '':
+			machine = 'eNB'
+			IPAddress = self.eNBIPAddress
+			UserName = self.eNBUserName
+			Password = self.eNBPassword
+		elif self.UEIPAddress != '' and self.UEUserName != '' and self.UEPassword != '':
+			machine = 'UE'
+			IPAddress = self.UEIPAddress
+			UserName = self.UEUserName
+			Password = self.UEPassword
+		if machine is None:
 			Usage()
 			sys.exit('Insufficient Parameter')
-		self.open(self.eNBIPAddress, self.eNBUserName, self.eNBPassword)
+		self.open(IPAddress, UserName, Password)
 		self.command('lsb_release -a', '\$', 5)
 		result = re.search('Description:\\\\t(?P<os_type>[a-zA-Z0-9\-\_\.\ ]+)', str(self.ssh.before))
 		if result is not None:
-			self.eNBOsVersion = result.group('os_type')
-			logging.debug('OS is: ' + self.eNBOsVersion)
+			self.OsVersion = result.group('os_type')
+			logging.debug('OS is: ' + self.OsVersion)
 		self.command('uname -r', '\$', 5)
 		result = re.search('uname -r\\\\r\\\\n(?P<kernel_version>[a-zA-Z0-9\-\_\.]+)', str(self.ssh.before))
 		if result is not None:
-			self.eNBKernelVersion = result.group('kernel_version')
-			logging.debug('Kernel Version is: ' + self.eNBKernelVersion)
+			self.KernelVersion = result.group('kernel_version')
+			logging.debug('Kernel Version is: ' + self.KernelVersion)
 		self.command('dpkg --list | egrep --color=never libuhd003', '\$', 5)
 		result = re.search('libuhd003:amd64 *(?P<uhd_version>[0-9\.]+)', str(self.ssh.before))
 		if result is not None:
-			self.eNBUhdVersion = result.group('uhd_version')
-			logging.debug('UHD Version is: ' + self.eNBUhdVersion)
-		self.command('echo ' + self.eNBPassword + ' | sudo -S uhd_find_devices', '\$', 5)
+			self.UhdVersion = result.group('uhd_version')
+			logging.debug('UHD Version is: ' + self.UhdVersion)
+		self.command('echo ' + Password + ' | sudo -S uhd_find_devices', '\$', 5)
 		result = re.search('product: (?P<usrp_board>[0-9A-Za-z]+)\\\\r\\\\n', str(self.ssh.before))
 		if result is not None:
-			self.eNBUsrpBoard = result.group('usrp_board')
-			logging.debug('USRP Board  is: ' + self.eNBUsrpBoard)
+			self.UsrpBoard = result.group('usrp_board')
+			logging.debug('USRP Board  is: ' + self.UsrpBoard)
 		self.command('lscpu', '\$', 5)
 		result = re.search('CPU\(s\): *(?P<nb_cpus>[0-9]+).*Model name: *(?P<model>[a-zA-Z0-9\-\_\.\ \(\)]+).*CPU MHz: *(?P<cpu_mhz>[0-9\.]+)', str(self.ssh.before))
 		if result is not None:
-			self.eNBCpuNb = result.group('nb_cpus')
-			logging.debug('nb_cpus: ' + self.eNBCpuNb)
-			self.eNBCpuModel = result.group('model')
-			logging.debug('model: ' + self.eNBCpuModel)
-			self.eNBCpuMHz = result.group('cpu_mhz') + ' MHz'
-			logging.debug('cpu_mhz: ' + self.eNBCpuMHz)
+			self.CpuNb = result.group('nb_cpus')
+			logging.debug('nb_cpus: ' + self.CpuNb)
+			self.CpuModel = result.group('model')
+			logging.debug('model: ' + self.CpuModel)
+			self.CpuMHz = result.group('cpu_mhz') + ' MHz'
+			logging.debug('cpu_mhz: ' + self.CpuMHz)
 		self.close()
 
 #-----------------------------------------------------------
@@ -2385,6 +2815,9 @@ class SSHConnection():
 #-----------------------------------------------------------
 	def CreateHtmlHeader(self):
 		if (not self.htmlHeaderCreated):
+			logging.debug('\u001B[1m----------------------------------------\u001B[0m')
+			logging.debug('\u001B[1m  Creating HTML header \u001B[0m')
+			logging.debug('\u001B[1m----------------------------------------\u001B[0m')
 			self.htmlFile = open('test_results.html', 'w')
 			self.htmlFile.write('<!DOCTYPE html>\n')
 			self.htmlFile.write('<html class="no-js" lang="en-US">\n')
@@ -2462,18 +2895,13 @@ class SSHConnection():
 				self.htmlFile.write('     </tr>\n')
 			self.htmlFile.write('  </table>\n')
 
-			terminate_ue_flag = True
 			if (self.ADBIPAddress != 'none'):
+				terminate_ue_flag = True
 				self.GetAllUEDevices(terminate_ue_flag)
 				self.GetAllCatMDevices(terminate_ue_flag)
-			else:
-				self.UEDevices.append('doughq9rehg')
-				self.UEDevices.append('dnsgiuahgia')
-				self.UEDevices.append('uehgieng9')
-			self.htmlUEConnected = len(self.UEDevices)
-
-			self.htmlFile.write('  <h2><span class="glyphicon glyphicon-phone"></span> <span class="glyphicon glyphicon-menu-right"></span> ' + str(len(self.UEDevices)) + ' UE(s) is(are) connected to ADB bench server</h2>\n')
-			self.htmlFile.write('  <h2><span class="glyphicon glyphicon-phone"></span> <span class="glyphicon glyphicon-menu-right"></span> ' + str(len(self.CatMDevices)) + ' CAT-M UE(s) is(are) connected to bench server</h2>\n')
+				self.htmlUEConnected = len(self.UEDevices)
+				self.htmlFile.write('  <h2><span class="glyphicon glyphicon-phone"></span> <span class="glyphicon glyphicon-menu-right"></span> ' + str(len(self.UEDevices)) + ' UE(s) is(are) connected to ADB bench server</h2>\n')
+				self.htmlFile.write('  <h2><span class="glyphicon glyphicon-phone"></span> <span class="glyphicon glyphicon-menu-right"></span> ' + str(len(self.CatMDevices)) + ' CAT-M UE(s) is(are) connected to bench server</h2>\n')
 			self.htmlFile.write('  <br>\n')
 			self.htmlFile.write('  <ul class="nav nav-pills">\n')
 			count = 0
@@ -2512,10 +2940,6 @@ class SSHConnection():
 				if (self.ADBIPAddress != 'none'):
 					self.GetAllUEDevices(terminate_ue_flag)
 					self.GetAllCatMDevices(terminate_ue_flag)
-				else:
-					self.UEDevices.append('doughq9rehg')
-					self.UEDevices.append('dnsgiuahgia')
-					self.UEDevices.append('uehgieng9')
 				self.htmlUEConnected = len(self.UEDevices)
 
 			i = 0
@@ -2540,6 +2964,9 @@ class SSHConnection():
 
 	def CreateHtmlFooter(self, passStatus):
 		if (os.path.isfile('test_results.html')):
+			logging.debug('\u001B[1m----------------------------------------\u001B[0m')
+			logging.debug('\u001B[1m  Creating HTML footer \u001B[0m')
+			logging.debug('\u001B[1m----------------------------------------\u001B[0m')
 			self.RetrieveSystemVersion()
 			self.htmlFile = open('test_results.html', 'a')
 			self.htmlFile.write('</div>\n')
@@ -2550,21 +2977,21 @@ class SSHConnection():
 			self.htmlFile.write('      </tr>\n')
 			self.htmlFile.write('      <tr>\n')
 			self.htmlFile.write('        <td>OS Version</td>\n')
-			self.htmlFile.write('        <td><span class="label label-default">' + self.eNBOsVersion + '</span></td>\n')
+			self.htmlFile.write('        <td><span class="label label-default">' + self.OsVersion + '</span></td>\n')
 			self.htmlFile.write('        <td>Kernel Version</td>\n')
-			self.htmlFile.write('        <td><span class="label label-default">' + self.eNBKernelVersion + '</span></td>\n')
+			self.htmlFile.write('        <td><span class="label label-default">' + self.KernelVersion + '</span></td>\n')
 			self.htmlFile.write('        <td>UHD Version</td>\n')
-			self.htmlFile.write('        <td><span class="label label-default">' + self.eNBUhdVersion + '</span></td>\n')
+			self.htmlFile.write('        <td><span class="label label-default">' + self.UhdVersion + '</span></td>\n')
 			self.htmlFile.write('        <td>USRP Board</td>\n')
-			self.htmlFile.write('        <td><span class="label label-default">' + self.eNBUsrpBoard + '</span></td>\n')
+			self.htmlFile.write('        <td><span class="label label-default">' + self.UsrpBoard + '</span></td>\n')
 			self.htmlFile.write('      </tr>\n')
 			self.htmlFile.write('      <tr>\n')
 			self.htmlFile.write('        <td>Nb CPUs</td>\n')
-			self.htmlFile.write('        <td><span class="label label-default">' + self.eNBCpuNb + '</span></td>\n')
+			self.htmlFile.write('        <td><span class="label label-default">' + self.CpuNb + '</span></td>\n')
 			self.htmlFile.write('        <td>CPU Model Name</td>\n')
-			self.htmlFile.write('        <td><span class="label label-default">' + self.eNBCpuModel + '</span></td>\n')
+			self.htmlFile.write('        <td><span class="label label-default">' + self.CpuModel + '</span></td>\n')
 			self.htmlFile.write('        <td>CPU Frequency</td>\n')
-			self.htmlFile.write('        <td><span class="label label-default">' + self.eNBCpuMHz + '</span></td>\n')
+			self.htmlFile.write('        <td><span class="label label-default">' + self.CpuMHz + '</span></td>\n')
 			self.htmlFile.write('        <td></td>\n')
 			self.htmlFile.write('        <td></td>\n')
 			self.htmlFile.write('      </tr>\n')
@@ -2582,7 +3009,7 @@ class SSHConnection():
 			self.htmlFile.write('</html>\n')
 			self.htmlFile.close()
 
-	def CreateHtmlTestRow(self, options, status, processesStatus):
+	def CreateHtmlTestRow(self, options, status, processesStatus, machine='eNB'):
 		if ((not self.htmlFooterCreated) and (self.htmlHeaderCreated)):
 			self.htmlFile.write('      <tr>\n')
 			self.htmlFile.write('        <td bgcolor = "lightcyan" >' + self.testCase_id  + '</td>\n')
@@ -2594,15 +3021,17 @@ class SSHConnection():
 				if (processesStatus == 0):
 					self.htmlFile.write('        <td bgcolor = "lightcoral" >' + str(status)  + '</td>\n')
 				elif (processesStatus == ENB_PROCESS_FAILED):
-					self.htmlFile.write('        <td bgcolor = "lightcoral" >KO - eNB process not found</td>\n')
+					self.htmlFile.write('        <td bgcolor = "lightcoral" >KO - ' + machine + ' process not found</td>\n')
 				elif (processesStatus == ENB_PROCESS_SEG_FAULT):
-					self.htmlFile.write('        <td bgcolor = "lightcoral" >KO - eNB process ended in Segmentation Fault</td>\n')
-				elif (processesStatus == ENB_PROCESS_ASSERTION):
-					self.htmlFile.write('        <td bgcolor = "lightcoral" >KO - eNB process ended in Assertion</td>\n')
+					self.htmlFile.write('        <td bgcolor = "lightcoral" >KO - ' + machine + ' process ended in Segmentation Fault</td>\n')
+				elif (processesStatus == ENB_PROCESS_ASSERTION) or (processesStatus == UE_PROCESS_ASSERTION):
+					self.htmlFile.write('        <td bgcolor = "lightcoral" >KO - ' + machine + ' process ended in Assertion</td>\n')
 				elif (processesStatus == ENB_PROCESS_REALTIME_ISSUE):
-					self.htmlFile.write('        <td bgcolor = "lightcoral" >KO - eNB process faced Real Time issue(s)</td>\n')
-				elif (processesStatus == ENB_PROCESS_NOLOGFILE_TO_ANALYZE):
-					self.htmlFile.write('        <td bgcolor = "orange" >OK</td>\n')
+					self.htmlFile.write('        <td bgcolor = "lightcoral" >KO - ' + machine + ' process faced Real Time issue(s)</td>\n')
+				elif (processesStatus == ENB_PROCESS_NOLOGFILE_TO_ANALYZE) or (processesStatus == UE_PROCESS_NOLOGFILE_TO_ANALYZE):
+					self.htmlFile.write('        <td bgcolor = "orange" >OK?</td>\n')
+				elif (processesStatus == UE_PROCESS_COULD_NOT_SYNC):
+					self.htmlFile.write('        <td bgcolor = "lightcoral" >KO - UE could not sync</td>\n')
 				elif (processesStatus == HSS_PROCESS_FAILED):
 					self.htmlFile.write('        <td bgcolor = "lightcoral" >KO - HSS process not found</td>\n')
 				elif (processesStatus == MME_PROCESS_FAILED):
@@ -2707,7 +3136,7 @@ def Usage():
 	print('------------------------------------------------------------')
 
 def CheckClassValidity(action,id):
-	if action != 'Build_eNB' and action != 'Initialize_eNB' and action != 'Terminate_eNB' and action != 'Initialize_UE' and action != 'Terminate_UE' and action != 'Attach_UE' and action != 'Detach_UE' and action != 'DataDisable_UE' and action != 'DataEnable_UE' and action != 'CheckStatusUE' and action != 'Ping' and action != 'Iperf' and action != 'Reboot_UE' and action != 'Initialize_FlexranCtrl' and action != 'Terminate_FlexranCtrl' and action != 'Initialize_HSS' and action != 'Terminate_HSS' and action != 'Initialize_MME' and action != 'Terminate_MME' and action != 'Initialize_SPGW' and action != 'Terminate_SPGW'  and action != 'Initialize_CatM_module' and action != 'Terminate_CatM_module' and action != 'Attach_CatM_module' and action != 'Detach_CatM_module' and action != 'Ping_CatM_module' and action != 'IdleSleep':
+	if action != 'Build_eNB' and action != 'Initialize_eNB' and action != 'Terminate_eNB' and action != 'Initialize_UE' and action != 'Terminate_UE' and action != 'Attach_UE' and action != 'Detach_UE' and action != 'Build_OAI_UE' and action != 'Initialize_OAI_UE' and action != 'Terminate_OAI_UE' and action != 'DataDisable_UE' and action != 'DataEnable_UE' and action != 'CheckStatusUE' and action != 'Ping' and action != 'Iperf' and action != 'Reboot_UE' and action != 'Initialize_FlexranCtrl' and action != 'Terminate_FlexranCtrl' and action != 'Initialize_HSS' and action != 'Terminate_HSS' and action != 'Initialize_MME' and action != 'Terminate_MME' and action != 'Initialize_SPGW' and action != 'Terminate_SPGW' and action != 'Initialize_CatM_module' and action != 'Terminate_CatM_module' and action != 'Attach_CatM_module' and action != 'Detach_CatM_module' and action != 'Ping_CatM_module' and action != 'IdleSleep':
 		logging.debug('ERROR: test-case ' + id + ' has wrong class ' + action)
 		return False
 	return True
@@ -2741,6 +3170,20 @@ def GetParametersFromXML(action):
 		else:
 			SSH.expectedNbOfConnectedUEs = int(expectedNBUE)
 
+	if action == 'Build_OAI_UE':
+		SSH.Build_OAI_UE_args = test.findtext('Build_OAI_UE_args')
+
+	if action == 'Initialize_OAI_UE':
+		SSH.Initialize_OAI_UE_args = test.findtext('Initialize_OAI_UE_args')
+		SSH.UE_instance = test.findtext('UE_instance')
+		if (SSH.UE_instance is None):
+			SSH.UE_instance = '0'
+
+	if action == 'Terminate_OAI_UE':
+		SSH.eNB_instance = test.findtext('UE_instance')
+		if (SSH.UE_instance is None):
+			SSH.UE_instance = '0'
+
 	if action == 'Ping' or action == 'Ping_CatM_module':
 		SSH.ping_args = test.findtext('ping_args')
 		SSH.ping_packetloss_threshold = test.findtext('ping_packetloss_threshold')
@@ -2783,6 +3226,7 @@ SSH = SSHConnection()
 
 argvs = sys.argv
 argc = len(argvs)
+cwd = os.getcwd()
 
 while len(argvs) > 1:
 	myArgv = argvs.pop(1)	# 0th is this file's name
@@ -2855,6 +3299,18 @@ while len(argvs) > 1:
 		matchReg = re.match('^\-\-XMLTestFile=(.+)$', myArgv, re.IGNORECASE)
 		SSH.testXMLfiles.append(matchReg.group(1))
 		SSH.nbTestXMLfiles += 1
+	elif re.match('^\-\-UEIPAddress=(.+)$', myArgv, re.IGNORECASE):
+		matchReg = re.match('^\-\-UEIPAddress=(.+)$', myArgv, re.IGNORECASE)
+		SSH.UEIPAddress = matchReg.group(1)
+	elif re.match('^\-\-UEUserName=(.+)$', myArgv, re.IGNORECASE):
+		matchReg = re.match('^\-\-UEUserName=(.+)$', myArgv, re.IGNORECASE)
+		SSH.UEUserName = matchReg.group(1)
+	elif re.match('^\-\-UEPassword=(.+)$', myArgv, re.IGNORECASE):
+		matchReg = re.match('^\-\-UEPassword=(.+)$', myArgv, re.IGNORECASE)
+		SSH.UEPassword = matchReg.group(1)
+	elif re.match('^\-\-UESourceCodePath=(.+)$', myArgv, re.IGNORECASE):
+		matchReg = re.match('^\-\-UESourceCodePath=(.+)$', myArgv, re.IGNORECASE)
+		SSH.UESourceCodePath = matchReg.group(1)
 	elif re.match('^\-\-finalStatus=(.+)$', myArgv, re.IGNORECASE):
 		matchReg = re.match('^\-\-finalStatus=(.+)$', myArgv, re.IGNORECASE)
 		finalStatus = matchReg.group(1)
@@ -2870,7 +3326,13 @@ if re.match('^TerminateeNB$', mode, re.IGNORECASE):
 		sys.exit('Insufficient Parameter')
 	SSH.TerminateeNB()
 elif re.match('^TerminateUE$', mode, re.IGNORECASE):
-	if SSH.ADBIPAddress == '' or SSH.ADBUserName == '' or SSH.ADBPassword == '':
+	if (SSH.ADBIPAddress == '' or SSH.ADBUserName == '' or SSH.ADBPassword == ''):
+		Usage()
+		sys.exit('Insufficient Parameter')
+	signal.signal(signal.SIGUSR1, receive_signal)
+	SSH.TerminateUE()
+elif re.match('^TerminateOAIUE$', mode, re.IGNORECASE):
+	if SSH.UEIPAddress == '' or SSH.UEUserName == '' or SSH.UEPassword == '':
 		Usage()
 		sys.exit('Insufficient Parameter')
 	signal.signal(signal.SIGUSR1, receive_signal)
@@ -2891,7 +3353,7 @@ elif re.match('^TerminateSPGW$', mode, re.IGNORECASE):
 		sys.exit('Insufficient Parameter')
 	SSH.TerminateSPGW()
 elif re.match('^LogCollectBuild$', mode, re.IGNORECASE):
-	if SSH.eNBIPAddress == '' or SSH.eNBUserName == '' or SSH.eNBPassword == '' or SSH.eNBSourceCodePath == '':
+	if (SSH.eNBIPAddress == '' or SSH.eNBUserName == '' or SSH.eNBPassword == '' or SSH.eNBSourceCodePath == '') and (SSH.UEIPAddress == '' or SSH.UEUserName == '' or SSH.UEPassword == '' or SSH.UESourceCodePath == ''):
 		Usage()
 		sys.exit('Insufficient Parameter')
 	SSH.LogCollectBuild()
@@ -2925,36 +3387,53 @@ elif re.match('^LogCollectIperf$', mode, re.IGNORECASE):
 		Usage()
 		sys.exit('Insufficient Parameter')
 	SSH.LogCollectIperf()
+elif re.match('^LogCollectOAIUE$', mode, re.IGNORECASE):
+        if SSH.UEIPAddress == '' or SSH.UEUserName == '' or SSH.UEPassword == '' or SSH.UESourceCodePath == '':
+                Usage()
+                sys.exit('Insufficient Parameter')
+        SSH.LogCollectOAIUE()
 elif re.match('^InitiateHtml$', mode, re.IGNORECASE):
-	if SSH.ADBIPAddress == '' or SSH.ADBUserName == '' or SSH.ADBPassword == '':
+	if (SSH.ADBIPAddress == '' or SSH.ADBUserName == '' or SSH.ADBPassword == ''):
 		Usage()
 		sys.exit('Insufficient Parameter')
 	count = 0
+	foundCount = 0
 	while (count < SSH.nbTestXMLfiles):
+		xml_test_file = cwd + "/" + SSH.testXMLfiles[count]
 		xml_test_file = sys.path[0] + "/" + SSH.testXMLfiles[count]
-		xmlTree = ET.parse(xml_test_file)
-		xmlRoot = xmlTree.getroot()
-		SSH.htmlTabRefs.append(xmlRoot.findtext('htmlTabRef',default='test-tab-' + str(count)))
-		SSH.htmlTabNames.append(xmlRoot.findtext('htmlTabName',default='Test-' + str(count)))
-		SSH.htmlTabIcons.append(xmlRoot.findtext('htmlTabIcon',default='info-sign'))
+		if (os.path.isfile(xml_test_file)):
+			xmlTree = ET.parse(xml_test_file)
+			xmlRoot = xmlTree.getroot()
+			SSH.htmlTabRefs.append(xmlRoot.findtext('htmlTabRef',default='test-tab-' + str(count)))
+			SSH.htmlTabNames.append(xmlRoot.findtext('htmlTabName',default='Test-' + str(count)))
+			SSH.htmlTabIcons.append(xmlRoot.findtext('htmlTabIcon',default='info-sign'))
+			foundCount += 1
 		count += 1
+	if foundCount != SSH.nbTestXMLfiles:
+		SSH.nbTestXMLfiles = foundCount
 	SSH.CreateHtmlHeader()
 elif re.match('^FinalizeHtml$', mode, re.IGNORECASE):
 	SSH.CreateHtmlFooter(SSH.finalStatus)
-elif re.match('^TesteNB$', mode, re.IGNORECASE):
-	if SSH.eNBIPAddress == '' or SSH.eNBRepository == '' or SSH.eNBBranch == '' or SSH.eNBUserName == '' or SSH.eNBPassword == '' or SSH.eNBSourceCodePath == '' or SSH.EPCIPAddress == '' or SSH.EPCUserName == '' or SSH.EPCPassword == '' or SSH.EPCType == '' or SSH.EPCSourceCodePath == '' or SSH.ADBIPAddress == '' or SSH.ADBUserName == '' or SSH.ADBPassword == '':
-		Usage()
-		sys.exit('Insufficient Parameter')
+elif re.match('^TesteNB$', mode, re.IGNORECASE) or re.match('^TestUE$', mode, re.IGNORECASE):
+	if re.match('^TesteNB$', mode, re.IGNORECASE):
+		if SSH.eNBIPAddress == '' or SSH.eNBRepository == '' or SSH.eNBBranch == '' or SSH.eNBUserName == '' or SSH.eNBPassword == '' or SSH.eNBSourceCodePath == '' or SSH.EPCIPAddress == '' or SSH.EPCUserName == '' or SSH.EPCPassword == '' or SSH.EPCType == '' or SSH.EPCSourceCodePath == '' or SSH.ADBIPAddress == '' or SSH.ADBUserName == '' or SSH.ADBPassword == '':
+			Usage()
+			sys.exit('Insufficient Parameter')
+
+		if (SSH.EPCIPAddress != ''):
+			SSH.copyout(SSH.EPCIPAddress, SSH.EPCUserName, SSH.EPCPassword, cwd + "/tcp_iperf_stats.awk", "/tmp")
+			SSH.copyout(SSH.EPCIPAddress, SSH.EPCUserName, SSH.EPCPassword, cwd + "/active_net_interfaces.awk", "/tmp")
+	else:
+		if SSH.UEIPAddress == '' or SSH.eNBRepository == '' or SSH.eNBBranch == '' or SSH.UEUserName == '' or SSH.UEPassword == '' or SSH.UESourceCodePath == '':
+			Usage()
+			sys.exit('UE: Insufficient Parameter')
 
-	if (SSH.EPCIPAddress != 'none'):
-		SSH.copyout(SSH.EPCIPAddress, SSH.EPCUserName, SSH.EPCPassword, sys.path[0] + "/tcp_iperf_stats.awk", "/tmp")
-		SSH.copyout(SSH.EPCIPAddress, SSH.EPCUserName, SSH.EPCPassword, sys.path[0] + "/active_net_interfaces.awk", "/tmp")
 	#read test_case_list.xml file
         # if no parameters for XML file, use default value
 	if (SSH.nbTestXMLfiles != 1):
-		xml_test_file = sys.path[0] + "/test_case_list.xml"
+		xml_test_file = cwd + "/test_case_list.xml"
 	else:
-		xml_test_file = sys.path[0] + "/" + SSH.testXMLfiles[0]
+		xml_test_file = cwd + "/" + SSH.testXMLfiles[0]
 
 	xmlTree = ET.parse(xml_test_file)
 	xmlRoot = xmlTree.getroot()
@@ -3038,6 +3517,12 @@ elif re.match('^TesteNB$', mode, re.IGNORECASE):
 				SSH.DataEnableUE()
 			elif action == 'CheckStatusUE':
 				SSH.CheckStatusUE()
+			elif action == 'Build_OAI_UE':
+				SSH.BuildOAIUE()
+			elif action == 'Initialize_OAI_UE':
+				SSH.InitializeOAIUE()
+			elif action == 'Terminate_OAI_UE':
+				SSH.TerminateOAIUE()
 			elif action == 'Initialize_CatM_module':
 				SSH.InitializeCatM()
 			elif action == 'Terminate_CatM_module':
diff --git a/ci-scripts/oai-ci-vm-tool b/ci-scripts/oai-ci-vm-tool
index 917b0e7491127ba26fdb3e106c4e45e16d46bd33..4a545e78c8cc859bdf275930964c9be91da0d5c3 100755
--- a/ci-scripts/oai-ci-vm-tool
+++ b/ci-scripts/oai-ci-vm-tool
@@ -264,7 +264,7 @@ case $key in
     ARCHIVES_LOC=cppcheck
     LOG_PATTERN=cppcheck.xml
     NB_PATTERN_FILES=1
-    BUILD_OPTIONS="--enable=warning --force --xml --xml-version=2 --suppressions-list=ci-scripts/cppcheck_suppressions.list"
+    BUILD_OPTIONS="--enable=warning --force --xml --xml-version=2 --suppressions-list=ci-scripts/cppcheck_suppressions.list -I common/utils -j4"
     NBARGS=$[$NBARGS+256]
     shift
     ;;
@@ -344,7 +344,7 @@ case $key in
         ARCHIVES_LOC=cppcheck
         LOG_PATTERN=cppcheck.xml
         NB_PATTERN_FILES=1
-        BUILD_OPTIONS="--enable=warning --force --xml --xml-version=2 --suppressions-list=ci-scripts/cppcheck_suppressions.list"
+        BUILD_OPTIONS="--enable=warning --force --xml --xml-version=2 --suppressions-list=ci-scripts/cppcheck_suppressions.list -I common/utils -j4"
         NBARGS=$[$NBARGS+256]
         ;;
         enb-ethernet)
diff --git a/ci-scripts/xml_files/enb_usrp210_band40_test_05mhz_tm1.xml b/ci-scripts/xml_files/enb_usrp210_band40_test_05mhz_tm1.xml
index 9cdd7523adc529608847b610b512078a26225096..d5a25c7fa7367f1791cf6657d4dfe6df2ca579aa 100644
--- a/ci-scripts/xml_files/enb_usrp210_band40_test_05mhz_tm1.xml
+++ b/ci-scripts/xml_files/enb_usrp210_band40_test_05mhz_tm1.xml
@@ -65,7 +65,7 @@
                 <class>Ping</class>
                 <desc>ping (5MHz - 20 sec)</desc>
                 <ping_args>-c 20</ping_args>
-                <ping_packetloss_threshold>50</ping_packetloss_threshold>
+                <ping_packetloss_threshold>25</ping_packetloss_threshold>
         </testCase>
 
         <testCase id="040601">
@@ -112,7 +112,7 @@
 		<class>Iperf</class>
 		<desc>iperf (5MHz - UL/2Mbps/UDP)(30 sec)(unbalanced)</desc>
 		<iperf_args>-u -b 2M -t 30 -i 1 -R</iperf_args>
-		<iperf_packetloss_threshold>80</iperf_packetloss_threshold>
+		<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
 		<iperf_profile>unbalanced</iperf_profile>
 	</testCase>
 
diff --git a/ci-scripts/xml_files/if4p5_usrp210_band40_test_05mhz.xml b/ci-scripts/xml_files/if4p5_usrp210_band40_test_05mhz.xml
index d3b456187629429c2945c7f5fb42e71914f30d31..5e7f4e48c8d9cdd93573407ca6192e67493b99be 100644
--- a/ci-scripts/xml_files/if4p5_usrp210_band40_test_05mhz.xml
+++ b/ci-scripts/xml_files/if4p5_usrp210_band40_test_05mhz.xml
@@ -81,7 +81,7 @@
                 <class>Ping</class>
                 <desc>ping (5MHz - 20 sec)</desc>
                 <ping_args>-c 20</ping_args>
-                <ping_packetloss_threshold>50</ping_packetloss_threshold>
+                <ping_packetloss_threshold>25</ping_packetloss_threshold>
         </testCase>
 
         <testCase id="040602">
diff --git a/ci-scripts/xml_files/if4p5_usrp210_band40_test_20mhz.xml b/ci-scripts/xml_files/if4p5_usrp210_band40_test_20mhz.xml
index 512c958105cd9da45c3e081c41bfadce25d3d183..cd732294ec03d55f0d49acea6d84627593e21d9a 100644
--- a/ci-scripts/xml_files/if4p5_usrp210_band40_test_20mhz.xml
+++ b/ci-scripts/xml_files/if4p5_usrp210_band40_test_20mhz.xml
@@ -37,7 +37,7 @@
 		<Initialize_eNB_args>-O ci-scripts/conf_files/rru.tdd.band40.conf</Initialize_eNB_args>
 		<eNB_instance>0</eNB_instance>
 	</testCase>
-	
+
 	<testCase id="030125">
 		<class>Initialize_eNB</class>
 		<desc>Initialize RCC (TDD/Band40/20MHz/info)</desc>
diff --git a/ci-scripts/xml_files/ue_band20_build.xml b/ci-scripts/xml_files/ue_band20_build.xml
new file mode 100644
index 0000000000000000000000000000000000000000..9ca1a2b2346509748444db85a4792054015cf246
--- /dev/null
+++ b/ci-scripts/xml_files/ue_band20_build.xml
@@ -0,0 +1,38 @@
+<!--
+
+ 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
+
+-->
+<testCaseList>
+	<htmlTabRef>build-tab</htmlTabRef>
+	<htmlTabName>Build</htmlTabName>
+	<htmlTabIcon>wrench</htmlTabIcon>
+	<TestCaseRequestedList>
+090101
+	</TestCaseRequestedList>
+	<TestCaseExclusionList></TestCaseExclusionList>
+
+	<testCase id="090101">
+		<class>Build_OAI_UE</class>
+		<desc>Build OAI UE</desc>
+		<Build_OAI_UE_args>-w USRP --UE</Build_OAI_UE_args>
+	</testCase>
+
+</testCaseList>
diff --git a/ci-scripts/xml_files/ue_band20_test_10mhz_orange.xml b/ci-scripts/xml_files/ue_band20_test_10mhz_orange.xml
new file mode 100644
index 0000000000000000000000000000000000000000..0e61e75d567b259f6c221182f0616d35ffa95f74
--- /dev/null
+++ b/ci-scripts/xml_files/ue_band20_test_10mhz_orange.xml
@@ -0,0 +1,49 @@
+<!--
+
+ 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
+
+-->
+<testCaseList>
+        <htmlTabRef>test-10mhz-orange</htmlTabRef>
+        <htmlTabName>Test-10Mhz-Orange</htmlTabName>
+        <htmlTabIcon>tasks</htmlTabIcon>	
+	<TestCaseRequestedList>
+090102 000001 090109
+	</TestCaseRequestedList>
+	<TestCaseExclusionList></TestCaseExclusionList>
+
+	<testCase id="090102">
+		<class>Initialize_OAI_UE</class>
+		<desc>Initialize OAI UE -- sniffing Orange frequency</desc>
+		<Initialize_OAI_UE_args>-C 816000000 -r 50 --ue-rxgain 120 --ue-scan-carrier --no-L2-connect</Initialize_OAI_UE_args>
+	</testCase>
+
+	<testCase id="000001">
+		<class>IdleSleep</class>
+		<desc>Sleep</desc>
+		<idle_sleep_time_in_sec>30</idle_sleep_time_in_sec>
+	</testCase>
+
+	<testCase id="090109">
+		<class>Terminate_OAI_UE</class>
+		<desc>Terminate OAI UE</desc>
+	</testCase>
+
+</testCaseList>
diff --git a/ci-scripts/xml_files/ue_band20_test_10mhz_sfr.xml b/ci-scripts/xml_files/ue_band20_test_10mhz_sfr.xml
new file mode 100644
index 0000000000000000000000000000000000000000..ae8aa0e668d829a3c92e44b8edfc763f77af8827
--- /dev/null
+++ b/ci-scripts/xml_files/ue_band20_test_10mhz_sfr.xml
@@ -0,0 +1,49 @@
+<!--
+
+ 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
+
+-->
+<testCaseList>
+        <htmlTabRef>test-10mHz-sfr</htmlTabRef>
+        <htmlTabName>Test-10MHz-SFR</htmlTabName>
+        <htmlTabIcon>tasks</htmlTabIcon>
+	<TestCaseRequestedList>
+090104 000001 090109
+	</TestCaseRequestedList>
+	<TestCaseExclusionList></TestCaseExclusionList>
+
+	<testCase id="090104">
+		<class>Initialize_OAI_UE</class>
+		<desc>Initialize OAI UE -- sniffing SFR frequency</desc>
+		<Initialize_OAI_UE_args>-C 806000000 -r 50 --ue-rxgain 120 --ue-scan-carrier --no-L2-connect</Initialize_OAI_UE_args>
+	</testCase>
+
+	<testCase id="000001">
+		<class>IdleSleep</class>
+		<desc>Sleep</desc>
+		<idle_sleep_time_in_sec>30</idle_sleep_time_in_sec>
+	</testCase>
+
+	<testCase id="090109">
+		<class>Terminate_OAI_UE</class>
+		<desc>Terminate OAI UE</desc>
+	</testCase>
+
+</testCaseList>
diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt
index 95fc2cc1506e0861ebf7f8120fd8c4e762455230..7bd7ee60c0b3491e0797bd36c1b16ad314242eaa 100644
--- a/cmake_targets/CMakeLists.txt
+++ b/cmake_targets/CMakeLists.txt
@@ -176,7 +176,6 @@ set(CMAKE_C_FLAGS
 set(CMAKE_CXX_FLAGS
 	"${CMAKE_CXX_FLAGS} ${C_FLAGS_PROCESSOR} -std=c++11 -D${MKVER}"
 )
-add_definitions("-DASN_DISABLE_OER_SUPPORT")
 
 
 #########################
@@ -228,7 +227,6 @@ add_definitions("-DPACKAGE_VERSION=\"Branch: ${GIT_BRANCH} Abrev. Hash: ${GIT_CO
 add_definitions("-DPACKAGE_BUGREPORT=\"openair4g-devel@lists.eurecom.fr\"")
 
 
-
 # Debug related options
 #########################################
 add_boolean_option(ASN_DEBUG           False "ASN1 coder/decoder Debug")
@@ -383,7 +381,7 @@ file(GLOB S1AP_source ${S1AP_C_DIR}/*.c)
 add_custom_target (
   s1ap_flag ALL
   ${OPENAIR_CMAKE}/tools/make_asn1c_includes.sh "${S1AP_C_DIR}" "${S1AP_ASN_DIR}/${S1AP_ASN_FILES}" "S1AP_" -fno-include-deps
-  DEPENDS  "${S1AP_ASN_DIR}/${S1AP_ASN_FILES}" 
+  DEPENDS  "${S1AP_ASN_DIR}/${S1AP_ASN_FILES}"
 )
 
 add_library(S1AP_LIB
@@ -475,6 +473,50 @@ add_library(X2AP_ENB
  )
 add_dependencies(X2AP_ENB rrc_flag x2_flag)
 
+# F1AP
+##############
+add_list1_option(F1AP_RELEASE R15 "F1AP ASN.1 grammar version" R15)
+set(F1AP_DIR ${OPENAIR2_DIR}/F1AP)
+if (${F1AP_RELEASE} STREQUAL "R15")
+  make_version(F1AP_VERSION 15 2 1)
+  set (ASN1RELDIR R15.2.1)
+endif(${F1AP_RELEASE} STREQUAL "R15")
+add_definitions(-DF1AP_VERSION=${F1AP_VERSION})
+set(F1AP_ASN_DIR ${F1AP_DIR}/MESSAGES/ASN1/${ASN1RELDIR})
+set(F1AP_ASN_FILES
+  ${F1AP_ASN_DIR}/F1AP-CommonDataTypes.asn
+  ${F1AP_ASN_DIR}/F1AP-Constants.asn
+  ${F1AP_ASN_DIR}/F1AP-PDU-Descriptions.asn
+  ${F1AP_ASN_DIR}/F1AP-PDU-Contents.asn
+  ${F1AP_ASN_DIR}/F1AP-IEs.asn
+  ${F1AP_ASN_DIR}/F1AP-Containers.asn
+  )
+
+set(F1AP_ASN_GENERATED_C_DIR ${asn1_generated_dir}/F1AP_${ASN1RELDIR})
+message("calling ASN1C_PREFIX=F1AP_ asn1c -gen-PER -fcompound-names -no-gen-example -findirect-choice -fno-include-deps -D ${F1AP_ASN_GENERATED_C_DIR} ${F1AP_ASN_FILES}")
+execute_process(COMMAND mkdir -p ${F1AP_ASN_GENERATED_C_DIR}
+                COMMAND env "ASN1C_PREFIX=F1AP_" asn1c -gen-PER -fcompound-names -no-gen-example -findirect-choice -fno-include-deps -D ${F1AP_ASN_GENERATED_C_DIR} ${F1AP_ASN_FILES}
+                RESULT_VARIABLE ret
+                OUTPUT_QUIET
+                ERROR_QUIET)
+
+if (NOT ${ret} STREQUAL 0)
+  message(FATAL_ERROR "asn1c: error")
+endif (NOT ${ret} STREQUAL 0)
+
+file(GLOB F1AP_ASN_GENERATED_C_FILES ${F1AP_ASN_GENERATED_C_DIR}/*.c)
+add_library(F1AP_LIB
+  ${F1AP_ASN_GENERATED_C_FILES}
+)
+
+include_directories ("${F1AP_ASN_GENERATED_C_DIR}")
+include_directories ("${F1AP_DIR}")
+
+file(GLOB F1AP_C_FILES ${F1AP_DIR}/*.c)
+add_library(F1AP
+  ${F1AP_C_FILES}
+)
+
 # Hardware dependant options
 ###################################
 add_list1_option(NB_ANTENNAS_RX "2" "Number of antennas in reception" "1" "2" "4")
@@ -622,7 +664,12 @@ add_boolean_option(PHY_TX_THREAD            False         "enable UE_EXPANSION w
 add_boolean_option(PRE_SCD_THREAD           False         "enable UE_EXPANSION with max 256 UE")
 add_boolean_option(UESIM_EXPANSION          False         "enable UESIM_EXPANSION with max 256 UE")
 
-########################
+#############################################################################
+# Flag for UE compilation to avoid issues in common eNB/UE PDCP/RLC functions
+#############################################################################
+
+add_boolean_option(UETARGET                 False         "set UE as target for compiler")
+
 # Include order
 ##########################
 add_boolean_option(ENB_MODE True "Swap the include directories between openair2 and openair3" )
@@ -748,6 +795,8 @@ include_directories("${NFAPI_DIR}/sim_common/inc")
 include_directories("${NFAPI_DIR}/pnf_sim/inc")
 include_directories("${OPENAIR1_DIR}")
 include_directories("${OPENAIR2_DIR}")
+include_directories("${OPENAIR3_DIR}/NAS/TOOLS")
+include_directories("${OPENAIR2_DIR}/ENB_APP")
 include_directories("${OPENAIR2_DIR}/LAYER2/RLC")
 include_directories("${OPENAIR2_DIR}/LAYER2/RLC/AM_v9.3.0")
 include_directories("${OPENAIR2_DIR}/LAYER2/RLC/UM_v9.3.0")
@@ -770,19 +819,21 @@ include_directories("${OPENAIR3_DIR}/SECU")
 include_directories("${OPENAIR3_DIR}/SCTP")
 include_directories("${OPENAIR3_DIR}/S1AP")
 include_directories("${OPENAIR2_DIR}/X2AP")
+include_directories("${OPENAIR2_DIR}/F1AP")
 include_directories("${OPENAIR3_DIR}/UDP")
 include_directories("${OPENAIR3_DIR}/GTPV1-U")
 include_directories("${OPENAIR_DIR}/targets/COMMON")
 include_directories("${OPENAIR_DIR}/targets/ARCH/COMMON")
 include_directories("${OPENAIR_DIR}/targets/ARCH/EXMIMO/USERSPACE/LIB/")
 include_directories("${OPENAIR_DIR}/targets/ARCH/EXMIMO/DEFS")
-include_directories("${OPENAIR2_DIR}/ENB_APP")
+include_directories("${OPENAIR2_DIR}/ENB_APP/CONTROL_MODULES/PHY")
 include_directories("${OPENAIR2_DIR}/ENB_APP/CONTROL_MODULES/MAC")
 include_directories("${OPENAIR2_DIR}/ENB_APP/CONTROL_MODULES/RRC")
 include_directories("${OPENAIR2_DIR}/ENB_APP/CONTROL_MODULES/PDCP")
 include_directories("${OPENAIR2_DIR}/UTIL/OSA")
 include_directories("${OPENAIR2_DIR}/UTIL/LFDS/liblfds6.1.1/liblfds611/inc")
 include_directories("${OPENAIR2_DIR}/UTIL/LFDS/liblfds7.0.0/liblfds700/inc")
+include_directories("${OPENAIR2_DIR}/LAYER2/PROTO_AGENT")
 include_directories("${OPENAIR2_DIR}/UTIL/MEM")
 include_directories("${OPENAIR2_DIR}/UTIL/LISTS")
 include_directories("${OPENAIR2_DIR}/UTIL/FIFO")
@@ -824,7 +875,7 @@ set(FLPT_MSG_FILES
   ${FLPT_MSG_DIR}/control_delegation.proto
   )
 
-set(FLPT_C_DIR ${protobuf_generated_dir}/${FLPTDIR})
+set(FLPT_C_DIR ${protobuf_generated_dir}/FLPT_${FLPTDIR})
 #message("calling protoc_call=${protoc_call} FLPT_C_DIR=${FLPT_C_DIR} FLPT_MSG_FILES=${FLPT_MSG_FILES}")
 execute_process(COMMAND ${protoc_call} ${FLPT_C_DIR} ${FLPT_MSG_DIR} ${FLPT_MSG_FILES})
 file(GLOB FLPT_source ${FLPT_C_DIR}/*.c)
@@ -867,6 +918,7 @@ add_library(FLEXRAN_AGENT
   ${OPENAIR2_DIR}/ENB_APP/flexran_agent_ran_api.c
   ${OPENAIR2_DIR}/ENB_APP/flexran_agent_timer.c
   ${OPENAIR2_DIR}/ENB_APP/flexran_agent_common_internal.c
+  ${OPENAIR2_DIR}/ENB_APP/CONTROL_MODULES/PHY/flexran_agent_phy.c
   ${OPENAIR2_DIR}/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c
   ${OPENAIR2_DIR}/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc.c
   ${OPENAIR2_DIR}/ENB_APP/CONTROL_MODULES/PDCP/flexran_agent_pdcp.c
@@ -892,6 +944,63 @@ MARK_AS_ADVANCED(LIBYAML_INCLUDE_DIR LIBYAML_LIBRARIES)
 
 #set(PROTOBUF_LIB "protobuf") #for Cpp
 
+# set the version of protobuf messages, V3 not supported yet
+add_list1_option(FSPT_VERSION V2 "FSPT MSG  protobuf  grammar version" V2 V3)
+
+if (${FSPT_VERSION} STREQUAL "V2")
+  set (FSPTDIR V2)
+elseif (${FSPT_VERSION} STREQUAL "V3")
+  set (FSPTDIR V3)
+endif(${FSPT_VERSION} STREQUAL "V2")
+
+set(FSPT_MSG_DIR ${OPENAIR_DIR}/targets/COMMON/MESSAGES/${FSPTDIR} )
+set(FSPT_MSG_FILES
+  ${FSPT_MSG_DIR}/flexsplit.proto
+  )
+
+set(FSPT_C_DIR ${protobuf_generated_dir}/FSPT_${FSPTDIR})
+message("calling protoc_call=${protoc_call} FSPT_C_DIR=${FSPT_C_DIR} FSPT_MSG_DIR=${FSPT_MSG_DIR} FSPT_MSG_FILES=${FSPT_MSG_FILES}")
+execute_process(COMMAND ${protoc_call} ${FSPT_C_DIR} ${FSPT_MSG_DIR} ${FSPT_MSG_FILES})
+file(GLOB FSPT_source ${FSPT_C_DIR}/*.c)
+set(FSPT_OAI_generated
+  ${FSPT_C_DIR}/flexsplit.pb-c.c
+  )
+
+file(GLOB fspt_h ${FSPT_C_DIR}/*.h)
+set(fspt_h ${fspt_h} )
+
+add_library(FSPT_MSG
+  ${FSPT_OAI_generated}
+  ${FSPT_source}
+  )
+set(FSPT_MSG_LIB FSPT_MSG)
+message("fspt c dir is : ${FSPT_C_DIR}")
+include_directories (${FSPT_C_DIR})
+
+#  add_library(ASYNC_IF
+#    ${OPENAIR2_DIR}/UTIL/ASYNC_IF/socket_link.c
+#    ${OPENAIR2_DIR}/UTIL/ASYNC_IF/link_manager.c
+#    ${OPENAIR2_DIR}/UTIL/ASYNC_IF/message_queue.c
+#    ${OPENAIR2_DIR}/UTIL/ASYNC_IF/ringbuffer_queue.c
+#    )
+#  set(ASYNC_IF_LIB ASYNC_IF)
+#  include_directories(${OPENAIR2_DIR}/UTIL/ASYNC_IF)
+
+add_library(PROTO_AGENT
+  ${OPENAIR2_DIR}/LAYER2/PROTO_AGENT/proto_agent_handler.c
+  ${OPENAIR2_DIR}/LAYER2/PROTO_AGENT/proto_agent_common.c
+  ${OPENAIR2_DIR}/LAYER2/PROTO_AGENT/proto_agent.c
+  ${OPENAIR2_DIR}/LAYER2/PROTO_AGENT/proto_agent_net_comm.c
+  ${OPENAIR2_DIR}/LAYER2/PROTO_AGENT/proto_agent_async.c
+  )
+set(PROTO_AGENT_LIB PROTO_AGENT)
+include_directories(${OPENAIR2_DIR}/LAYER2/PROTO_AGENT)
+
+
+
+set(PROTOBUF_LIB "protobuf-c")
+
+#set(PROTOBUF_LIB "protobuf") #for Cpp
 
 add_library(HASHTABLE
   ${OPENAIR_DIR}/common/utils/hashtable/hashtable.c
@@ -914,7 +1023,7 @@ set(UTIL_SRC
   ${OPENAIR_DIR}/common/utils/LOG/log.c
 #  ${OPENAIR2_DIR}/UTIL/LOG/vcd_signal_dumper.c
   ${OPENAIR2_DIR}/UTIL/MATH/oml.c
-  ${OPENAIR2_DIR}/UTIL/MEM/mem_block.c
+  #${OPENAIR2_DIR}/UTIL/MEM/mem_block.c
 #  ${OPENAIR2_DIR}/UTIL/OCG/OCG.c
 #  ${OPENAIR2_DIR}/UTIL/OCG/OCG_create_dir.c
 #  ${OPENAIR2_DIR}/UTIL/OCG/OCG_detect_file.c
@@ -1974,11 +2083,39 @@ add_dependencies(lte-softmodem rrc_flag s1ap_flag x2_flag)
 
 target_link_libraries (lte-softmodem
   -Wl,--start-group
-  RRC_LIB S1AP_LIB S1AP_ENB X2AP_LIB X2AP_ENB GTPV1U SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT UDP SCHED_LIB SCHED_RU_LIB PHY_COMMON PHY PHY_RU LFDS L2
-  ${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} ${FLEXRAN_AGENT_LIB} LFDS7
+  RRC_LIB S1AP_LIB S1AP_ENB F1AP_LIB F1AP X2AP_LIB X2AP_ENB GTPV1U SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT UDP SCHED_LIB SCHED_RU_LIB PHY_COMMON PHY PHY_RU LFDS L2
+  ${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} ${FLEXRAN_AGENT_LIB} ${FSPT_MSG_LIB} ${PROTO_AGENT_LIB} LFDS7
   NFAPI_COMMON_LIB NFAPI_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB NFAPI_USER_LIB
   -Wl,--end-group z dl)
 
+add_executable(cu_test
+  ${OPENAIR2_DIR}/LAYER2/PROTO_AGENT/cu_test.c
+  ${OPENAIR2_DIR}/LAYER2/PROTO_AGENT/proto_agent_handler.c
+  ${OPENAIR2_DIR}/LAYER2/PROTO_AGENT/proto_agent_common.c
+  ${OPENAIR2_DIR}/LAYER2/PROTO_AGENT/proto_agent.c
+  ${OPENAIR2_DIR}/LAYER2/PROTO_AGENT/proto_agent_net_comm.c
+  ${OPENAIR2_DIR}/LAYER2/PROTO_AGENT/proto_agent_async.c
+  ${T_SOURCE}
+)
+target_link_libraries(cu_test
+  ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} ${FSPT_MSG_LIB} ${PROTOBUF_LIB}
+  ${PROTO_AGENT_LIB} pthread UTIL ${T_LIB} dl ${ITTI_LIB}
+)
+
+add_executable(du_test
+  ${OPENAIR2_DIR}/LAYER2/PROTO_AGENT/du_test.c
+  ${OPENAIR2_DIR}/LAYER2/PROTO_AGENT/proto_agent_handler.c
+  ${OPENAIR2_DIR}/LAYER2/PROTO_AGENT/proto_agent_common.c
+  ${OPENAIR2_DIR}/LAYER2/PROTO_AGENT/proto_agent.c
+  ${OPENAIR2_DIR}/LAYER2/PROTO_AGENT/proto_agent_net_comm.c
+  ${OPENAIR2_DIR}/LAYER2/PROTO_AGENT/proto_agent_async.c
+  ${T_SOURCE}
+)
+target_link_libraries(du_test
+  ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} ${FSPT_MSG_LIB} ${PROTOBUF_LIB}
+  ${PROTO_AGENT_LIB} pthread UTIL ${T_LIB} dl ${ITTI_LIB}
+)
+
 target_link_libraries (lte-softmodem ${LIBXML2_LIBRARIES})
 target_link_libraries (lte-softmodem pthread m ${CONFIG_LIBRARIES} rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${NETTLE_LIBRARIES} sctp  ${XFORMS_LIBRARIES} ${PROTOBUF_LIB}  ${CMAKE_DL_LIBS} ${LIBYAML_LIBRARIES})
 target_link_libraries (lte-softmodem ${LIB_LMS_LIBRARIES})
@@ -2015,14 +2152,14 @@ add_dependencies(lte-softmodem-nos1 rrc_flag s1ap_flag x2_flag)
 
 target_link_libraries (lte-softmodem-nos1
   -Wl,--start-group
-  RRC_LIB S1AP_LIB S1AP_ENB X2AP_LIB X2AP_ENB GTPV1U SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT UDP SCHED_LIB SCHED_RU_LIB PHY_COMMON PHY PHY_RU LFDS L2
-  ${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} ${FLEXRAN_AGENT_LIB} LFDS7
+  RRC_LIB F1AP F1AP_LIB S1AP_LIB S1AP_ENB X2AP_LIB X2AP_ENB GTPV1U SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT UDP SCHED_LIB SCHED_RU_LIB PHY_COMMON PHY PHY_RU LFDS L2
+  ${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} ${FLEXRAN_AGENT_LIB} ${FSPT_MSG_LIB} ${PROTO_AGENT_LIB} LFDS7
   NFAPI_COMMON_LIB NFAPI_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB NFAPI_USER_LIB
   -Wl,--end-group z dl)
 
 target_link_libraries (lte-softmodem-nos1 ${LIBXML2_LIBRARIES})
-target_link_libraries (lte-softmodem-nos1 pthread m ${CONFIG_LIBRARIES} rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${NETTLE_LIBRARIES} sctp  ${XFORMS_LIBRARIES} ${PROTOBUF_LIB}  ${CMAKE_DL_LIBS} ${LIBYAML_LIBRARIES})
-target_link_libraries (lte-softmodem-nos1 ${LIB_LMS_LIBRARIES})
+target_link_libraries (lte-softmodem-nos1 pthread m ${CONFIG_LIBRARIES} rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${NETTLE_LIBRARIES} sctp ${XFORMS_LIBRARIES} ${PROTOBUF_LIB} ${CMAKE_DL_LIBS} ${LIBYAML_LIBRARIES})
+target_link_libraries (lte-softmodem-nos1  ${LIB_LMS_LIBRARIES})
 target_link_libraries (lte-softmodem-nos1 ${T_LIB})
 # lte-uesoftmodem is  UE implementation
 #######################################
@@ -2055,7 +2192,7 @@ add_executable(lte-uesoftmodem
 add_dependencies(lte-uesoftmodem rrc_flag s1ap_flag x2_flag)
 target_link_libraries (lte-uesoftmodem
   -Wl,--start-group
-  RRC_LIB S1AP_LIB S1AP_ENB X2AP_LIB X2AP_ENB GTPV1U SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT UDP SCHED_RU_LIB SCHED_UE_LIB PHY_COMMON PHY_UE PHY_RU LFDS L2_UE SIMU
+  RRC_LIB S1AP_LIB S1AP_ENB X2AP_LIB X2AP_ENB F1AP F1AP_LIB GTPV1U SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT UDP SCHED_RU_LIB SCHED_UE_LIB PHY_COMMON PHY_UE PHY_RU LFDS L2_UE SIMU
   ${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} LFDS7 ${ATLAS_LIBRARIES}
   NFAPI_COMMON_LIB NFAPI_LIB NFAPI_PNF_LIB NFAPI_USER_LIB
   -Wl,--end-group z dl)
@@ -2096,14 +2233,14 @@ add_dependencies(lte-uesoftmodem-nos1 rrc_flag s1ap_flag x2_flag)
 
 target_link_libraries (lte-uesoftmodem-nos1
   -Wl,--start-group
-  RRC_LIB S1AP_LIB S1AP_ENB X2AP_LIB X2AP_ENB GTPV1U SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT UDP SCHED_RU_LIB SCHED_UE_LIB PHY_COMMON PHY_UE PHY_RU LFDS L2_UE SIMU
+  RRC_LIB S1AP_LIB S1AP_ENB X2AP_LIB X2AP_ENB F1AP F1AP_LIB GTPV1U SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT UDP SCHED_RU_LIB SCHED_UE_LIB PHY_COMMON PHY_UE PHY_RU LFDS L2_UE SIMU
   ${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} LFDS7 ${ATLAS_LIBRARIES}
   NFAPI_COMMON_LIB NFAPI_LIB NFAPI_PNF_LIB NFAPI_USER_LIB
   -Wl,--end-group z dl)
 
 target_link_libraries (lte-uesoftmodem-nos1 ${LIBXML2_LIBRARIES})
-target_link_libraries (lte-uesoftmodem-nos1 pthread m ${CONFIG_LIBRARIES} rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${NETTLE_LIBRARIES} sctp  ${XFORMS_LIBRARIES} ${PROTOBUF_LIB}  ${CMAKE_DL_LIBS} ${LIBYAML_LIBRARIES} ${ATLAS_LIBRARIES})
-target_link_libraries (lte-uesoftmodem-nos1 ${LIB_LMS_LIBRARIES})
+target_link_libraries (lte-uesoftmodem-nos1 pthread m ${CONFIG_LIBRARIES} rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${NETTLE_LIBRARIES} sctp  ${XFORMS_LIBRARIES} ${PROTOBUF_LIB} ${CMAKE_DL_LIBS} ${LIBYAML_LIBRARIES} ${ATLAS_LIBRARIES})
+target_link_libraries (lte-uesoftmodem-nos1  ${LIB_LMS_LIBRARIES})
 target_link_libraries (lte-uesoftmodem-nos1 ${T_LIB})
 # USIM process
 #################
@@ -2159,7 +2296,7 @@ foreach(myExe dlsim dlsim_tm7 ulsim pbchsim scansim mbmssim pdcchsim pucchsim pr
   target_link_libraries (${myExe}
 
     -Wl,--start-group SIMU UTIL SCHED_LIB SCHED_RU_LIB SCHED_UE_LIB PHY_COMMON PHY PHY_UE PHY_RU LFDS ${ITTI_LIB} LFDS7 -Wl,--end-group
-    pthread m rt ${CONFIG_LIBRARIES} ${ATLAS_LIBRARIES} ${XFORMS_LIBRARIES} ${T_LIB} dl 
+    pthread m rt ${CONFIG_LIBRARIES} ${ATLAS_LIBRARIES} ${XFORMS_LIBRARIES} ${T_LIB} dl
     )
 endforeach(myExe)
 
@@ -2172,7 +2309,7 @@ add_executable(test_epc_generate_scenario
   ${OPENAIR3_DIR}/S1AP/s1ap_eNB_defs.h
   )
 target_link_libraries (test_epc_generate_scenario
-  -Wl,--start-group RRC_LIB S1AP_LIB S1AP_ENB X2AP_LIB X2AP_ENB GTPV1U LIB_NAS_UE SECU_CN UTIL HASHTABLE SCTP_CLIENT UDP SCHED_LIB PHY LFDS ${ITTI_LIB} L2 -Wl,--end-group pthread m rt crypt sctp ${LIBXML2_LIBRARIES} ${LIBXSLT_LIBRARIES} ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${NETTLE_LIBRARIES} ${CONFIG_LIBRARIES}
+  -Wl,--start-group RRC_LIB S1AP_LIB S1AP_ENB X2AP_LIB X2AP_ENB F1AP_LIB F1AP GTPV1U LIB_NAS_UE SECU_CN UTIL HASHTABLE SCTP_CLIENT UDP SCHED_LIB PHY LFDS ${ITTI_LIB} ${MSC_LIB} L2 -Wl,--end-group pthread m rt crypt sctp ${LIBXML2_LIBRARIES} ${LIBXSLT_LIBRARIES} ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${NETTLE_LIBRARIES} ${CONFIG_LIBRARIES}
   )
 
 add_executable(test_epc_play_scenario
@@ -2191,7 +2328,7 @@ add_executable(test_epc_play_scenario
   )
 target_include_directories(test_epc_play_scenario PUBLIC /usr/local/share/asn1c)
 target_link_libraries (test_epc_play_scenario
-  -Wl,--start-group RRC_LIB S1AP_LIB X2AP_LIB X2AP_ENB GTPV1U LIB_NAS_UE SECU_CN UTIL HASHTABLE SCTP_CLIENT UDP SCHED_LIB PHY_COMMON PHY PHY_UE LFDS ${ITTI_LIB} ${MSC_LIB} -Wl,--end-group pthread m rt crypt sctp ${LIBXML2_LIBRARIES} ${LIBXSLT_LIBRARIES} ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${NETTLE_LIBRARIES} ${CONFIG_LIBRARIES}
+  -Wl,--start-group RRC_LIB S1AP_LIB X2AP_LIB X2AP_ENB F1AP_LIB F1AP GTPV1U LIB_NAS_UE SECU_CN UTIL HASHTABLE SCTP_CLIENT UDP SCHED_LIB PHY_COMMON PHY PHY_UE LFDS ${ITTI_LIB} ${MSC_LIB} -Wl,--end-group pthread m rt crypt sctp ${LIBXML2_LIBRARIES} ${LIBXSLT_LIBRARIES} ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${NETTLE_LIBRARIES} ${CONFIG_LIBRARIES}
   )
 
 
@@ -2225,15 +2362,15 @@ if (${T_TRACER})
         #all "add_executable" definitions (except tests, rb_tool, updatefw)
         lte-softmodem lte-softmodem-nos1 lte-uesoftmodem lte-uesoftmodem-nos1
         dlsim_tm4 dlsim dlsim_tm7 ulsim pbchsim scansim mbmssim
-        pdcchsim pucchsim prachsim syncsim ulsim
+        pdcchsim pucchsim prachsim syncsim ulsim cu_test du_test
         #all "add_library" definitions
-        ITTI RRC_LIB S1AP_LIB S1AP_ENB X2AP_LIB X2AP_ENB
+        ITTI RRC_LIB S1AP_LIB S1AP_ENB X2AP_LIB X2AP_ENB F1AP_LIB F1AP
         oai_exmimodevif oai_usrpdevif oai_bladerfdevif oai_lmssdrdevif
         oai_eth_transpro
         FLPT_MSG ASYNC_IF FLEXRAN_AGENT HASHTABLE MSC UTIL OMG_SUMO SECU_OSA
-        SECU_CN SCHED_LIB PHY L2 default_sched remote_sched RAL CN_UTILS
-        GTPV1U SCTP_CLIENT UDP LIB_NAS_UE LFDS LFDS7 SIMU OPENAIR0_LIB PHY_MEX
-        coding)
+        SECU_CN SCHED_LIB SCHED_RU_LIB SCHED_UE_LIB PHY L2 default_sched
+        remote_sched RAL CN_UTILS GTPV1U SCTP_CLIENT UDP LIB_NAS_UE LFDS
+        LFDS7 SIMU OPENAIR0_LIB PHY_MEX coding)
     if (TARGET ${i})
       add_dependencies(${i} generate_T)
     endif()
diff --git a/cmake_targets/autotests/test_case_list.xml b/cmake_targets/autotests/test_case_list.xml
index fc4567269e51fd2b3f3c1f90a7b9fc2815ba2b8d..bf3d57af0dbbec3c3ce877662e813c21132f2fa0 100644
--- a/cmake_targets/autotests/test_case_list.xml
+++ b/cmake_targets/autotests/test_case_list.xml
@@ -990,11 +990,11 @@
       <pre_exec>$OPENAIR_DIR/cmake_targets/autotests/tools/free_mem.bash</pre_exec>
       <pre_exec_args></pre_exec_args>
       <main_exec> $OPENAIR_DIR/targets/bin/ulsim.Rel14</main_exec>
-      <main_exec_args> -BnbRBs=25 -mcs=5 -yN_rx=1 -gchannel=N -xTransmission=1 -snr=6 -wsnrInterrupt=1.0 -e_snr_step=.1 -P -nb_frame=500 -Operf=70 
-                       -BnbRBs=25 -mcs=16 -yN_rx=1 -gchannel=N -xTransmission=1 -snr=12 -wsnrInterrupt=1.0 -e_snr_step=.1 -P -nb_frame=500 -Operf=70 
-                        -BnbRBs=50 -mcs=5 -yN_rx=1 -gchannel=N -xTransmission=1 -snr=6 -wsnrInterrupt=1.0 -e_snr_step=.1 -P -nb_frame=500 -Operf=70  
-                       -BnbRBs=50 -mcs=16 -yN_rx=1 -gchannel=N -xTransmission=1 -snr=12 -wsnrInterrupt=1.0 -e_snr_step=.1 -P -nb_frame=500 -Operf=70 
-                        -BnbRBs=100 -mcs=5 -yN_rx=1 -gchannel=N -xTransmission=1 -snr=6 -wsnrInterrupt=1.0 -e_snr_step=.1 -P -nb_frame=500 -Operf=70 
+      <main_exec_args> -BnbRBs=25 -mcs=5 -yN_rx=1 -gchannel=N -xTransmission=1 -snr=6 -wsnrInterrupt=1.0 -e_snr_step=.1 -P -nb_frame=500 -Operf=70
+                       -BnbRBs=25 -mcs=16 -yN_rx=1 -gchannel=N -xTransmission=1 -snr=12 -wsnrInterrupt=1.0 -e_snr_step=.1 -P -nb_frame=500 -Operf=70
+                        -BnbRBs=50 -mcs=5 -yN_rx=1 -gchannel=N -xTransmission=1 -snr=6 -wsnrInterrupt=1.0 -e_snr_step=.1 -P -nb_frame=500 -Operf=70
+                       -BnbRBs=50 -mcs=16 -yN_rx=1 -gchannel=N -xTransmission=1 -snr=12 -wsnrInterrupt=1.0 -e_snr_step=.1 -P -nb_frame=500 -Operf=70
+                        -BnbRBs=100 -mcs=5 -yN_rx=1 -gchannel=N -xTransmission=1 -snr=6 -wsnrInterrupt=1.0 -e_snr_step=.1 -P -nb_frame=500 -Operf=70
                        -BnbRBs=100 -mcs=16 -yN_rx=1 -gchannel=N -xTransmission=1 -snr=12 -wsnrInterrupt=1.0 -e_snr_step=.1 -P -nb_frame=500 -Operf=70 </main_exec_args>
      <tags>ulsim.test1 ulsim.test2 ulsim.test3 ulsim.test4 ulsim.test5 ulsim.test6</tags>
       <search_expr_true>"passed"</search_expr_true>
diff --git a/cmake_targets/build_oai b/cmake_targets/build_oai
index e77dbab0497ac39f9c403bb0d014e7053b71ab9b..887b3ebe2fe285638d54df572eeb397d7de902ad 100755
--- a/cmake_targets/build_oai
+++ b/cmake_targets/build_oai
@@ -70,6 +70,7 @@ DISABLE_LOG_X="False"
 USRP_REC_PLAY="False"
 BUILD_ECLIPSE=0
 UE_NAS_USE_TUN="False"
+UETARGET="False"
 BASIC_SIMULATOR=0
 trap handle_ctrl_c INT
 
@@ -103,6 +104,8 @@ Options
    Specify conf_nvram_path (default \"$conf_nvram_path\")
 --UE-gen-nvram [output path]
    Specify gen_nvram_path (default \"$gen_nvram_path\")
+-a | --agent
+   Enables agent for software-defined control of the eNB
 -r | --3gpp-release
    default is Rel14,
    Rel8 limits the implementation to 3GPP Release 8 version
@@ -216,6 +219,7 @@ function main() {
 	    shift;;
        --UE)
             UE=1
+            UETARGET="True"
             echo_info "Will compile UE"
             shift;;
        --mu)
@@ -237,7 +241,7 @@ function main() {
             echo_info "Setting release to: $REL"
             shift 2;;
        -w | --hardware)
-                # Use OAI_USRP  as the key word USRP is used inside UHD driver
+            # Use OAI_USRP  as the key word USRP is used inside UHD driver           
                 case "$2" in
                     "EXMIMO")
                         HW="EXMIMO"
@@ -251,7 +255,7 @@ function main() {
                     *)
                         echo_fatal "Unknown HW type $HW: exit..."
                 esac
-	echo_info "Setting hardware to: $HW"
+		echo_info "Setting hardware to: $HW"
             shift 2;;
 	-t | --transport_protocol)
             TP="$2" #"${i#*=}"
@@ -389,35 +393,35 @@ function main() {
   
   CMAKE_CMD="$CMAKE_CMD .."
   echo_info "CMAKE_CMD=$CMAKE_CMD"
-    #########################################################
-    # check validity of HW and TP parameters for eNB
-    #########################################################
-    # to be discussed
-    
-    if [ "$eNB" = "1" ] ; then
-	if [ "$HW" = "None" -a  "$TP" = "None" ] ; then
-            echo_fatal "Define a local radio head (e.g. -w EXMIMO) or a transport protocol (e.g. -t ETHERNET) to communicate with a remote radio head!"
-	fi
-	if [ "$HW" = "None" ] ; then 
-            echo_info "No radio head has been selected (HW set to $HW)"   
-	fi
-	if [ "$TP" = "None" ] ; then
-            echo_info "No transport protocol has been selected (TP set to $TP)"   
-	fi
-    fi
-    
-    echo_info "RF HW set to $HW" 
+  #########################################################
+  # check validity of HW and TP parameters for eNB
+  #########################################################
+  # to be discussed
+  
+  if [ "$eNB" = "1" ] ; then
+      if [ "$HW" = "None" -a  "$TP" = "None" ] ; then
+	  echo_fatal "Define a local radio head (e.g. -w EXMIMO) or a transport protocol (e.g. -t ETHERNET) to communicate with a remote radio head!"
+      fi
+      if [ "$HW" = "None" ] ; then 
+	  echo_info "No radio head has been selected (HW set to $HW)"	
+      fi
+      if [ "$TP" = "None" ] ; then
+	  echo_info "No transport protocol has been selected (TP set to $TP)"	
+      fi
+  fi
+  
+  echo_info "RF HW set to $HW" 
     # If the user doesn't specify the Linux scheduler to use, we set a value
     if [ "$DEADLINE_SCHEDULER_FLAG_USER" = "" ]; then
       case "$HW" in
  	  "EXMIMO")
-               DEADLINE_SCHEDULER_FLAG_USER="True"
+        DEADLINE_SCHEDULER_FLAG_USER="True"
               ;;
  	  *)
-              DEADLINE_SCHEDULER_FLAG_USER="False"
+        DEADLINE_SCHEDULER_FLAG_USER="False"
               ;;
       esac
-    fi
+  fi
   #Disable CPU Affinity for deadline scheduler
   if [ "$DEADLINE_SCHEDULER_FLAG_USER" = "True" ] ; then 
      CPU_AFFINITY_FLAG_USER="False"
@@ -497,18 +501,18 @@ function main() {
   
   echo_info "3. building the compilation directives ..."
 
-    DIR=$OPENAIR_DIR/cmake_targets
+  DIR=$OPENAIR_DIR/cmake_targets
     
     if [ "$T_TRACER" =  "False" ] ; then
         noLOGDirsuffix="_noLOG"
-    fi
+      fi
     if [ "$NOS1" =  "1" ] ; then
         noS1Dir="_noS1"
         bin_suffix="-nos1"
-    else
-        lte_build_dir=lte_build_oai
+  else
+      lte_build_dir=lte_build_oai
         bin_suffix=""
-    fi
+  fi
 
     lte_build_dir="lte${noS1Dir}_build_oai${noLOGDirsuffix}"
 # configuration module libraries, one currently available, using libconfig 
@@ -545,6 +549,9 @@ function main() {
     echo "set (UE_TIMING_TRACE $UE_TIMING_TRACE)"        >>  $cmake_file
     echo "set (DISABLE_LOG_X $DISABLE_LOG_X)"        >>  $cmake_file
     echo "set (USRP_REC_PLAY $USRP_REC_PLAY)"        >>  $cmake_file
+    if [ "$UE" = 1 ] ; then
+       echo "set (UETARGET $UETARGET )"                   >> $cmake_file
+    fi
     if [ "$UE" = 1 -a "$NOS1" = "0" ] ; then
      echo_info "Compiling UE S1 build : enabling Linux and NETLINK"
      echo "set (LINUX True )"              >>  $cmake_file
@@ -707,81 +714,81 @@ function main() {
     cp $OPENAIR_DIR/cmake_targets/tools/init_exmimo2 $dbin
   fi
 
-    # Telnet server compilation
-    #####################
-    if [ "$BUILD_TELNETSRV" = "1" ] ; then
-        compilations \
+  # Telnet server compilation
+  #####################
+  if [ "$BUILD_TELNETSRV" = "1" ] ; then
+              compilations \
             $lte_build_dir telnetsrv \
-            libtelnetsrv.so $dbin/libtelnetsrv.so
-        
-    fi
+                  libtelnetsrv.so $dbin/libtelnetsrv.so
+
+  fi 
     # msc library compilation
-    #####################
-    if [ "$MSC_GEN" = "1" ] ; then
-        compilations \
+  #####################
+  if [ "$MSC_GEN" = "1" ] ; then
+              compilations \
             $lte_build_dir msc \
-            libmsc.so $dbin/libmsc.so
-        
-    fi
-    # build RF device and transport protocol libraries
-    #####################################
-    if [ "$eNB" = "1" -o "$UE" = "1" ] ; then
-        
-        # build RF device libraries
-        if [ "$HW" != "None" ] ; then
-            rm -f liboai_device.so
-            rm -f $dbin/liboai_device.so
-            
-            # link liboai_device.so with the selected RF device library
-            if [ "$HW" == "EXMIMO" ] ; then
-                compilations \
+                  libmsc.so $dbin/libmsc.so
+
+  fi  
+  # build RF device and transport protocol libraries
+  #####################################
+  if [ "$eNB" = "1" -o "$UE" = "1" ] ; then
+
+      # build RF device libraries
+      if [ "$HW" != "None" ] ; then
+	  rm -f liboai_device.so
+	  rm -f $dbin/liboai_device.so
+
+	  # link liboai_device.so with the selected RF device library
+	  if [ "$HW" == "EXMIMO" ] ; then
+	      compilations \
                     $lte_build_dir oai_exmimodevif \
-                    liboai_exmimodevif.so $dbin/liboai_exmimodevif.so.$REL
-                
-                ln -sf liboai_exmimodevif.so liboai_device.so
-                ln -sf $dbin/liboai_exmimodevif.so.$REL $dbin/liboai_device.so
-                echo_info "liboai_device.so is linked to EXMIMO device library"
-            elif [ "$HW" == "OAI_USRP" ] ; then
-                compilations \
+		  liboai_exmimodevif.so $dbin/liboai_exmimodevif.so.$REL
+
+	      ln -sf liboai_exmimodevif.so liboai_device.so
+	      ln -sf $dbin/liboai_exmimodevif.so.$REL $dbin/liboai_device.so
+	      echo_info "liboai_device.so is linked to EXMIMO device library"       
+	  elif [ "$HW" == "OAI_USRP" ] ; then
+              compilations \
                     $lte_build_dir oai_usrpdevif \
-                    liboai_usrpdevif.so $dbin/liboai_usrpdevif.so.$REL
-                
-                ln -sf liboai_usrpdevif.so liboai_device.so
-                ln -sf $dbin/liboai_usrpdevif.so.$REL $dbin/liboai_device.so
-                echo_info "liboai_device.so is linked to USRP device library"
-            elif [ "$HW" == "OAI_BLADERF" ] ; then
-                if [ -f "/usr/include/libbladeRF.h" ] ; then
-                    compilations \
+                  liboai_usrpdevif.so $dbin/liboai_usrpdevif.so.$REL
+
+	      ln -sf liboai_usrpdevif.so liboai_device.so
+	      ln -sf $dbin/liboai_usrpdevif.so.$REL $dbin/liboai_device.so
+	      echo_info "liboai_device.so is linked to USRP device library"        
+	  elif [ "$HW" == "OAI_BLADERF" ] ; then
+	      if [ -f "/usr/include/libbladeRF.h" ] ; then
+		  compilations \
                         $lte_build_dir oai_bladerfdevif \
-                        liboai_bladerfdevif.so $dbin/liboai_bladerfdevif.so.$REL
-                fi
-                
-                ln -sf liboai_bladerfdevif.so liboai_device.so
-                ln -sf $dbin/liboai_bladerfdevif.so.$REL $dbin/liboai_device.so
-                echo_info "liboai_device.so is linked to BLADERF device library"
-            elif [ "$HW" == "OAI_LMSSDR" ] ; then
+		      liboai_bladerfdevif.so $dbin/liboai_bladerfdevif.so.$REL
+	      fi
+
+	      ln -sf liboai_bladerfdevif.so liboai_device.so
+	      ln -sf $dbin/liboai_bladerfdevif.so.$REL $dbin/liboai_device.so
+	      echo_info "liboai_device.so is linked to BLADERF device library"	 
+	  elif [ "$HW" == "OAI_LMSSDR" ] ; then
                 #       if [ -f "/usr/include/libbladeRF.h" ] ; then
-                compilations \
+		  compilations \
                     $lte_build_dir oai_lmssdrdevif \
-                    liboai_lmssdrdevif.so $dbin/liboai_lmssdrdevif.so.$REL
+		      liboai_lmssdrdevif.so $dbin/liboai_lmssdrdevif.so.$REL
                 #       fi
-                
-                ln -sf liboai_lmssdrdevif.so liboai_device.so
-                ln -sf $dbin/liboai_lmssdrdevif.so.$REL $dbin/liboai_device.so
-                echo_info "liboai_device.so is linked to LMSSDR device library"
-            elif [ "$HW" == "OAI_IRIS" ] ; then
-                compilations \
+
+	      ln -sf liboai_lmssdrdevif.so liboai_device.so
+	      ln -sf $dbin/liboai_lmssdrdevif.so.$REL $dbin/liboai_device.so
+	      echo_info "liboai_device.so is linked to LMSSDR device library"	 
+          elif [ "$HW" == "OAI_IRIS" ] ; then
+                  compilations \
                     $lte_build_dir oai_irisdevif \
-                    liboai_irisdevif.so $dbin/liboai_irisdevif.so.$REL
-                
-                ln -s liboai_irisdevif.so liboai_device.so
-                ln -s $dbin/liboai_irisdevif.so.$REL $dbin/liboai_device.so
-                echo_info "liboai_device.so is linked to IRIS device library"
-            else
-                echo_info "liboai_device.so is not linked to any device library"
-            fi
-        fi
-        
+                      liboai_irisdevif.so $dbin/liboai_irisdevif.so.$REL
+
+              ln -s liboai_irisdevif.so liboai_device.so
+              ln -s $dbin/liboai_irisdevif.so.$REL $dbin/liboai_device.so
+              echo_info "liboai_device.so is linked to IRIS device library"
+	  else 
+	      echo_info "liboai_device.so is not linked to any device library"	    
+	  fi
+      fi
+      
         # build simulators devices
         echo_info "Compiling rfsimulator"
         compilations \
@@ -793,16 +800,16 @@ function main() {
             libtcp_bridge_oai.so $dbin/libtcp_bridge_oai.so.$REL
         # build transport protocol libraries (currently only ETHERNET is available)
 
-        rm -f liboai_transpro.so
-        rm -f $dbin/liboai_transpro.so
-        compilations \
+	  rm -f liboai_transpro.so
+	  rm -f $dbin/liboai_transpro.so
+	      compilations \
             $lte_build_dir oai_eth_transpro \
-            liboai_eth_transpro.so $dbin/liboai_eth_transpro.so.$REL
-        ln -sf liboai_eth_transpro.so liboai_transpro.so
-        ln -sf $dbin/liboai_eth_transpro.so.$REL $dbin/liboai_transpro.so
+		  liboai_eth_transpro.so $dbin/liboai_eth_transpro.so.$REL
+	      ln -sf liboai_eth_transpro.so liboai_transpro.so
+	      ln -sf $dbin/liboai_eth_transpro.so.$REL $dbin/liboai_transpro.so
         echo_info "liboai_transpro.so is linked to ETHERNET transport"
-    fi
-    
+      fi
+
     if [ "$RFSIMULATOR" == "true" -o "$HW" == "OAI_SIMU" ] ; then
         echo_info "Compiling rfsimulator"
         compilations \
@@ -938,6 +945,7 @@ function main() {
     echo "set (USRP_REC_PLAY $USRP_REC_PLAY)"         >>  $cmake_file
     echo "set (LINUX True )"                          >>  $cmake_file
     echo "set (PDCP_USE_NETLINK True )"               >>  $cmake_file
+    echo "set (UETARGET True )"                       >>  $cmake_file
     echo "set (BASIC_SIMULATOR \"True\" )"            >>  $cmake_file
 #    echo "set (UE_NAS_USE_TUN \"True\" )"             >>  $cmake_file
     echo 'include(${CMAKE_CURRENT_SOURCE_DIR}/../../CMakeLists.txt)' >> $cmake_file
diff --git a/cmake_targets/tools/build_helper b/cmake_targets/tools/build_helper
index 048ba300e7ba5db425437b3905981c79d8bdd4f8..0021b673f2bdb3f5145c75aea02d3501f4aaafe5 100755
--- a/cmake_targets/tools/build_helper
+++ b/cmake_targets/tools/build_helper
@@ -102,7 +102,7 @@ check_supported_distribution() {
         "ubuntu14.04") return 0 ;;
         "fedora24")    return 0 ;;
         "rhel7")       return 0 ;;
-	"rhel7.6")     return 0 ;; 
+	"rhel7.6")     return 0 ;;
         "centos7")     return 0 ;;
     esac
     return 1
@@ -639,8 +639,6 @@ check_install_oai_software() {
 	libidn2-0-dev  \
 	libidn11-dev \
 	libmysqlclient-dev  \
-	liboctave-dev \
-	libpgm-dev \
 	libpython2.7-dev \
 	libsctp1  \
 	libsctp-dev  \
@@ -651,7 +649,6 @@ check_install_oai_software() {
 	libxml2-dev  \
 	libxslt1-dev \
 	mscgen  \
-	octave \
 	octave-signal \
 	openssh-client \
 	openssh-server \
@@ -663,7 +660,8 @@ check_install_oai_software() {
 	pydb \
 	libyaml-dev \
 	wget \
-	libxpm-dev
+	libxpm-dev \
+        libboost-all-dev
 
     $SUDO update-alternatives --set "$LAPACK_LIBNAME" "$LAPACK_TARGET"
 
@@ -711,8 +709,6 @@ check_install_oai_software() {
       libidn2-devel  \
       libidn-devel \
       mariadb-devel \
-      octave-devel \
-      openpgm-devel \
       lksctp-tools \
       lksctp-tools-devel \
       openssl-devel \
@@ -722,8 +718,6 @@ check_install_oai_software() {
       libxml2 \
       libxml2-devel \
       libxslt-devel \
-      octave \
-      octave-signal \
       openssh-clients \
       openssh-server \
       openssl \
@@ -746,7 +740,7 @@ check_install_oai_software() {
       libyaml-devel
   fi
 
-    install_asn1c_from_source
+    install_asn1c_from_source $1
     $SUDO rm -fr /opt/ssh
     $SUDO git clone https://gist.github.com/2190472.git /opt/ssh
 }
diff --git a/cmake_targets/tools/fix_asn1 b/cmake_targets/tools/fix_asn1
index fe819c27162df2174c27cc2cc93aa250b00c3bd1..1486589a0c5b3ef76c488a5853faf137bcb4cd72 100755
--- a/cmake_targets/tools/fix_asn1
+++ b/cmake_targets/tools/fix_asn1
@@ -23,7 +23,7 @@ reset_color="$(tput sgr0)"
 function error()
 {
   echo -e "$red_color"ERROR: "$@""$reset_color"
-  exit 1
+#  exit 1
 }
 
 function check_sha1()
@@ -56,11 +56,11 @@ function patch_file()
 
   echo -e "$green_color""patch file $file with $OPENAIR_DIR/cmake_targets/tools/$patch""$reset_color"
 
-  patch "$file" "$OPENAIR_DIR/cmake_targets/tools/$patch"
-  if [ $? -ne 0 ]
-  then
-    error "patching of $file with $OPENAIR_DIR/cmake_targets/tools/$patch failed"
-  fi
+#  patch "$file" "$OPENAIR_DIR/cmake_targets/tools/$patch"
+#  if [ $? -ne 0 ]
+#  then
+#    error "patching of $file with $OPENAIR_DIR/cmake_targets/tools/$patch failed"
+#  fi
 }
 
 function apply_patches()
@@ -140,6 +140,22 @@ function patch_s1ap()
   esac
 }
 
+function patch_f1ap()
+{
+  local directory="$1"
+  local version="$2"
+
+  case "$version" in
+    R15 )
+      #nothing to do anymore (fixes went to asn1c)
+      ;;
+    * )
+      error unknwon/unhandled F1AP version \'"$version"\'
+      ;;
+  esac
+}
+
+
 function main()
 {
   if [ $# -ne 3 ]
@@ -167,6 +183,9 @@ function main()
     S1AP )
       patch_s1ap "$directory" "$version"
       ;;
+    F1AP )
+      patch_f1ap "$directory" "$version"
+      ;;
     * )
       error unknown module "$module"
       ;;
diff --git a/cmake_targets/tools/generate_asn1 b/cmake_targets/tools/generate_asn1
index 79becbf28881395dd495bad7921ee11dce02100b..b382730c6a74f117d3dedb13006ffc60824fb3f7 100755
--- a/cmake_targets/tools/generate_asn1
+++ b/cmake_targets/tools/generate_asn1
@@ -2,23 +2,29 @@
 
 function main()
 {
-mkdir -p $1
-cd $1
+PROTOCOL_DIR=$1
+mkdir -p ${PROTOCOL_DIR}
+cd ${PROTOCOL_DIR}
+
+# Because use $* also include directory, so we need shift
 shift
 
-#if this script is called with only 2 arguments (so 1 here after the shift), it's for RRC
-#(there may be a better way...)
-if [ $# -eq 1 ]; then
+# There are three types parameter for asn1c
+# One is for RRC
+# and one is for F1AP
+# another is for other protocols
+
+if echo ${PROTOCOL_DIR} | grep -q "RRC"; then
 
-#asn1c does not work well with extension groups, we need the following fix:
-# replace [[ by '<name> SEQUENCE {'
-#     and ]] by '} OPTIONAL'
-#<name> is ext<N> with N starting from 1 and incremented at each new [[ ]] just
-#following another [[ ]]
-#
-#this is what the following C program does
+    #asn1c does not work well with extension groups, we need the following fix:
+    # replace [[ by '<name> SEQUENCE {'
+    #     and ]] by '} OPTIONAL'
+    #<name> is ext<N> with N starting from 1 and incremented at each new [[ ]] just
+    #following another [[ ]]
+    #
+    #this is what the following C program does
 
-echo generate asnfix.c
+    echo generate asnfix.c
 
 cat << EOF > asnfix.c
 /* transforms:
@@ -85,30 +91,34 @@ int main(void)
 }
 EOF
 
-echo compile asnfix.c
+    echo compile asnfix.c
 
-gcc -Wall -o asnfix asnfix.c
+    gcc -Wall -o asnfix asnfix.c
 
-echo run asnfix on $1
+    echo run asnfix on $1
 
-./asnfix < $1 > fixed_grammar.asn
+    ./asnfix < $1 > fixed_grammar.asn
 
-rm -f asnfix asnfix.c
+    rm -f asnfix asnfix.c
 
-echo done with asnfix
+    echo done with asnfix
 
-echo running asn1c
+    echo running asn1c
 
-asn1c -gen-PER -fcompound-names fixed_grammar.asn 2>&1 | grep -v -- '->' | grep -v '^Compiled' |grep -v sample
+    asn1c -gen-PER -fcompound-names -no-gen-example fixed_grammar.asn 2>&1 | grep -v -- '->' | grep -v '^Compiled' |grep -v sample
 
-rm -f fixed_grammar.asn
+    rm -f fixed_grammar.asn
 
-echo asn1c done
+    echo asn1c done
 
+elif echo ${PROTOCOL_DIR} | grep -q "F1AP"; then
+    
+    asn1c -gen-PER -fcompound-names -no-gen-example -findirect-choice -fno-include-deps $* 2>&1 | grep -v -- '->' | grep -v '^Compiled' |grep -v sample
+    
 else
-
-asn1c -gen-PER -fcompound-names $* 2>&1 | grep -v -- '->' | grep -v '^Compiled' |grep -v sample
-
+    
+    asn1c -gen-PER -fcompound-names -no-gen-example $* 2>&1 | grep -v -- '->' | grep -v '^Compiled' |grep -v sample
+    
 fi
 
 awk ' 
diff --git a/cmake_targets/tools/make_asn1c_includes.sh b/cmake_targets/tools/make_asn1c_includes.sh
index bd4254c9388e1a577ba8ca27ec4370f700022581..a7f480f90f3653e71743c113a7bb60dc69b5c633 100755
--- a/cmake_targets/tools/make_asn1c_includes.sh
+++ b/cmake_targets/tools/make_asn1c_includes.sh
@@ -3,11 +3,11 @@ GENERATED_FULL_DIR=$1
 shift
 ASN1_SOURCE_DIR=$1
 shift
-export ASN1C_PREFIX=$1 
+export ASN1C_PREFIX=$1
 shift
 options=$*
 done_flag="$GENERATED_FULL_DIR"/done
-if [ "$done_flag" -ot $ASN1_SOURCE_DIR ] ; then 
+if [ "$done_flag" -ot $ASN1_SOURCE_DIR ] ; then
    rm -f "$GENERATED_FULL_DIR"/${ASN1C_PREFIX}*.c "$GENERATED_FULL_DIR"/${ASN1C_PREFIX}*.h
    mkdir -p "$GENERATED_FULL_DIR"
    asn1c -pdu=all -fcompound-names -gen-PER -no-gen-OER -no-gen-example $options -D $GENERATED_FULL_DIR $ASN1_SOURCE_DIR |& egrep -v "^Copied|^Compiled" | sort -u
diff --git a/common/config/DOC/config/arch.md b/common/config/DOC/config/arch.md
index 170241500b3672984105ad7eb9f43cafcfcb11f4..f888724c4116ed1062f0c096ada1947f601b2839 100644
--- a/common/config/DOC/config/arch.md
+++ b/common/config/DOC/config/arch.md
@@ -1,7 +1,7 @@
 # config module source files
-![configmodule_srcdir](/uploads/fdc3e96011fd5592440900dfa05b4701/configmodule_srcdir.png)  
+![configmodule_srcdir](/uploads/fdc3e96011fd5592440900dfa05b4701/configmodule_srcdir.png)
 # config module components
 ![configmodule_components](/uploads/54f8a3953d5ee53717cd9a3b71f85c68/configmodule_components.png)
 
 
-[Configuration module home](../config.md)
\ No newline at end of file
+[Configuration module home](../config.md)
diff --git a/common/config/DOC/config/devusage.md b/common/config/DOC/config/devusage.md
index bfc1180ab8b90b1af108da3a4e0acbbbb926a6f6..151ffeafa8c435786927e900c3316e2d4aaf2d88 100644
--- a/common/config/DOC/config/devusage.md
+++ b/common/config/DOC/config/devusage.md
@@ -1,17 +1,17 @@
-The configuration module objectives are 
+The configuration module objectives are
 1. Allow easy parameters management in oai, helping the development of a flexible, modularized and fully configurable softmodem.
 1. Use a common configuration API in all oai modules
-1. Allow development of alternative configuration sources without modifying the oai code. Today the only delivered configuration source is the libconfig format configuration file.  
+1. Allow development of alternative configuration sources without modifying the oai code. Today the only delivered configuration source is the libconfig format configuration file.
 
 As a developer you may need to look at these sections:
 
 * [add parameters in an existing section](devusage/addaparam.md)
 * [add a parameter set, in a new section](devusage/addparamset.md)
-* [configuration module API](devusage/api.md) 
-* [configuration module public structures](devusage/struct.md)  
+* [configuration module API](devusage/api.md)
+* [configuration module public structures](devusage/struct.md)
 
-Whatever your need is, configuration module usage examples can be found in oai sources:  
-*  complex example, using all the configuration module functionalities, including parameter checking: 
+Whatever your need is, configuration module usage examples can be found in oai sources:
+*  complex example, using all the configuration module functionalities, including parameter checking:
 [NB-IoT configuration code](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/openair2/ENB_APP/NB_IoT_config.c) and [NB-IoT configuration include file](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/openair2/ENB_APP/NB_IoT_paramdef.h)
 *  very simple example, just reading a parameter set corresponding to a dedicated section:  the telnetsrv_autoinit function in [common/utils/telnetsrv/telnetsrv.c, around line 726](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/common/utils/telnetsrv/telnetsrv.c#L726)
 *  an example with run-time definition of parameters, in the logging sub-system: the log_getconfig function at the top of [openair2/UTIL/LOG/log.c](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/openair2/UTIL/LOG/log.c)
diff --git a/common/config/DOC/config/devusage/addaparam.md b/common/config/DOC/config/devusage/addaparam.md
index b7bb8a73b90df5f1e7f17a61d47266b68bc1982c..246c49452613a2da5c5e4ecc287a32d9064dca22 100644
--- a/common/config/DOC/config/devusage/addaparam.md
+++ b/common/config/DOC/config/devusage/addaparam.md
@@ -1,6 +1,6 @@
-To add a new parameter in an existing section you  insert an item in a `paramdef_t` array, which describes the parameters to be read in the existing `config_get` call. You also need to increment the numparams argument.  
+To add a new parameter in an existing section you  insert an item in a `paramdef_t` array, which describes the parameters to be read in the existing `config_get` call. You also need to increment the numparams argument.
 
-existing code:  
+existing code:
 ```c
 unsigned int varopt1;
 paramdef_t someoptions[] = {
@@ -11,10 +11,10 @@ paramdef_t someoptions[] = {
    {"opt1",  "<help opt1>",   0,      uptr:&varopt1, defuintval:0, TYPE_UINT,  0 },
 };
 
-config_get( someoptions,sizeof(someoptions)/sizeof(paramdef_t),"somesection"); 
+config_get( someoptions,sizeof(someoptions)/sizeof(paramdef_t),"somesection");
 
 ```
-new code:  
+new code:
 ```c
 unsigned int varopt1;
 
@@ -31,7 +31,7 @@ paramdef_t someoptions[] = {
    {"opt2",  "<help opt2>",   0,      strptr:&varopt2,defstrval:"",TYPE_STRING,0   },
 };
 
-config_get( someoptions,sizeof(someoptions)/sizeof(paramdef_t),"somesection"); 
+config_get( someoptions,sizeof(someoptions)/sizeof(paramdef_t),"somesection");
 
 ```
 
@@ -57,10 +57,10 @@ The configuration module provides a mechanism to check the parameter value read
  A `checkedparam_t` structure array provides the parameter verification procedures:
 
 ```c
-/* 
+/*
    definition of the verification to be done on param opt1 and opt2.
    opt1 is an integer option we must be set to 0,2,3,4 or 7 in the
-   config source.  
+   config source.
    if opt1 is set to 0 in the config file, it will be set to 1, etc
    opt2 is C string option with the authorize values "zero","oneThird","twoThird","one"
  */
@@ -82,5 +82,5 @@ for(int i=0 ; i < sizeof(someoptions)/sizeof(paramdesc_t) ; i ++) {
 ```
 When you need a specific verification algorithm, you can provide your own verification function and use it in place of the available ones, in the `checkedparam_t` union. If no existing structure definition match your need, you can enhance the configuration module. You then have to add a new verification function in https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/common/config/config_userapi.c and add a new structure definition in the `checkedparam_t` type defined in https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/common/config/config_paramdesc.h
 
-[Configuration module developer main page](../../config/devusage.md)  
+[Configuration module developer main page](../../config/devusage.md)
 [Configuration module home](../../config.md)
diff --git a/common/config/DOC/config/devusage/addparamset.md b/common/config/DOC/config/devusage/addparamset.md
index 130a7eda749033beb1492332c9367df5311f4447..49448e11da79fd2292f0e8105456f6fb3e6ca81a 100644
--- a/common/config/DOC/config/devusage/addparamset.md
+++ b/common/config/DOC/config/devusage/addparamset.md
@@ -1,7 +1,7 @@
 The configuration module maps a configuration file section to a `paramdef_t` structure array. One `config_get` call can be used to return the values of all the parameters described in the `paramdef_t` array.
 Retrieving a single occurence of a parameter set ( a group in the libconfig terminology) is just a two steps task:
 1.  describe the parameters in a `paramdef_t` array
-1.  call the `config_get` function  
+1.  call the `config_get` function
 
 
 [config_get example](../../config/devusage/addaparam.md)
@@ -30,19 +30,19 @@ NB-IoT_MACRLCs =
 );
 
 ```
-The configuration module provides the `config_getlist` call to support lists of group of parameters. Below is a commented code example, using the config_getlist call.  
+The configuration module provides the `config_getlist` call to support lists of group of parameters. Below is a commented code example, using the config_getlist call.
 
 ```c
 /* name of section containing the list */
 #define NBIOT_MACRLCLIST_CONFIG_STRING      "NB-IoT_MACRLCs"
 
-/* 
+/*
 The following macro define the parameters names, as used in the
 configuration file
-*/   
-#define CONFIG_STRING_MACRLC_CC             "num_cc" 
+*/
+#define CONFIG_STRING_MACRLC_CC             "num_cc"
 .....
-#define CONFIG_MACRLC_S_PORTD               "remote_s_portd" 
+#define CONFIG_MACRLC_S_PORTD               "remote_s_portd"
 
 /*
    now define a macro which will be used to initialize the NbIoT_MacRLC_Params
@@ -51,16 +51,16 @@ configuration file
    module allocate the memory for the parameters values.
 */
 /*------------------------------------------------------------------------------------------------------------*/
-/*   optname               helpstr   paramflags    XXXptr              defXXXval                  type           numelt     */ 
+/*   optname               helpstr   paramflags    XXXptr              defXXXval                  type           numelt     */
 /*------------------------------------------------------------------------------------------------------------*/
 
 #define MACRLCPARAMS_DESC { \
 {CONFIG_STRING_MACRLC_CC, NULL,     0,          uptr:NULL,           defintval:1,           TYPE_UINT,     0}, \
 .............  \
 {CONFIG_MACRLC_S_PORTD,   NULL,     0,          uptr:NULL,           defintval:50021,           TYPE_UINT,     0}, \
-}  
+}
 
-/* 
+/*
 the following macros define the indexes used to access the NbIoT_MacRLC_Params array
 items. They must be maintained consistent with the previous  MACRLCPARAMS_DESC macro
 which is used to initialize the NbIoT_MacRLC_Params variable
@@ -72,60 +72,60 @@ which is used to initialize the NbIoT_MacRLC_Params variable
 
 
 void RCconfig_NbIoTmacrlc(void) {
- 
+
 
 /*
    define and initialize the array of paramdef_t structures describing the groups of
-   parameters we want to read. It will be passed as the second argument of the 
+   parameters we want to read. It will be passed as the second argument of the
    config_getlist call, which will use it as an input only argument.
 */
   paramdef_t NbIoT_MacRLC_Params[] = MACRLCPARAMS_DESC;
 
-/* 
+/*
       now define and initialize a paramlist_def_t structure which will be passed
    to the config_getlist call. The first field is the only one to be initialized
-   it contains the name of the section to be read. 
+   it contains the name of the section to be read.
    that section contains the list of group of parameters.
       The two other fields are output parameters used to return respectively
-   a pointer to a two dimensional array of paramdef_t structures pointers, and the 
+   a pointer to a two dimensional array of paramdef_t structures pointers, and the
    number  of items in the list of groups (size of first dimension, the second one
    being the number of parameters in each group.
-*/ 
+*/
   paramlist_def_t NbIoT_MacRLC_ParamList = {NBIOT_MACRLCLIST_CONFIG_STRING,NULL,0};
 
 
- /* 
-   the config_getlist will allocate the second field of the paramlist_def_t structure, a 
-two dimensional array of paramdef_t pointers. In each param_def item it will allocate 
+ /*
+   the config_getlist will allocate the second field of the paramlist_def_t structure, a
+two dimensional array of paramdef_t pointers. In each param_def item it will allocate
 the value pointer and set the value to what it will get from the config source. The
 numelt field of the paramlist_def_t structure will be set to the number of groups of
 parameters in the list.
     in this example the last argument of config_getlist is unused, it may contain a
 character string, used as a prefix for the section name. It has to be specified when the
 list to be read is under another section.
-*/  
+*/
   config_getlist( &NbIoT_MacRLC_ParamList,NbIoT_MacRLC_Params,
-                  sizeof(NbIoT_MacRLC_Params)/sizeof(paramdef_t), 
+                  sizeof(NbIoT_MacRLC_Params)/sizeof(paramdef_t),
                   NULL);
-  
-/* 
+
+/*
   start a loop in the nuber of groups in the list, the numelt field of the
   paramlist_def_t structure has been set in the config_getlist call
 */
   for (j=0 ; j<NbIoT_MacRLC_ParamList.numelt ; j++) {
 
 ..........
- 
+
 /* access the MACRLC_REMOTE_S_PORTD parameter in the j ieme group of the list */
-	RC.nb_iot_mac[j]->eth_params_s.remote_portd = 
+	RC.nb_iot_mac[j]->eth_params_s.remote_portd =
                *(NbIoT_MacRLC_ParamList.paramarray[j][MACRLC_REMOTE_S_PORTD_IDX].iptr);
 ............
-	
+
   } // MacRLC_ParamList.numelt > 0
 }
 
 
-```  
+```
 
-[Configuration module developer main page](../../config/devusage.md)  
+[Configuration module developer main page](../../config/devusage.md)
 [Configuration module home](../../config.md)
diff --git a/common/config/DOC/config/devusage/api.md b/common/config/DOC/config/devusage/api.md
index 050abc5315cf86384a35e2006551b3a2d47d3399..06c22dba6fe53c91034e48900d90913bb6167f52 100644
--- a/common/config/DOC/config/devusage/api.md
+++ b/common/config/DOC/config/devusage/api.md
@@ -25,14 +25,14 @@ int config_get(paramdef_t *params,int numparams, char *prefix)
  - `PARAMFLAG_DISABLECMDLINE`: parameter cannot be modified via the command line
  - `PARAMFLAG_DONOTREAD`: ignore the parameter, can be used at run-time, to alter a pre-defined `paramdef_t` array which is used in several `config_get` or/and `config_getlist` calls.
  - `PARAMFLAG_NOFREE`: do not free the memory possibly allocated by the config module to store the value of the parameter. Default behavior is for the config module to free the memory it has allocated when the `config_end` function is called.
- - `PARAMFLAG_BOOL`: Only relevant for integer types. tell the config module that when processing the command line, the corresponding option can be specified without any arggument and that in this case it must set the value to 1.  
+ - `PARAMFLAG_BOOL`: Only relevant for integer types. tell the config module that when processing the command line, the corresponding option can be specified without any arggument and that in this case it must set the value to 1.
 
 * `params` is also used as an output parameter, `< XXX >ptr >` field  is used by the config module to store the value it has read. The following bits can possibly be set in the `paramflags` mask after the call:
   - `PARAMFLAG_MALLOCINCONFIG`: memory has been allocated for the ` < XXX >ptr > ` field
   - `PARAMFLAG_PARAMSET`: parameter has been found in the config source, it is not set to default value.
   - `PARAMFLAG_PARAMSET`: parameter has been set to its default value
 * `numparams` is the number of entries in the params array
-* `prefix` is a character string to be appended to the parameters name, it defines the parameters position in the configuration file hierarchy (the section name in libconfig terminology). 
+* `prefix` is a character string to be appended to the parameters name, it defines the parameters position in the configuration file hierarchy (the section name in libconfig terminology).
 * The returned value is the number of parameters which have been assigned a value or -1 if a severe error occured
 
 ```c
@@ -42,8 +42,8 @@ int config_libconfig_getlist(paramlist_def_t *ParamList, paramdef_t *params, int
 * Calls the `config_<config source>_get` function for each list occurrence
 * `params` points to an array of `paramdef_t` structures which describes the parameters in each occurrence of the list
 * `ParamList`  points to a structure, where `paramarray` field points to an array of `paramdef_t` structure, allocated by the function. It is used to return the values of the parameters.
-* The returned value is the number of occurrences in the list or -1 in case of severe error  
+* The returned value is the number of occurrences in the list or -1 in case of severe error
 
 
-[Configuration module developer main page](../../config/devusage.md)  
+[Configuration module developer main page](../../config/devusage.md)
 [Configuration module home](../../config.md)
diff --git a/common/config/DOC/config/devusage/struct.md b/common/config/DOC/config/devusage/struct.md
index 236c1b4e0387f50add8ee03085ead2c568169c4a..e8b15fc0f1e549e03e5ef5692346b8c6e9941c90 100644
--- a/common/config/DOC/config/devusage/struct.md
+++ b/common/config/DOC/config/devusage/struct.md
@@ -10,11 +10,11 @@ It is defined in include file [ common/config/config_paramdesc.h ](https://gitla
 | `type` | Supported parameter types are defined as integer macros. Supported simple types are `TYPE_STRING`, parameter value is returned in `strptr` field,  `TYPE_INT8` `TYPE_UINT8` `TYPE_INT16` `TYPE_UINT16` `TYPE_INT32` `TYPE_UINT32` `TYPE_INT64` `TYPE_UINT64`, parameter value is returned in the corresponding uXptr or iXptr, `TYPE_MASK`, value is returned in `u32ptr`, `TYPE_DOUBLE` value is returned in `dblptr`, `TYPE_IPV4ADDR` value is returned in binary, network bytes order in `u32ptr` field. `TYPE_STRINGLIST`, `TYPE_INTARRAY` and `TYPE_UINTARRAY` are multiple values types. Multiple values are returned in respectively, `strlistptr`, `iptr` and `uptr` fields which then point to arrays. The  `numelt` field gives the number of item in the array. | I |
 | `numelt` | For `TYPE_STRING` where `strptr` points to a preallocated string, this field must contain the size in bytes of the available memory. For all multiple values types, this field contains the number of values in the value field.| I/O |
 | `chkPptr` | possible pointer to the structure containing the info used to check parameter values | I |
-| `processedvalue` | When `chkPptr` is not `ǸULL`, is used to return a value, computed from the original parameter, as read from the configuration source. | O |  
-  
+| `processedvalue` | When `chkPptr` is not `ǸULL`, is used to return a value, computed from the original parameter, as read from the configuration source. | O |
+
 # `paramlist_def_t`structure
-It is defined in include file [ common/config/config_paramdesc.h ](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/common/config/config_paramdesc.h#L160). 
-It is used as an argument to `config_getlist` calls, to get values of multiple occurrences of group of parameters.  
+It is defined in include file [ common/config/config_paramdesc.h ](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/common/config/config_paramdesc.h#L160).
+It is used as an argument to `config_getlist` calls, to get values of multiple occurrences of group of parameters.
 
 | Fields     | Description                                                       | I/O |
 |:-----------|:------------------------------------------------------------------|----:|
@@ -23,11 +23,11 @@ It is used as an argument to `config_getlist` calls, to get values of multiple o
 | `numelt` | Number of items in the `paramarray` field | O |
 
 # `checkedparam_t` union
-It is defined in include file [ common/config/config_paramdesc.h ](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/common/config/config_paramdesc.h#L62). 
+It is defined in include file [ common/config/config_paramdesc.h ](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/common/config/config_paramdesc.h#L62).
 This union of structures is used to provide a parameter checking mechanism. Each `paramdef_t` instance may include a pointer to a `checkedparam_t`structure which is then used by the configuration module to check the value it got from the config source.
 Each structure in the union provides one parameter verification method, which returns `-1` when the verification fails. Currently the following structures  are defined in the `checkedparam_t` union:
 
-| structure name    | Description                                                     | 
+| structure name    | Description                                                     |
 |:-----------|:------------------------------------------------------------------|----:|
 | `s1` | check an integer against a list of authorized values |
 | `s1a` | check an integer against a list of authorized values and set the parameter value to another integer depending on the read value|
@@ -40,14 +40,14 @@ each of these structures provide the required fields to perform the specified pa
 The configuration module provides an implementation of the functions to be used to check parameters, qs described below.
 
 ## `s1` structure
-| field    | Description                                                     | 
+| field    | Description                                                     |
 |:-----------|:------------------------------------------------------------------|
 | `f1` | pointer to the checking function. Initialize to `config_check_intval` to use the config module implementation |
 | `okintval` | array of `CONFIG_MAX_NUMCHECKVAL` integers containing the authorized values |
 | `num_okintval` | number of used values in `okintval` |
 
 ## `s1a` structure
-| field    | Description                                                     | 
+| field    | Description                                                     |
 |:-----------|:------------------------------------------------------------------|
 | `f1a` | pointer to the checking function. Initialize to `config_check_modify_integer` to use the config module implementation |
 | `okintval` | array of `CONFIG_MAX_NUMCHECKVAL` integers containing the authorized values |
@@ -55,13 +55,13 @@ The configuration module provides an implementation of the functions to be used
 | `num_okintval` | number of used values in `okintval` and `setintval` |
 
 ## `s2` structure
-| field    | Description                                                     | 
+| field    | Description                                                     |
 |:-----------|:------------------------------------------------------------------|
 | `f2` | pointer to the checking function. Initialize to `config_check_intrange` to use the config module implementation |
 | `okintrange` | array of 2 integers containing the min and max values for the parameter |
 
 ## `s3` structure
-| field    | Description                                                     | 
+| field    | Description                                                     |
 |:-----------|:------------------------------------------------------------------|
 | `f3` | pointer to the checking function. Initialize to `config_check_strval` to use the config module implementation |
 | `okstrval` | array of `CONFIG_MAX_NUMCHECKVAL` C string pointers containing the authorized values |
@@ -69,7 +69,7 @@ The configuration module provides an implementation of the functions to be used
 
 
 ## `s3a` structure
-| field    | Description                                                     | 
+| field    | Description                                                     |
 |:-----------|:------------------------------------------------------------------|
 | `f3a` | pointer to the checking function. Initialize to `config_checkstr_assign_integer` to use the config module implementation |
 | `okstrval` | array of `CONFIG_MAX_NUMCHECKVAL` C string pointers containing the authorized values |
@@ -77,9 +77,9 @@ The configuration module provides an implementation of the functions to be used
 | `num_okstrval` | number of used values in `okintval` and `setintval` |
 
 ## `s4` and `s5` structures
-| field    | Description                                                     | 
+| field    | Description                                                     |
 |:-----------|:------------------------------------------------------------------|
 | `f4`  or `f5` | pointer to the checking function. they are generic structures to be used  when no existing structure provides the required parameter verification. `f4` takes one argument, the `paramdef_t` structure corresponding to the parameter to be checked (`int  (*f4)(paramdef_t *param)`), `f5` taxes no argument (`void (*checkfunc)(void)`) |
 
-[Configuration module developer main page](../../config/devusage.md)  
+[Configuration module developer main page](../../config/devusage.md)
 [Configuration module home](../../config.md)
diff --git a/common/config/DOC/config/rtusage.md b/common/config/DOC/config/rtusage.md
index 109ba84bba2b1503fab255045b11415c5b20bf44..10cbee24950bb3972f80118745f4efb65a50b516 100644
--- a/common/config/DOC/config/rtusage.md
+++ b/common/config/DOC/config/rtusage.md
@@ -1,34 +1,34 @@
- 
-   -O  is the only mandatory command line option to start the eNodeb softmodem (lte-softmodem executable), it is used to specify the configuration source with the associated parameters:  
+
+   -O  is the only mandatory command line option to start the eNodeb softmodem (lte-softmodem executable), it is used to specify the configuration source with the associated parameters:
 ```bash
 $ ./lte-softmodem -O <configsource>:<parameter1>:<parameter2>:...
 ```
-  The configuration module can also be used without a configuration source, ie to only parse the command line. In this case the -O switch is optional. This mode is used in the ue-softmodem executable and by the phy_simulators executables (ulsim, dlsim)  
+  The configuration module can also be used without a configuration source, ie to only parse the command line. In this case the -O switch is optional. This mode is used in the ue-softmodem executable and by the phy_simulators executables (ulsim, dlsim)
 
 Currently the available config sources are:
 
-- **libconfig**: libconfig file. [libconfig file format](http://www.hyperrealm.com/libconfig/libconfig_manual.html#Configuration-Files) Parameter1 is the file path and parameter 2 can be used to specify the level of console messages printed by the configuration module.  
+- **libconfig**: libconfig file. [libconfig file format](http://www.hyperrealm.com/libconfig/libconfig_manual.html#Configuration-Files) Parameter1 is the file path and parameter 2 can be used to specify the level of console messages printed by the configuration module.
 ```bash
 $ ./lte-softmodem -O libconfig:<config>:dbgl<debuglevel>
 ```
 - **cmdlineonly**: command line only, the default mode for lte-uesoftmodem and the phy simiulators. In this case -O may be used to specify the config module debug level.
 
-The debug level is a mask:  
-*  bit 1: print parameters values 
+The debug level is a mask:
+*  bit 1: print parameters values
 *  bit 2: print memory allocation/free performed by the config module
 *  bit 3: print command line processing messages
 *  bit 4: disable execution abort when parameters checking fails
 
-As a oai user, you may have to use bit 1 (dbgl1) , to check your configuration and get the full name of a parameter you would like to modify on the command line. Other bits are for developers usage, (dbgl7 will print all debug messages).  
+As a oai user, you may have to use bit 1 (dbgl1) , to check your configuration and get the full name of a parameter you would like to modify on the command line. Other bits are for developers usage, (dbgl7 will print all debug messages).
 
 ```bash
-$ ./lte-softmodem -O libconfig:<config>:dbgl1  
+$ ./lte-softmodem -O libconfig:<config>:dbgl1
 ```
 ```bash
 $ ./lte-uesoftmodem -O cmdlineonly:dbgl1
 ```
 To get help on supported parameters you can use specific options:
-*  ---help: print help for command line only parameters and for parameters not defined in a specific section 
+*  ---help: print help for command line only parameters and for parameters not defined in a specific section
 	*  ---help_< prefix > : print help for parameters defined under the section < prefix >
 
 ```
@@ -49,23 +49,23 @@ To get help on supported parameters you can use specific options:
     -C: Set the downlink frequency for all component carriers
     -a: Channel id offset
     -d: Enable soft scope and L1 and L2 stats (Xforms)
-    -q: Enable processing timing measurement of lte softmodem on per subframe basis 
-    -S: Skip the missed slots/subframes 
+    -q: Enable processing timing measurement of lte softmodem on per subframe basis
+    -S: Skip the missed slots/subframes
     --numerology: adding numerology for 5G
     --parallel-config: three config for level of parallelism 'PARALLEL_SINGLE_THREAD', 'PARALLEL_RU_L1_SPLIT', or 'PARALLEL_RU_L1_TRX_SPLIT'
     --worker-config: two option for worker 'WORKER_DISABLE' or 'WORKER_ENABLE'
     --nbiot-disable: disable nb-iot, even if defined in config
     --noS1: Disable s1 interface
-    --nokrnmod: (noS1 only): Use tun instead of namesh module 
+    --nokrnmod: (noS1 only): Use tun instead of namesh module
 --------------------------------------------------------------------
 
 [LIBCONFIG] (root): 4/4 parameters successfully set, (4 to default value)
 
 -----Help for section (root section)            : 004 entries------
-    -R: Enable online log 
+    -R: Enable online log
     -g: Set the global log level, valide options: (4:trace, 3:debug, 2:info, 1:warn, (0:error))
-    --telnetsrv: Start embedded telnet server 
-    --msc: Enable the MSC tracing utility 
+    --telnetsrv: Start embedded telnet server
+    --msc: Enable the MSC tracing utility
 --------------------------------------------------------------------
 
 [LIBCONFIG] loader: 2/2 parameters successfully set, (2 to default value)
@@ -84,13 +84,13 @@ Getting ENBSParams
 
 ```
 
-For the lte-softmodem (the eNodeB) The config source parameter defaults to libconfig, preserving the initial -O option format. In this case you cannot specify the debug level.  
+For the lte-softmodem (the eNodeB) The config source parameter defaults to libconfig, preserving the initial -O option format. In this case you cannot specify the debug level.
 
 ```bash
 $ ./lte-softmodem -O <config>
 ```
 
-Configuration file parameters, except for the configuration file path,  can be specified in a **config** section in the configuration file:  
+Configuration file parameters, except for the configuration file path,  can be specified in a **config** section in the configuration file:
 
 ```
 config:
@@ -102,8 +102,8 @@ Configuration files examples can be found in the targets/PROJECTS/GENERIC-LTE-EP
 
 ```bash
 $ ./lte-softmodem -O <config> --eNBs.[0].component_carriers.[0].N_RB_DL 100
-```  
+```
 
 As specified earlier, use the dbgl1 debug level to get the full name of a parameter you would like to modify on the command line.
 
-[Configuration module home](../config.md)
\ No newline at end of file
+[Configuration module home](../config.md)
diff --git a/common/ngran_types.h b/common/ngran_types.h
new file mode 100644
index 0000000000000000000000000000000000000000..224a85def5c704f03f873e139f3a1a4de05123f0
--- /dev/null
+++ b/common/ngran_types.h
@@ -0,0 +1,51 @@
+/*
+ * 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
+ */
+
+/*! \file common/ngran_types.h
+* \brief Definitions for NGRAN node types
+* \author R. Knopp
+* \date 2018
+* \version 0.1
+* \company Eurecom
+* \email: knopp@eurecom.fr
+* \note
+* \warning
+*/
+
+#ifndef __NGRAN_TYPES_H__
+#define __NGRAN_TYPES_H__
+
+typedef enum {
+  ngran_eNB       = 0,
+  ngran_ng_eNB    = 1,
+  ngran_gNB       = 2,
+  ngran_eNB_CU    = 3,
+  ngran_ng_eNB_CU = 4,
+  ngran_gNB_CU    = 5,
+  ngran_eNB_DU    = 6,
+  ngran_gNB_DU    = 7
+} ngran_node_t;
+
+#define NODE_IS_MONOLITHIC(nOdE_TyPe) ((nOdE_TyPe) == ngran_eNB    || (nOdE_TyPe) == ngran_ng_eNB    || (nOdE_TyPe) == ngran_gNB)
+#define NODE_IS_CU(nOdE_TyPe)         ((nOdE_TyPe) == ngran_eNB_CU || (nOdE_TyPe) == ngran_ng_eNB_CU || (nOdE_TyPe) == ngran_gNB_CU)
+#define NODE_IS_DU(nOdE_TyPe)         ((nOdE_TyPe) == ngran_eNB_DU || (nOdE_TyPe) == ngran_gNB_DU)
+
+#endif
diff --git a/common/ran_context.h b/common/ran_context.h
index 08c05411c98fa36829c39cb5cf04ec35c0f95dfc..c0b58d2af2cc79bc09b179245a1d3e132b278ad9 100644
--- a/common/ran_context.h
+++ b/common/ran_context.h
@@ -39,6 +39,8 @@
 #include "PHY/types.h"
 #include "PHY/impl_defs_top.h"
 #include "PHY/impl_defs_lte.h"
+
+#include "ENB_APP/enb_config.h"
 #include "RRC/LTE/rrc_defs.h"
 #include "flexran_agent_defs.h"
 
@@ -49,7 +51,11 @@
 #include "gtpv1u_eNB_defs.h"
 
 #include "PHY/defs_L1_NB_IoT.h"
+
 #include "RRC/LTE/defs_NB_IoT.h"
+
+
+
 typedef struct {
   /// RAN context config file name
   char *config_file_name;
diff --git a/common/utils/DOC/loader/arch.md b/common/utils/DOC/loader/arch.md
index 6fd1f47e7b94ec7faa8605aacaa4ec9191589bde..52ffd428ddba5fa31f9a3ddcdb784a174f606039 100644
--- a/common/utils/DOC/loader/arch.md
+++ b/common/utils/DOC/loader/arch.md
@@ -2,6 +2,6 @@
 
 The oai shared library loader is implemented in two source files, located in [common/utils](https://gitlab.eurecom.fr/oai/openairinterface5g/tree/develop/common/utils)
 1. [load_module_shlib.c](https://gitlab.eurecom.fr/oai/openairinterface5g/tree/develop/common/utils/load_module_shlib.c) contains the loader implementation
-1.  [load_module_shlib.h](https://gitlab.eurecom.fr/oai/openairinterface5g/tree/develop/common/utils/load_module_shlib.h) is the loader include file containing both private and public data type definitions. It also contain API prototypes.  
+1.  [load_module_shlib.h](https://gitlab.eurecom.fr/oai/openairinterface5g/tree/develop/common/utils/load_module_shlib.h) is the loader include file containing both private and public data type definitions. It also contain API prototypes.
 
-[loader home page](../loader.md)
\ No newline at end of file
+[loader home page](../loader.md)
diff --git a/common/utils/DOC/loader/devusage.md b/common/utils/DOC/loader/devusage.md
index 915075c361d9f89c5ac38e892d95ecf4362d3481..bd45c88a85223ce1123877f339c4bfbf19663e94 100644
--- a/common/utils/DOC/loader/devusage.md
+++ b/common/utils/DOC/loader/devusage.md
@@ -1,16 +1,16 @@
-The loader objectives are 
+The loader objectives are
 1. provides a common mechanism to prevent an executable to include code that is only used under specific configurations, without rebuilding the code
 1. Provide a common mechanism to allow to choose between different implementations of a given set of functions, without rebuilding the code
 
 As a developer you may need to look at these sections:
 
 * [loading a shared library](devusage/loading.md)
-* [loader API](devusage/api.md) 
-* [loader public structures](devusage/struct.md)  
+* [loader API](devusage/api.md)
+* [loader public structures](devusage/struct.md)
 
-Loader usage examples can be found in oai sources:  
+Loader usage examples can be found in oai sources:
 
-*  device and transport initialization code: [function `load_lib` in *targets/ARCH/COMMON/__common_lib.c__* ](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/targets/ARCH/COMMON/common_lib.c#L91) 
+*  device and transport initialization code: [function `load_lib` in *targets/ARCH/COMMON/__common_lib.c__* ](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/targets/ARCH/COMMON/common_lib.c#L91)
 *  turbo encoder and decoder initialization: [function `load_codinglib`in *openair1/PHY/CODING/__coding_load.c__*](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/openair1/PHY/CODING/coding_load.c#L113)
 
 [loader home page](../loader.md)
diff --git a/common/utils/DOC/loader/devusage/api.md b/common/utils/DOC/loader/devusage/api.md
index 21c2a1d25372e848f0723db766aafa4188edc24a..a6e59c593800ab34b93e98453660c1db73f00034 100644
--- a/common/utils/DOC/loader/devusage/api.md
+++ b/common/utils/DOC/loader/devusage/api.md
@@ -1,12 +1,12 @@
- Loader API is defined in the [common/utils/load_module_shlib.h](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/common/utils/load_module_shlib.h) include file. 
+ Loader API is defined in the [common/utils/load_module_shlib.h](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/common/utils/load_module_shlib.h) include file.
 ```c
 int load_module_shlib(char *modname,loader_shlibfunc_t *farray, int numf)
 ```
-* possibly initializes the loader, if it has not been already initialized 
-* Formats the full shared library path, using the `modname` argument and the loader `shlibpath` and `shlibversion`configuration parameters. 
+* possibly initializes the loader, if it has not been already initialized
+* Formats the full shared library path, using the `modname` argument and the loader `shlibpath` and `shlibversion`configuration parameters.
 * loads the shared library, using the dlopen system call
 * looks for `< modname >_autoinit` symbol, using the `dlsym` system call and possibly call the corresponding function.
-* looks for `< modname >_checkbuildver` symbol, using the `dlsym` system call and possibly calls the corresponding function. If the return value of this call is `-1`, program execution is stopped. It is the responsibility of the shared library developer to implement or not a `< modname >_checkbuildver` function and to decide if a version mismatch is a fatal condition. The `< modname >_checkbuildver` function must match the `checkverfunc_t` function type. The first argument is the main executable version, as set  in the `PACKAGE_VERSION` macro defined in the [oai CMakeLists](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/cmake_targets/CMakeLists.txt#L218), around line 218. The second argument points to the shared library version which should be set  by the `< modname >_checkbuildver` function. 
+* looks for `< modname >_checkbuildver` symbol, using the `dlsym` system call and possibly calls the corresponding function. If the return value of this call is `-1`, program execution is stopped. It is the responsibility of the shared library developer to implement or not a `< modname >_checkbuildver` function and to decide if a version mismatch is a fatal condition. The `< modname >_checkbuildver` function must match the `checkverfunc_t` function type. The first argument is the main executable version, as set  in the `PACKAGE_VERSION` macro defined in the [oai CMakeLists](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/cmake_targets/CMakeLists.txt#L218), around line 218. The second argument points to the shared library version which should be set  by the `< modname >_checkbuildver` function.
 * If the farray pointer is null,  looks for `< modname >_getfarray` symbol, calls the corresponding function when the symbol is found. `< modname >_getfarray` takes one argument, a pointer to a  `loader_shlibfunc_t` array, and returns the number of items in this array, as defined by the `getfarrayfunc_t` type. The `loader_shlibfunc_t` array returned by the shared library must be fully filled (both `fname` and `fptr` fields).
 * looks for the `numf` function symbols listed in the `farray[i].fname` arguments and set the corresponding `farray[i].fptr`function pointers
 
@@ -14,7 +14,7 @@ int load_module_shlib(char *modname,loader_shlibfunc_t *farray, int numf)
 ```c
 void * get_shlibmodule_fptr(char *modname, char *fname)
 ```
-Returns a pointer to the symbol `fname`, defined in module `modname`, or `NULL` if the symbol is not found. 
+Returns a pointer to the symbol `fname`, defined in module `modname`, or `NULL` if the symbol is not found.
 
-[loader home page](../../loader.md)  
-[loader developer home page](../devusage.md)
\ No newline at end of file
+[loader home page](../../loader.md)
+[loader developer home page](../devusage.md)
diff --git a/common/utils/DOC/loader/devusage/loading.md b/common/utils/DOC/loader/devusage/loading.md
index 766bf854620779b9c20d688feb044273850b7b16..b34782ecd3dabbd7fc5f6f9d9c22dcd6197f1bb8 100644
--- a/common/utils/DOC/loader/devusage/loading.md
+++ b/common/utils/DOC/loader/devusage/loading.md
@@ -10,16 +10,16 @@ Typical loader usage looks like:
 /* shared library loader include file */
 #include "common/utils/load_module_shlib.h"
 .............
-/* 
-  define and initialize the array, describing the list of functions 
+/*
+  define and initialize the array, describing the list of functions
   implemented in "mymodule"
 */
   loader_shlibfunc_t mymodule_fdesc[2];
-  mymodule_fdesc[0].fname="mymodule_f1"; 
-  mymodule_fdesc[1].fname="mymodule_f2"; 
+  mymodule_fdesc[0].fname="mymodule_f1";
+  mymodule_fdesc[1].fname="mymodule_f2";
 
 /*
- load the library, it's name must be libmymod.so. Configuration can be 
+ load the library, it's name must be libmymod.so. Configuration can be
  used to specify a specific path to look for libmymod.so. Configuration
  can also specify a version, for example "V1", in this case the loader
  will look for libmymodV1.so
@@ -28,13 +28,13 @@ Typical loader usage looks like:
   if (ret < 0) {
        fprintf(stderr,"Library couldn't be loaded\n");
   } else {
-/* 
+/*
 library has been loaded, we probably want to call some functions...
 */
   ret=((funcf1_t)mymodule_fdesc[0].fptr)();
 
 ..................
-/* 
+/*
 later and/or somewhere else in the code you may want to call function "mymodule_f2"
 You can use the loader get_shlibmodule_fptr(char *modname, char *fname) function
 to retrieve the pointer to that function
@@ -50,7 +50,7 @@ if (f2 != NULL) {
 }
 ...............
 ```
-When loading a shared library the loader looks for a symbol named `< module name > _autoinit` and, if it finds it, calls it. The `autoinit` function is called without any argument and the returned value, if any, is not tested. 
+When loading a shared library the loader looks for a symbol named `< module name > _autoinit` and, if it finds it, calls it. The `autoinit` function is called without any argument and the returned value, if any, is not tested.
 
-[loader home page](../loader.md)  
-[loader developer home page](../../loader/devusage.md)
\ No newline at end of file
+[loader home page](../loader.md)
+[loader developer home page](../../loader/devusage.md)
diff --git a/common/utils/DOC/loader/devusage/struct.md b/common/utils/DOC/loader/devusage/struct.md
index 17504f3866fd8ebef73454c9d9c7b21841084fe2..08d4ce955893d23d6b5ef6594e81d8c2bc16ad1e 100644
--- a/common/utils/DOC/loader/devusage/struct.md
+++ b/common/utils/DOC/loader/devusage/struct.md
@@ -6,5 +6,5 @@ It is defined in include file [ common/util/load_module_shlib.h ](https://gitlab
 | `fname`    | symbol name, is passed to the [`dlsym`](http://man7.org/linux/man-pages/man3/dlsym.3.html) system call performed by the loader to get a pointer to the symbol | I |
 | `fptr`     | pointer to the symbol name, set by the loader. `fptr` is defined as a `int (*fptr)(void)` function type | O |
 
-[loader home page](../../loader.md)  
-[loader developer home page](../devusage.md)
\ No newline at end of file
+[loader home page](../../loader.md)
+[loader developer home page](../devusage.md)
diff --git a/common/utils/DOC/loader/rtusage.md b/common/utils/DOC/loader/rtusage.md
index bf87316e13483fc7d42f47b16ed2f165878a2a34..0bcdf6429f7a830bd7f64f7be021578408cf87a4 100644
--- a/common/utils/DOC/loader/rtusage.md
+++ b/common/utils/DOC/loader/rtusage.md
@@ -6,7 +6,7 @@ Shared library full names are built by the loader using the format:
 1.  the < *module version* > and < *path* > optional  parameters, are defined at run-time, depending on the configuration.
 
 ## loader parameters
-The loader is using the [configuration module](../../../config/DOC/config.md), and defines global and per library parameters. Global parameters must be specified under the **loader** section and library specific parameters under a **loader.<*module name*>** section. Module specific parameters override the global parameters. 
+The loader is using the [configuration module](../../../config/DOC/config.md), and defines global and per library parameters. Global parameters must be specified under the **loader** section and library specific parameters under a **loader.<*module name*>** section. Module specific parameters override the global parameters.
 ### Global loader parameters
 | name | type | default | description |
 |:---:|:---:|:---:|:----|
@@ -39,7 +39,7 @@ If you want to load a device called *liboai_device_USRP.so* without writting a s
 
 With this latest example, nn the softmodem logs, you can check that the right device library has been loaded:
 ```bash
-[LIBCONFIG] loader.oai_device.shlibpath not found in /usr/local/oai/develop-nb-iot-merge/openairinterface5g/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.nbiot.band7.tm1.50PRB.usrpb210.conf 
+[LIBCONFIG] loader.oai_device.shlibpath not found in /usr/local/oai/develop-nb-iot-merge/openairinterface5g/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.nbiot.band7.tm1.50PRB.usrpb210.conf
 [LIBCONFIG] loader.oai_device.shlibversion set to default value ""
 [LIBCONFIG] loader.oai_device: 1/2 parameters successfully set, (1 to default value)
 [CONFIG] shlibversion set to  _USRP from command line
@@ -47,4 +47,4 @@ With this latest example, nn the softmodem logs, you can check that the right de
 
 ```
 
-[loader home page](../loader.md)
\ No newline at end of file
+[loader home page](../loader.md)
diff --git a/common/utils/LOG/DOC/addconsoletrace.md b/common/utils/LOG/DOC/addconsoletrace.md
index d850ac1036c110f9f282c016bc9aae372819a013..9ab90cf12009e8de2bc2a5885f34dd67c4708295 100644
--- a/common/utils/LOG/DOC/addconsoletrace.md
+++ b/common/utils/LOG/DOC/addconsoletrace.md
@@ -12,11 +12,11 @@ these macros are used in place of the printf C function. The additionnal ***comp
 
 | macro | level letter | level value | level name |
 |:---------|:---------------|:---------------|----------------:|
-| LOG_E |  E | 0 | error | 
+| LOG_E |  E | 0 | error |
 | LOG_W | W | 1 | warning |
 | LOG_I | I | 2 | informational |
 | LOG_D | D | 3 | debug |
-| LOG_T | T | 4 | trace |  
+| LOG_T | T | 4 | trace |
 
 component list is defined as an `enum` in  [log.h](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/common/utils/LOG/log.h). A new component can be defined by adding an item in this type, it must also be defined in the T tracer [T_messages.txt ](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/common/utils/T/T_messages.txt).
 
@@ -27,18 +27,18 @@ Most oai sources are including LOG macros.
 ```C
 LOG_DEBUGFLAG(<flag>)
 ```
-this macro is to be used in if statements. The condition is true if the flag has been set, as described in the [run time usage page](rtusage.md) 
+this macro is to be used in if statements. The condition is true if the flag has been set, as described in the [run time usage page](rtusage.md)
 ```C
 if ( LOG_DEBUGFLAG(<flag>) {
-/* 
+/*
    the code below is only executed if the corresponding
    <flag>_debug option is set.
- */ 
+ */
 ......................
 ......................
 }
 ```
-[example in oai code](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/openair1/PHY/LTE_TRANSPORT/ulsch_demodulation.c#L396) 
+[example in oai code](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/openair1/PHY/LTE_TRANSPORT/ulsch_demodulation.c#L396)
 
 #### memory dump macros
 ```C
@@ -47,16 +47,16 @@ LOG_DUMPFLAG(<flag>)
 this macro is to be used in if statements. The condition is true if the flag has been set, as described in the [run time usage page](rtusage.md). It is mainly provided to surround LOG_M macros or direct calls to `log_dump`which otherwise would be unconditionals.
 ```C
 if ( LOG_DUMPFLAG(<flag>) {
-/* 
+/*
    the code below is only executed if the corresponding
    <flag>_dump option is set.
- */ 
+ */
 LOG_M(.............
 LOG_M(.............
 log_dump(...
 }
 
-[example in oai code](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/openair1/PHY/LTE_TRANSPORT/prach.c#L205) 
+[example in oai code](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/openair1/PHY/LTE_TRANSPORT/prach.c#L205)
 #### matlab format dump
 ```C
 LOG_M(file, vector, data, len, dec, format)
@@ -71,13 +71,13 @@ LOG_M(file, vector, data, len, dec, format)
 |format| int | defines the type of data to be dumped|
 
 This macro can be used to dump a buffer in a format that can be used for analyze via tools like matlab or octave. **It must be surrounded by LOG_DEBUGFLAG or LOG_DUMPFLAG macros, to prevent the dump to be built unconditionally.** The LOG_M macro points to the `write_file_matlab` function implemented in  [log.c](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/common/utils/LOG/log.c). **This function should be revisited for more understandable implementation and ease of use (format parameter ???)**
-[example in oai code](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/openair1/PHY/LTE_TRANSPORT/prach.c#L205) 
+[example in oai code](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/openair1/PHY/LTE_TRANSPORT/prach.c#L205)
 
 #### hexadecimal format dump
 ```C
 LOG_DUMPMSG(c, f, b, s, x...)
 ```
-dumps a memory region if the corresponding debug flag `f` is set as explained here [run time usage page](rtusage.md) 
+dumps a memory region if the corresponding debug flag `f` is set as explained here [run time usage page](rtusage.md)
 
 |argument| type| description |
 |:-----------|:-------|-----------------:|
@@ -88,12 +88,12 @@ dumps a memory region if the corresponding debug flag `f` is set as explained he
 | x...| printf format and arguments| text string to be printed at the top of the dump|
 
 This macro can be used to conditionaly dump a buffer, bytes by bytes, giving the integer value of each byte in hexadecimal form.
-[example in oai code](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/openair2/RRC/LTE/rrc_eNB.c#L1181) 
+[example in oai code](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/openair2/RRC/LTE/rrc_eNB.c#L1181)
 
 This macro points to the `log_dump` function, implemented in  [log.c](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/common/utils/LOG/log.c). This function can also dump buffers containing `double` data via the LOG_UDUMPMSG macro
 
 ```C
-LOG_UDUMPMSG(c, b, s, f, x...) 
+LOG_UDUMPMSG(c, b, s, f, x...)
 ```
 |argument| type| description |
 |:-----------|:-------|-----------------:|
@@ -103,8 +103,8 @@ LOG_UDUMPMSG(c, b, s, f, x...)
 |f|  int | format of dumped data LOG_DUMP_CHAR or  LOG_DUMP_DOUBLE|
 | x...| printf format and arguments| text string to be printed at the top of the dump|
 
-[example in oai code](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/openair1/SIMULATION/LTE_PHY/dlsim.c#L1974) 
+[example in oai code](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/openair1/SIMULATION/LTE_PHY/dlsim.c#L1974)
 
-[logging facility developer main page](devusage.md)  
-[logging facility  main page](log.md)  
-[oai Wikis home](https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/home)
\ No newline at end of file
+[logging facility developer main page](devusage.md)
+[logging facility  main page](log.md)
+[oai Wikis home](https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/home)
diff --git a/common/utils/LOG/DOC/arch.md b/common/utils/LOG/DOC/arch.md
index b9302927be83f5458d34fbd4c728c28fc9bb0096..1d6aeae6aa1b963c88a4c0164592e75c5806b978 100644
--- a/common/utils/LOG/DOC/arch.md
+++ b/common/utils/LOG/DOC/arch.md
@@ -2,11 +2,11 @@
 
 The oai logging facility is implemented in two source files, located in [common/utils/LOG](LOG)
 1. [log.c](../log.c) contains logging implementation
-1.  [log.h](../log.h) is the logging facility include file containing both private and public data type definitions. It also contain API prototypes.  
+1.  [log.h](../log.h) is the logging facility include file containing both private and public data type definitions. It also contain API prototypes.
 
 The logging facility doesn't create any thread, all api's are executed in the context of the caller. The tracing macro's `LOG_<X>` are all using the logRecord_mt function to output the messages. To keep this function thread safe it must perform a single system call to the output stream. The buffer used to build the message must be specific to the calling thread, which is today enforced by using a variable in the logRecord_mt stack.
 
 Data used by the logging utility are defined by the `log_t` structure which is allocated at init time, when calling the `logInit` function.
 
-[logging facility  main page](log.md)  
-[oai Wikis home](https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/home)
\ No newline at end of file
+[logging facility  main page](log.md)
+[oai Wikis home](https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/home)
diff --git a/common/utils/LOG/DOC/configurelog.md b/common/utils/LOG/DOC/configurelog.md
index c671c043bd30d5ae13c82d445998edfb0e00b4e4..862c02162b1d516d5f74fba0619457bb68f4675a 100644
--- a/common/utils/LOG/DOC/configurelog.md
+++ b/common/utils/LOG/DOC/configurelog.md
@@ -4,7 +4,7 @@
 ```C
 int  logInit (void);
 ```
-Allocate the internal data used by the logging utility, set the configuration, using the [configuration  module](../../../config/DOC/config.md) 
+Allocate the internal data used by the logging utility, set the configuration, using the [configuration  module](../../../config/DOC/config.md)
 
 ```C
 void logClean (void)
@@ -30,9 +30,9 @@ void close_component_filelog(int comp)
 Redirect or reset to stdout the output stream used by the logging facility. When the output stream is redirected to a file, it is created under /tmp with a hard-coded filename including the componemt name.
 
 ```C
-SET_LOG_DEBUG(flag) 
+SET_LOG_DEBUG(flag)
 CLEAR_LOG_DEBUG(flag)
-SET_LOG_DUMP(flag) 
+SET_LOG_DUMP(flag)
 CLEAR_LOG_DUMP(flag)
 ```
  These macros are used to set or clear the corresponding bit flag, trigerring the activation or un-activation of conditional code or memory dumps generation.
@@ -42,8 +42,8 @@ Example of using the logging utility APIs can be found, for initialization and c
 #### components and debug flags definitions
 
 Adding a new component is just adding an item in the `comp_name_t` enum defined in [log.h](../log.h) . You must also declare it in the T Tracer facility [message fefinitions](../../T/T_messages.txt).
-To add a flag than can then be used for adding conditional code or memory dumps you have to add the flag definition in the `LOG_MASKMAP_INIT` macro, in [log.h](../log.h). 
+To add a flag than can then be used for adding conditional code or memory dumps you have to add the flag definition in the `LOG_MASKMAP_INIT` macro, in [log.h](../log.h).
 
-[logging facility developer main page](devusage.md)  
-[logging facility  main page](log.md)  
-[oai Wikis home](https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/home)
\ No newline at end of file
+[logging facility developer main page](devusage.md)
+[logging facility  main page](log.md)
+[oai Wikis home](https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/home)
diff --git a/common/utils/LOG/DOC/devusage.md b/common/utils/LOG/DOC/devusage.md
index d7790917fc942f03b17ab891ca58a8beb44c7f29..61d25734e0a82733bd51116374f5453f1da4ccb4 100644
--- a/common/utils/LOG/DOC/devusage.md
+++ b/common/utils/LOG/DOC/devusage.md
@@ -1,14 +1,14 @@
 ### logging facility developer usage
-The logging facility objectives are 
-1. provide a common console tracing mechanism 
+The logging facility objectives are
+1. provide a common console tracing mechanism
 1. Allow a flexible activation of console traces, by configuration or dynamically at any time while code is running.
 
-Most developpers will only use the log macros to add console messages to the code. The logging facility also provides an api that is used for initialization and configuration. 
+Most developpers will only use the log macros to add console messages to the code. The logging facility also provides an api that is used for initialization and configuration.
 
-[Adding console traces in oaicode](addconsoletrace.md) 
+[Adding console traces in oaicode](addconsoletrace.md)
 
-[Configuring the logging facility](configurelog.md) 
+[Configuring the logging facility](configurelog.md)
 
 
-[logging facility  main page](log.md)  
+[logging facility  main page](log.md)
 [oai Wikis home](https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/home)
diff --git a/common/utils/LOG/DOC/log.md b/common/utils/LOG/DOC/log.md
index 121e227f3d92233e021941f5e9c1ca0f1cdab204..4b3e5981e1da3b4205bdc7f126fd92773d65730f 100644
--- a/common/utils/LOG/DOC/log.md
+++ b/common/utils/LOG/DOC/log.md
@@ -1,6 +1,6 @@
 # OAI console logging facility
 
-oai includes a console logging facility that any component should use when writting informational or debugging messages to the softmodem or uesoftmodem stdout stream. 
+oai includes a console logging facility that any component should use when writting informational or debugging messages to the softmodem or uesoftmodem stdout stream.
 By default, this facility is included at build-time and activated at run-time. The T Tracer and the Logging facility share common options for activation:
 
 -   To disable the logging facility (and T Tracer) at build-time use the *--disable-T-Tracer* switch:
diff --git a/common/utils/LOG/DOC/rtusage.md b/common/utils/LOG/DOC/rtusage.md
index 60835bafaf1edfaff43e76e739fa6dab5cedbb4b..445f335725c57fcc3675b9df0a608b8e2f3cab90 100644
--- a/common/utils/LOG/DOC/rtusage.md
+++ b/common/utils/LOG/DOC/rtusage.md
@@ -1,5 +1,5 @@
 ## configuring the logging facility
-The logging facility is fully configurable and it uses the [config module](../../../config/config.md) to get its parameters at init time. The [telnet server](../../telnetsrv/DOC/telnetsrv.md) includes a set of commands which can be used to dynamically modify the logging facility behavior 
+The logging facility is fully configurable and it uses the [config module](../../../config/config.md) to get its parameters at init time. The [telnet server](../../telnetsrv/DOC/telnetsrv.md) includes a set of commands which can be used to dynamically modify the logging facility behavior
 
 All logging facility parameters are defined in the log_config section. Some parameters are global to the logging facility, they modify the way messages are printed to stdout. Conversely, some parameters are specific to a component and  only modify the behavior for messages issued by a given component. A third type of parameters can be used to activate conditional debug code or dump messages or buffers.
 
@@ -14,7 +14,7 @@ All logging facility parameters are defined in the log_config section. Some para
 ### Component specific parameters
 | name | type | default | description |
 |:---:|:---:|:---:|:----|
-| `<component>_log_level` | `boolean` | global log level, as defined by the  `global_log_level ` parameter) | 
+| `<component>_log_level` | `boolean` | global log level, as defined by the  `global_log_level ` parameter) |
 | `<component>_log_infile` | `boolean` | 0 = false| Triggers the redirection of log messages printed by the specified component in a file. The file path and name is /tmp/<componemt>.[extension] the extension is optional and component dependant, it can be `log `,  `dat `,  `txt `|
 
 The list of components defined within oai can be retrieved from the  [config module](../../../config/config.md) traces, when asking for config module debugging info on the command line:
@@ -215,7 +215,7 @@ The list of components defined within oai can be retrieved from the  [config mod
 log init done
 
 ```
-It can also be retrieved when using the telnet server, as explained  [below](### Using the telnet server to configure the logging facility) 
+It can also be retrieved when using the telnet server, as explained  [below](### Using the telnet server to configure the logging facility)
 
 ### parameters to activate conditional code
 | name | type | default | description |
@@ -238,15 +238,15 @@ The following example sets all components log level to info, exept for hw,phy,ma
    };
 ```
 ### Using the command line to configure the logging facility
-Command line parameter values supersedes values specified in the configuration file. 
+Command line parameter values supersedes values specified in the configuration file.
 ```bash
-./lte-softmodem -O --log_config.global_log_options nocolor,level,thread  --log_config.prach_log_level debug --log_config.PRACH_debug 
+./lte-softmodem -O --log_config.global_log_options nocolor,level,thread  --log_config.prach_log_level debug --log_config.PRACH_debug
 ```
 In this example to get all the debug PRACH messages it is necessary to also set the PRACH_debug flag. This is a choice from the developper.
 The log messages will be printed whithout color and the header will include the lmessage evel and the thread name:
 ```bash
-[PHY]I ru thread Time in secs now: 104652566 
-[PHY]I ru thread Time in secs last pps: 91827117 
+[PHY]I ru thread Time in secs now: 104652566
+[PHY]I ru thread Time in secs last pps: 91827117
 [PHY]I ru thread RU 0 rf device ready
 [PHY]I ru thread RU 0 no asynch_south interface
 [MAC]E rxtx processing SCHED_MODE=0
@@ -256,10 +256,10 @@ The log messages will be printed whithout color and the header will include the
 [PHY]I lte-softmodem PRACH (eNB) : running rx_prach for subframe 1, prach_FreqOffset 2, prach_ConfigIndex 0 , rootSequenceIndex 0
 [PHY]I lte-softmodem PRACH (eNB) : running rx_prach for subframe 1, prach_FreqOffset 2, prach_ConfigIndex 0 , rootSequenceIndex 0
 ```
- 
+
 ### Using the telnet server to configure the logging facility
 The telnet server includes a `log` command which can be used to dymically modify the logging facility configuration parameters.
-[telnet server ***softmodem log*** commands](../../telnetsrv/DOC/telnetlog.md) 
+[telnet server ***softmodem log*** commands](../../telnetsrv/DOC/telnetlog.md)
 
-[logging facility  main page](log.md)  
+[logging facility  main page](log.md)
 [oai Wikis home](https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/home)
diff --git a/common/utils/LOG/log.c b/common/utils/LOG/log.c
index 98987ca66e6ea84e451618e4556f29414a2f327b..87150650db697c5f3c6e2127c125039f6a0e3269 100644
--- a/common/utils/LOG/log.c
+++ b/common/utils/LOG/log.c
@@ -393,15 +393,18 @@ int logInit (void) {
   register_log_component("mRAL","",RAL_UE);
   register_log_component("ENB_APP","log",ENB_APP);
   register_log_component("FLEXRAN_AGENT","log",FLEXRAN_AGENT);
+  register_log_component("PROTO_AGENT","log",PROTO_AGENT);
   register_log_component("TMR","",TMR);
   register_log_component("USIM","txt",USIM);
   register_log_component("SIM","txt",SIM);
   /* following log component are used for the localization*/
+  /* following log component are used for the localization*/
   register_log_component("LOCALIZE","log",LOCALIZE);
   register_log_component("NAS","log",NAS);
   register_log_component("UDP","",UDP_);
   register_log_component("GTPV1U","",GTPU);
   register_log_component("S1AP","",S1AP);
+  register_log_component("F1AP","",F1AP);
   register_log_component("X2AP","",X2AP);
   register_log_component("SCTP","",SCTP);
   register_log_component("X2AP","",X2AP);
diff --git a/common/utils/LOG/log.h b/common/utils/LOG/log.h
index 1ecb68732a2a021ccdfc9b6c67cb0a94e3aeb7f6..dea756a3acf58618aaa2c53cc041b83f53c1b6a5 100644
--- a/common/utils/LOG/log.h
+++ b/common/utils/LOG/log.h
@@ -204,6 +204,7 @@ typedef enum {
   GTPU,
   SPGW,
   S1AP,
+  F1AP,
   SCTP,
   HW,
   OSA,
@@ -214,6 +215,8 @@ typedef enum {
   TMR,
   USIM,
   LOCALIZE,
+  PROTO_AGENT,
+  F1U,
   X2AP,
   LOADER,
   ASN,
diff --git a/common/utils/T/T_messages.txt b/common/utils/T/T_messages.txt
index 7fa24f5535804ddb0a27d7d279fe93af8c113d7a..1dbfe64a2ae8f583e3765fcc18094c7190d42b4a 100644
--- a/common/utils/T/T_messages.txt
+++ b/common/utils/T/T_messages.txt
@@ -629,7 +629,7 @@ ID = LEGACY_OCM_DEBUG
     FORMAT = string,log
 ID = LEGACY_OCM_TRACE
     DESC = OCM legacy logs - trace level
-    GROUP = ALL:LEGACY_OCM:LEGACY_GROUP_TRACE:LEGACY
+    OGROUP = ALL:LEGACY_OCM:LEGACY_GROUP_TRACE:LEGACY
     FORMAT = string,log
 
 ID = LEGACY_OIP_INFO
@@ -888,6 +888,62 @@ ID = LEGACY_componentP_TRACE
 
 
 
+ID = LEGACY_PROTO_AGENT_DEBUG
+    DESC = PROTO AGENT DEBUG LEVEL
+    GROUP = ALL:LEGACY_PROTO:LEGACY_GROUP_DEBUG:LEGACY
+    FORMAT = string,log
+
+ID = LEGACY_PROTO_AGENT_INFO
+    DESC = PROTO AGENT INFO LEVEL
+    GROUP = ALL:LEGACY_PROTO:LEGACY_GROUP_INFO:LEGACY
+    FORMAT = string,log
+
+ID = LEGACY_PROTO_AGENT_WARNING
+    DESC = PROTO AGENT WARNING LEVEL
+    GROUP = ALL:LEGACY_PROTO:LEGACY_GROUP_WARNING:LEGACY
+    FORMAT = string,log
+
+ID = LEGACY_PROTO_AGENT_ERROR
+    DESC = PROTO AGENT ERROR LEVEL
+    GROUP = ALL:LEGACY_PROTO:LEGACY_GROUP_ERROR:LEGACY
+    FORMAT = string,log
+
+ID = LEGACY_F1U_DEBUG
+    DESC = F1U DEBUG LEVEL
+    GROUP = ALL:LEGACY_F1U:LEGACY_GROUP_DEBUG:LEGACY
+    FORMAT = string,log
+
+ID = LEGACY_F1U_INFO
+    DESC = F1U INFO LEVEL
+    GROUP = ALL:LEGACY_F1U:LEGACY_GROUP_INFO:LEGACY
+    FORMAT = string,log
+
+ID = LEGACY_F1U_ERROR
+    DESC = F1U ERROR LEVEL
+    GROUP = ALL:LEGACY_F1U:LEGACY_GROUP_ERROR:LEGACY
+    FORMAT = string,log
+
+ID = LEGACY_F1AP_TRACE
+    DESC = F1AP TRACE LEVEL
+    GROUP = ALL:LEGACY_F1AP:LEGACY_GROUP_TRACE:LEGACY
+    FORMAT = string,log
+ID = LEGACY_F1AP_DEBUG
+    DESC = F1AP DEBUG LEVEL
+    GROUP = ALL:LEGACY_F1AP:LEGACY_GROUP_DEBUG:LEGACY
+    FORMAT = string,log
+ID = LEGACY_F1AP_INFO
+    DESC = F1AP INFO LEVEL
+    GROUP = ALL:LEGACY_F1AP:LEGACY_GROUP_INFO:LEGACY
+    FORMAT = string,log
+ID = LEGACY_F1AP_WARNING
+    DESC = F1AP WARNING LEVEL
+    GROUP = ALL:LEGACY_F1AP:LEGACY_GROUP_WARNING:LEGACY
+    FORMAT = string,log
+ID = LEGACY_F1AP_ERROR
+    DESC = F1AP ERROR LEVEL
+    GROUP = ALL:LEGACY_F1AP:LEGACY_GROUP_ERROR:LEGACY
+    FORMAT = string,log
+
 #################
 #### UE LOGS ####
 #################
diff --git a/common/utils/assertions.h b/common/utils/assertions.h
index 77e939affe4b7393aadb286b86c8b8551cc5d25f..97f186627488de5f14c5660a4c40884f157876ec 100644
--- a/common/utils/assertions.h
+++ b/common/utils/assertions.h
@@ -35,13 +35,11 @@
 
 void output_log_mem(void);
 #define _Assert_Exit_                           \
-{                                               \
     fprintf(stderr, "\nExiting execution\n");   \
     display_backtrace();                        \
     fflush(stdout);                             \
     fflush(stderr);                             \
     exit(EXIT_FAILURE);                         \
-}
 
 #define _Assert_(cOND, aCTION, fORMAT, aRGS...)             \
 do {                                                        \
diff --git a/common/utils/msc/msc.c b/common/utils/msc/msc.c
index 7cb6da21b513b99f6a9f184131df47c5893812bf..ae87a8e3266f662f5851824aa2e4523488a844d7 100644
--- a/common/utils/msc/msc.c
+++ b/common/utils/msc/msc.c
@@ -150,7 +150,7 @@ int msc_init(const msc_env_t envP, const int max_threadsP)
     pointer_p = malloc(MSC_MAX_MESSAGE_LENGTH);
     AssertFatal (pointer_p, "malloc failed!\n");
     rv = lfds611_stack_guaranteed_push( g_msc_memory_stack_p, pointer_p );
-    AssertFatal (rv, "lfds611_stack_guaranteed_push failed for item %u\n", i);
+    AssertFatal (rv, "lfds611_stack_guaranteed_push failed for item %d\n", i);
   }
 
   for (i = MIN_MSC_PROTOS; i < MAX_MSC_PROTOS; i++) {
@@ -476,7 +476,20 @@ int msc_init(const msc_env_t envP, const int max_threadsP)
         }
 
         break;
-
+      case MSC_F1AP_CU:
+        rv = snprintf(&g_msc_proto2str[i][0], MSC_MAX_PROTO_NAME_LENGTH, "F1AP_CU");
+        if (rv >= MSC_MAX_PROTO_NAME_LENGTH) {g_msc_proto2str[i][MSC_MAX_PROTO_NAME_LENGTH-1] = 0;}
+        //if ((envP == MSC_E_UTRAN) || (envP == MSC_MME_GW)  || (envP == MSC_MME)) {
+          msc_log_declare_proto(i);
+        //}
+        break;
+      case MSC_F1AP_DU:
+        rv = snprintf(&g_msc_proto2str[i][0], MSC_MAX_PROTO_NAME_LENGTH, "F1AP_DU");
+        if (rv >= MSC_MAX_PROTO_NAME_LENGTH) {g_msc_proto2str[i][MSC_MAX_PROTO_NAME_LENGTH-1] = 0;}
+        //if ((envP == MSC_E_UTRAN) || (envP == MSC_MME_GW)  || (envP == MSC_MME)) {
+          msc_log_declare_proto(i);
+        //}
+        break;
       default:
         rv = snprintf(&g_msc_proto2str[i][0], MSC_MAX_PROTO_NAME_LENGTH, "UNKNOWN");
 
diff --git a/common/utils/msc/msc.h b/common/utils/msc/msc.h
index 60c483a168e7b6be9788956ecd8da7817bff0e1a..49c99abb56cf12b0bcdc6d1d93683d427cc50fb0 100644
--- a/common/utils/msc/msc.h
+++ b/common/utils/msc/msc.h
@@ -62,6 +62,8 @@ typedef enum {
   MSC_S11_MME,
   MSC_S6A_MME,
   MSC_HSS,
+  MSC_F1AP_CU,
+  MSC_F1AP_DU,
   MSC_X2AP_SRC_ENB,
   MSC_X2AP_TARGET_ENB,
   MAX_MSC_PROTOS,
diff --git a/common/utils/ocp_itti/all_msg.h b/common/utils/ocp_itti/all_msg.h
index f4395724009085aaffd9fa62385f321cb34b10e8..bbbe576e1bf94fb0d5b5cff0d448d2a15bfcfc90 100644
--- a/common/utils/ocp_itti/all_msg.h
+++ b/common/utils/ocp_itti/all_msg.h
@@ -13,3 +13,4 @@
 #include "openair2/COMMON/udp_messages_def.h"
 #include "openair2/COMMON/gtpv1_u_messages_def.h"
 #include "openair2/COMMON/flexran_messages_def.h"
+#include "openair2/COMMON/f1ap_messages_def.h"
diff --git a/common/utils/ocp_itti/intertask_interface.cpp b/common/utils/ocp_itti/intertask_interface.cpp
index 5b8d1a430e02cef93126e71a61f69ae7e6513d94..3d0bd0e1a34024673b8055351c21559ef5e44c2a 100644
--- a/common/utils/ocp_itti/intertask_interface.cpp
+++ b/common/utils/ocp_itti/intertask_interface.cpp
@@ -1,6 +1,6 @@
 /*
   Author: Laurent THOMAS, Open Cells
-  copyleft: OpenAirInterface Software Alliance and it's licence 
+  copyleft: OpenAirInterface Software Alliance and it's licence
 */
 #include <vector>
 #include <map>
@@ -122,7 +122,7 @@ extern "C" {
       pthread_mutex_unlock (&t->queue_cond_lock);
       t->admin.func(NULL);
       pthread_mutex_lock (&t->queue_cond_lock);
-    } 
+    }
     pthread_mutex_unlock (&t->queue_cond_lock);
     return ret;
   }
@@ -290,12 +290,12 @@ extern "C" {
       struct sched_param sparam;
       memset(&sparam, 0, sizeof(sparam));
       sparam.sched_priority = sched_get_priority_max(SCHED_FIFO)-10;
-      policy = SCHED_FIFO ; 
+      policy = SCHED_FIFO ;
       if (pthread_setschedparam(t->thread, policy, &sparam) != 0) {
 	LOG_E(TMR,"task %s : Failed to set pthread priority\n",  itti_get_task_name(task_id) );
       }
     }
-#endif    
+#endif
     return 0;
   }
 
diff --git a/common/utils/ocp_itti/intertask_interface.h b/common/utils/ocp_itti/intertask_interface.h
index 227e9b0b3e702040f97a1477f50dd133b31209c3..159265c6a8241762078665537dd726483afe141a 100644
--- a/common/utils/ocp_itti/intertask_interface.h
+++ b/common/utils/ocp_itti/intertask_interface.h
@@ -1,6 +1,6 @@
 /*
   Author: Laurent THOMAS, Open Cells
-  Copyleft: OpenAirInterface software alliance and it's licence 
+  Copyleft: OpenAirInterface software alliance and it's licence
 */
 #ifndef INTERTASK_INTERFACE_H_
 #define INTERTASK_INTERFACE_H_
@@ -300,6 +300,8 @@ typedef struct {
   TASK_DEF(TASK_MSC,      TASK_PRIORITY_MED,  200, NULL, NULL)\
   TASK_DEF(TASK_GTPV1_U,  TASK_PRIORITY_MED,  1000,NULL, NULL)\
   TASK_DEF(TASK_UDP,      TASK_PRIORITY_MED,  1000, NULL, NULL)\
+  TASK_DEF(TASK_CU_F1,    TASK_PRIORITY_MED,  200, NULL, NULL) \
+  TASK_DEF(TASK_DU_F1,    TASK_PRIORITY_MED,  200, NULL, NULL) \
   TASK_DEF(TASK_MAX,      TASK_PRIORITY_MED,  200, NULL, NULL)
 
 #define TASK_DEF(TaskID, pRIO, qUEUEsIZE, FuNc, ThreadFunc)          { pRIO, qUEUEsIZE, #TaskID, FuNc, ThreadFunc },
diff --git a/common/utils/telnetsrv/DOC/telnetaddcmd.md b/common/utils/telnetsrv/DOC/telnetaddcmd.md
index ef5af3fb7ee34219d9d2d44c197cbcfe0a263824..c7591282549fd30cc51863cbf3ec9b32c63b20b3 100644
--- a/common/utils/telnetsrv/DOC/telnetaddcmd.md
+++ b/common/utils/telnetsrv/DOC/telnetaddcmd.md
@@ -3,15 +3,15 @@
 The following example is extracted from [the oai `openair1/PHY/CODING/coding_load.c` file](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/openair1/PHY/CODING/coding_load.c).
 
 ```c
-/* 
+/*
 include the telnet server data structures and API definitions
 */
-#include "common/utils/telnetsrv/telnetsrv.h" 
+#include "common/utils/telnetsrv/telnetsrv.h"
 
 
 /*
 define the null terminated array of telnetshell_cmddef_t structures
-which map each sub-command string to a function implementing it. 
+which map each sub-command string to a function implementing it.
 you may also provide a help string which will be printed when
 the global help command is used. The prototype for the function
 implementing sub commands must match the `cmdfunc_t` type defined
@@ -25,7 +25,7 @@ static telnetshell_cmddef_t coding_cmdarray[] = {
 
 /*
 define the null terminated list of telnetshell_vardef_t structures defining the
-variables that can be set and get using the pre-defined get and set command 
+variables that can be set and get using the pre-defined get and set command
 of the telnet server
 */
 telnetshell_vardef_t coding_vardef[] = {
@@ -34,7 +34,7 @@ telnetshell_vardef_t coding_vardef[] = {
 };
 .................
 /*
- look for telnet server, if it is loaded, add the coding commands to it 
+ look for telnet server, if it is loaded, add the coding commands to it
  we use the shared library loader API to check the telnet server availibility
 The telnet server TELNET_ADDCMD_FNAME function takes three arguments:
 1.  The name of the telnet command to be added, here "coding"
@@ -43,9 +43,9 @@ The telnet server TELNET_ADDCMD_FNAME function takes three arguments:
 */
      add_telnetcmd_func_t addcmd = (add_telnetcmd_func_t)get_shlibmodule_fptr("telnetsrv", TELNET_ADDCMD_FNAME);
      if (addcmd != NULL) {
-         addcmd("coding",coding_vardef,coding_cmdarray); 
+         addcmd("coding",coding_vardef,coding_cmdarray);
 .......
-/* 
+/*
   functions implementing the "coding mode" sub command, as defined in
   the `coding_cmdarray` passed earlier to the TELNET_ADDCMD_FNAME function.
   This function will be called by the telnet server, when the `coding_cmdarray`
@@ -53,15 +53,15 @@ The telnet server TELNET_ADDCMD_FNAME function takes three arguments:
 */
 int coding_setmod_cmd(char *buff, int debug, telnet_printfunc_t prnt)
 {
-  /* 
+  /*
   1. buff argument is an input argument, pointer to the string received
   from the telnet client, the command and sub-command parts are removed
   In this case it points after "coding setmod" and is of no use as
-  we don't have second level sub-commands.  
+  we don't have second level sub-commands.
   1. debug argument is an input argument set by the telnet server
-  1. prnt arguments is also an input argument, a function pointer, to be used 
+  1. prnt arguments is also an input argument, a function pointer, to be used
   in place of printf to print messages on the telnet client interface. As this function
-  is called by the telnet server stdout points to the main executable console,  
+  is called by the telnet server stdout points to the main executable console,
   */
    if (debug > 0)
        prnt( "coding_setmod_cmd received %s\n",buff);
@@ -89,28 +89,28 @@ int coding_setmod_cmd(char *buff, int debug, telnet_printfunc_t prnt)
 ```c
 int add_telnetcmd(char *modulename, telnetshell_vardef_t *var, telnetshell_cmddef_t *cmd)
 ```
-Add a command and the `cmd` list of sub-commands to the telnet server. After a successful call to `add_telnetcmd` function, the telnet server calls the function defined for each sub-commands in the null terminated `cmd` array, when the character string received from the telnet client matches the command and sub-command strings.  
-Also adds the list of variables described in the `var` array to the list of variable which can be set and read.  
-The function returns -1 if one argument is NULL.  
-The telnet server is dynamically loaded, to use  the `add_telnetcmd` function, the shared library loader API should be used to check the availability of the telnet server and retrieve it's address, as shown in [the example at the top of this page](telnetaddcmd.md#code-example-of-adding-a-command-to-the-telnet-server).  
+Add a command and the `cmd` list of sub-commands to the telnet server. After a successful call to `add_telnetcmd` function, the telnet server calls the function defined for each sub-commands in the null terminated `cmd` array, when the character string received from the telnet client matches the command and sub-command strings.
+Also adds the list of variables described in the `var` array to the list of variable which can be set and read.
+The function returns -1 if one argument is NULL.
+The telnet server is dynamically loaded, to use  the `add_telnetcmd` function, the shared library loader API should be used to check the availability of the telnet server and retrieve it's address, as shown in [the example at the top of this page](telnetaddcmd.md#code-example-of-adding-a-command-to-the-telnet-server).
 
 # telnet server public data types
-## `telnetshell_vardef_t`structure  
+## `telnetshell_vardef_t`structure
  This structure is used by developers to describe the variables that can be set or read using the get,set and getall sub-commands.
 
-| Fields     | type |Description                                                       | 
+| Fields     | type |Description                                                       |
 |:-----------|:------:|:-----------------------|
 | `varname`    | `char[TELNET_CMD_MAXSIZE]`  | variable name, as specified when using the get and set commands. |
 | `vartype`     | `char` |  Defines the type of the variable pointed by the `varvalptr`field. Supported values: TELNET_VARTYPE_INT32  TELNET_VARTYPE_INT16 TELNET_VARTYPE_INT64  TELNET_VARTYPE_STRING   TELNET_VARTYPE_DOUBLE |
 | `varvalptr`     | `void*` |  Defines the type of the variable pointed by the `varvalptr`field |
 
-## `telnetshell_cmddef_t`structure  
+## `telnetshell_cmddef_t`structure
  This structure is used by developers to describe the first level sub-commands to be added to the telnet server.
 
-| Fields     | type |Description                                                       | 
+| Fields     | type |Description                                                       |
 |:-----------|:------:|:-----------------------|
 | `cmdname`    | `char[TELNET_CMD_MAXSIZE]`  | command name, as tested by the telnet server to check it should call the `cmdfunc` function  |
 | `helpstr`     | `char[TELNET_HELPSTR_SIZE]` |  character string to print when the elp`command is received from the telnet client |
 | `cmdfunc`     | `cmdfunc_t` |  pointer to the function implementing the `cmdname` sub command. |
 
-[oai telnet server home](telnetsrv.md)
\ No newline at end of file
+[oai telnet server home](telnetsrv.md)
diff --git a/common/utils/telnetsrv/DOC/telnetarch.md b/common/utils/telnetsrv/DOC/telnetarch.md
index f31a51b352b06bf98961d96fc97b0edf446fd3a5..ebb2342c22304f7c9a08c44880a358e34a187dcd 100644
--- a/common/utils/telnetsrv/DOC/telnetarch.md
+++ b/common/utils/telnetsrv/DOC/telnetarch.md
@@ -4,18 +4,18 @@ The oai telnet server is implemented in a shared library to be loaded by the [oa
 
 Currently the telnet server only supports one user connection. The same dedicated thread is used to wait for a user connection and process the input received from this connection.
 
-The telnet server provides an API which can be used by any oai component to add new CLI commands to the server. A pre-defined  command can be used to get or set a list of variables. 
+The telnet server provides an API which can be used by any oai component to add new CLI commands to the server. A pre-defined  command can be used to get or set a list of variables.
+
 
 
- 
 # telnet server source files
 
 telnet server source files are located in [common/utils/telnetsrv](https://gitlab.eurecom.fr/oai/openairinterface5g/tree/develop/common/utils/telnetsrv)
 
-1. [telnetsrv.c](https://gitlab.eurecom.fr/oai/openairinterface5g/tree/develop/common/utils/telnetsrv/telnetsrv.c) contains the telnet server implementation, including the implementation of the telnet CLI command. 
+1. [telnetsrv.c](https://gitlab.eurecom.fr/oai/openairinterface5g/tree/develop/common/utils/telnetsrv/telnetsrv.c) contains the telnet server implementation, including the implementation of the telnet CLI command.
 1.  [telnetsrv.h](https://gitlab.eurecom.fr/oai/openairinterface5g/tree/develop/common/utils/telnetsrv/telnetsrv.h) is the telnet server include file containing both private and public data type definitions. It also contains API prototypes for functions that are used to register a new command in the server.
 1.  `telnetsrv\_\<XXX\>.c`: implementation of \<XXX\> CLI command which are delivered with the telnet server.
 1.  `telnetsrv\_\<XXX\>.h`: include file for the implementation of XXX CLI command. Usually included only in the corresponding `.c`file
 1.  [telnetsrv_CMakeLists.txt](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/common/utils/telnetsrv/telnetsrv_CMakeLists.txt): CMakelists file containing the cmake instructions to build the telnet server. this file is included in the [global oai CMakelists](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/cmake_targets/CMakeLists.txt).
 
-[oai telnet server home](telnetsrv.md)
\ No newline at end of file
+[oai telnet server home](telnetsrv.md)
diff --git a/common/utils/telnetsrv/DOC/telnetgetset.md b/common/utils/telnetsrv/DOC/telnetgetset.md
index e0b2c90d79cd787f3316611d2c7bc7d250b4e59b..d851e90a8fdaec05fbde85e03413c6c9288f3a75 100644
--- a/common/utils/telnetsrv/DOC/telnetgetset.md
+++ b/common/utils/telnetsrv/DOC/telnetgetset.md
@@ -10,12 +10,12 @@ telnet, phypb = 65000
 telnet, hsize = 50
 telnet, hfile = "oaitelnet.history"
 softmodem> telnet set loopc 100
-telnet, loopc set to 
+telnet, loopc set to
 100
 softmodem> telnet get loopc
 telnet, loopc = 100
-softmodem> 
+softmodem>
 
 ```
-[oai telnetserver home](telnetsrv.md)  
-[oai telnetserver usage home](telnetusage.md)
\ No newline at end of file
+[oai telnetserver home](telnetsrv.md)
+[oai telnetserver usage home](telnetusage.md)
diff --git a/common/utils/telnetsrv/DOC/telnethelp.md b/common/utils/telnetsrv/DOC/telnethelp.md
index 63183fb61189430149b6e4faac78f303090abd48..b18f5caae7b528898e2ba23f25dc7547af95a8c5 100644
--- a/common/utils/telnetsrv/DOC/telnethelp.md
+++ b/common/utils/telnetsrv/DOC/telnethelp.md
@@ -22,7 +22,7 @@ softmodem> help
       softmodem show loglvl|thread|config
       softmodem log (enter help for details)
       softmodem thread (enter help for details)
-      softmodem exit 
+      softmodem exit
    module 2 = phy:
       phy disp [phycnt,uedump,uestat UE<x>]
    module 3 = loader:
@@ -34,24 +34,24 @@ softmodem> help
    module 4 = coding:
       coding [get set] maxiter <value>
       coding mode [sse,avx2,stdc,none]
-softmodem> 
-```  
+softmodem>
+```
 
-# oai telnet server, specific commands help  
+# oai telnet server, specific commands help
 
 ``` bash
 softmodem> softmodem log help
- log sub commands: 
- show:  		     display current log configuration 
- online, noonline:	     enable or disable console logs 
- enable, disable id1-id2:    enable or disable logs for components index id1 to id2 
- level_<level> id1-id2:      set log level to <level> for components index id1 to id2 
- level_<verbosity> id1-id2:  set log verbosity to <verbosity> for components index id1 to id2 
-use the show command to get the values for <level>, <verbosity> and the list of component indexes that can be used for id1 and id2 
+ log sub commands:
+ show:  		     display current log configuration
+ online, noonline:	     enable or disable console logs
+ enable, disable id1-id2:    enable or disable logs for components index id1 to id2
+ level_<level> id1-id2:      set log level to <level> for components index id1 to id2
+ level_<verbosity> id1-id2:  set log verbosity to <verbosity> for components index id1 to id2
+use the show command to get the values for <level>, <verbosity> and the list of component indexes that can be used for id1 and id2
 softmodem>
 
 
 ```
 
-[oai telnetserver home](telnetsrv.md)  
-[oai telnetserver usage home](telnetusage.md)
\ No newline at end of file
+[oai telnetserver home](telnetsrv.md)
+[oai telnetserver usage home](telnetusage.md)
diff --git a/common/utils/telnetsrv/DOC/telnethist.md b/common/utils/telnetsrv/DOC/telnethist.md
index d938435a2405c474fc29ee6b2459f5843b7e5086..b7cf152502802be199a66391e85485819b4ef46c 100644
--- a/common/utils/telnetsrv/DOC/telnethist.md
+++ b/common/utils/telnetsrv/DOC/telnethist.md
@@ -40,5 +40,5 @@ softmodem>
 
 ```
 
-[oai telnetserver home](telnetsrv.md)  
-[oai telnetserver usage home](telnetusage.md)
\ No newline at end of file
+[oai telnetserver home](telnetsrv.md)
+[oai telnetserver usage home](telnetusage.md)
diff --git a/common/utils/telnetsrv/DOC/telnetloader.md b/common/utils/telnetsrv/DOC/telnetloader.md
index 9250524989a67da5ea8a22108b3aeb7f86cd77a6..d6a0f158c6fcd9bef3bd6fdc5979042ee730f660 100644
--- a/common/utils/telnetsrv/DOC/telnetloader.md
+++ b/common/utils/telnetsrv/DOC/telnetloader.md
@@ -43,5 +43,5 @@ softmodem> loader show modules
 softmodem>
 ```
 
-[oai telnetserver home](telnetsrv.md)  
-[oai telnetserver usage home](telnetusage.md)
\ No newline at end of file
+[oai telnetserver home](telnetsrv.md)
+[oai telnetserver usage home](telnetusage.md)
diff --git a/common/utils/telnetsrv/DOC/telnetlog.md b/common/utils/telnetsrv/DOC/telnetlog.md
index 0faaf9c02e25791a9c4850ad4ad5e33b27e6fa7e..36c5cfb3486d5ff79efebb8921860ed4f185d1a3 100644
--- a/common/utils/telnetsrv/DOC/telnetlog.md
+++ b/common/utils/telnetsrv/DOC/telnetlog.md
@@ -38,10 +38,10 @@ log level/verbosity  comp 33 USIM set to info / medium (disabled)
 log level/verbosity  comp 34 LOCALIZE set to info / medium (disabled)
 log level/verbosity  comp 35 RRH set to info / medium (disabled)
 softmodem> softmodem log show
-Available log levels: 
-   emerg alert crit error warn notice info debug file trace 
-Available verbosity: 
-   none low medium high full 
+Available log levels:
+   emerg alert crit error warn notice info debug file trace
+Available verbosity:
+   none low medium high full
 component                 verbosity  level  enabled
 00               PHY:    medium      info  N
 01               MAC:    medium      info  N
@@ -89,8 +89,8 @@ log level/verbosity  comp 3 OCG set to error / medium (enabled)
 log level/verbosity  comp 4 OMG set to error / medium (enabled)
 softmodem> exit
 Connection closed by foreign host.
-```  
+```
 
-[oai telnetserver home](telnetsrv.md)  
+[oai telnetserver home](telnetsrv.md)
 [oai telnetserver usage home](telnetusage.md)
-[oai Wikis home](https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/home)
\ No newline at end of file
+[oai Wikis home](https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/home)
diff --git a/common/utils/telnetsrv/DOC/telnetloop.md b/common/utils/telnetsrv/DOC/telnetloop.md
index f045e8a7161d150edad0b58f798f64e1ff2cf176..a86baad6eb547dd24c4e1dbc029ffb8cf4cf4032 100644
--- a/common/utils/telnetsrv/DOC/telnetloop.md
+++ b/common/utils/telnetsrv/DOC/telnetloop.md
@@ -1,4 +1,4 @@
-The telnet server includes a **_loop_** command that can be used to iterate a given command. The number of iterations and the delay, in ms between two iterations can be modified, as shown in the following example:  
+The telnet server includes a **_loop_** command that can be used to iterate a given command. The number of iterations and the delay, in ms between two iterations can be modified, as shown in the following example:
 
 ```bash
 softmodem> telnet get loopc
@@ -6,35 +6,35 @@ telnet, loopc = 10
 softmodem> telnet get loopd
 telnet, loopd = 2000
 softmodem> telnet set loopd 1000
-telnet, loopd set to 
+telnet, loopd set to
 1000
 softmodem> loop softmodem show thread
                   2018-03-27 17:58:49.000 2/10
-  id          name            state   USRmod    KRNmod  prio nice   vsize   proc pol 
+  id          name            state   USRmod    KRNmod  prio nice   vsize   proc pol
 
-     3946        lte-softmodem   S       20005      9440  20   0 236560384   2    0 other 
+     3946        lte-softmodem   S       20005      9440  20   0 236560384   2    0 other
 
-     3946        lte-softmodem   S           7        95  20   0 236560384   2    0 other 
-     3948               telnet   R           0         0  20   0 236560384   2    0 other 
-     3949        ITTI acceptor   S           2         9  20   0 236560384   2    0 other 
-     3951              ITTI 12   S           2         2  20   0 236560384   7    0 other 
-     3952              ITTI 11   S           0         0  20   0 236560384   0    0 other 
-     3953               ITTI 9   S           0         0  20   0 236560384   1    0 other 
-     3954               ITTI 7   S           0         0  20   0 236560384   7    0 other 
-     3955               ITTI 8   S           0         0  20   0 236560384   7    0 other 
-     3956               ITTI 4   S          35         0  20   0 236560384   2    0 other 
-     3957            ru_thread   S       15366      3072 -10   0 236560384   0    2 rt: rr 
-     3958      ru_thread_prach   S           0         0 -10   0 236560384   7    1 rt: fifo 
-     3959           fep_thread   S        1874       123 -10   0 236560384   5    1 rt: fifo 
-     3960         feptx_thread   S        1554       101 -10   0 236560384   7    1 rt: fifo 
-     3969            ru_thread   S           0         0 -10   0 236560384   0    2 rt: rr 
-     3970            ru_thread   S        1313      5522 -10   0 236560384   5    2 rt: rr 
-     3971            ru_thread   S           4         6 -10   0 236560384   1    2 rt: rr 
-     3972        lte-softmodem   S         318         9 -10   0 236560384   7    1 rt: fifo 
-     3973        lte-softmodem   S           6        13 -10   0 236560384   4    1 rt: fifo 
+     3946        lte-softmodem   S           7        95  20   0 236560384   2    0 other
+     3948               telnet   R           0         0  20   0 236560384   2    0 other
+     3949        ITTI acceptor   S           2         9  20   0 236560384   2    0 other
+     3951              ITTI 12   S           2         2  20   0 236560384   7    0 other
+     3952              ITTI 11   S           0         0  20   0 236560384   0    0 other
+     3953               ITTI 9   S           0         0  20   0 236560384   1    0 other
+     3954               ITTI 7   S           0         0  20   0 236560384   7    0 other
+     3955               ITTI 8   S           0         0  20   0 236560384   7    0 other
+     3956               ITTI 4   S          35         0  20   0 236560384   2    0 other
+     3957            ru_thread   S       15366      3072 -10   0 236560384   0    2 rt: rr
+     3958      ru_thread_prach   S           0         0 -10   0 236560384   7    1 rt: fifo
+     3959           fep_thread   S        1874       123 -10   0 236560384   5    1 rt: fifo
+     3960         feptx_thread   S        1554       101 -10   0 236560384   7    1 rt: fifo
+     3969            ru_thread   S           0         0 -10   0 236560384   0    2 rt: rr
+     3970            ru_thread   S        1313      5522 -10   0 236560384   5    2 rt: rr
+     3971            ru_thread   S           4         6 -10   0 236560384   1    2 rt: rr
+     3972        lte-softmodem   S         318         9 -10   0 236560384   7    1 rt: fifo
+     3973        lte-softmodem   S           6        13 -10   0 236560384   4    1 rt: fifo
 
-```  
-A **_loop_** command can be interrupted by pressing the  **_enter_** key till getting the  prompt. 
+```
+A **_loop_** command can be interrupted by pressing the  **_enter_** key till getting the  prompt.
 
-[oai telnetserver home](telnetsrv.md)  
-[oai telnetserver usage home](telnetusage.md)
\ No newline at end of file
+[oai telnetserver home](telnetsrv.md)
+[oai telnetserver usage home](telnetusage.md)
diff --git a/common/utils/telnetsrv/DOC/telnetsrv.md b/common/utils/telnetsrv/DOC/telnetsrv.md
index e8909595d9e4c9770690958a119cbbd7de7cc662..11c6cf071fdd1c32b9489487dde1b0e8082f2de4 100644
--- a/common/utils/telnetsrv/DOC/telnetsrv.md
+++ b/common/utils/telnetsrv/DOC/telnetsrv.md
@@ -3,5 +3,5 @@ The oai embedded telnet server is an optional monitoring and debugging tool. It
 * [Using the telnet server](telnetusage.md)
 * [Adding commands to the oai telnet server](telnetaddcmd.md)
 * [telnet server architecture ](telnetarch.md)
- 
-[oai Wikis home](https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/home)
\ No newline at end of file
+
+[oai Wikis home](https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/home)
diff --git a/common/utils/telnetsrv/DOC/telnetusage.md b/common/utils/telnetsrv/DOC/telnetusage.md
index f8319d5ef28911bb18f89545e2d3ac6c10a04421..03561432265076dc279e82b797f7cbf02b43512a 100644
--- a/common/utils/telnetsrv/DOC/telnetusage.md
+++ b/common/utils/telnetsrv/DOC/telnetusage.md
@@ -1,28 +1,28 @@
-# starting the softmodem with the telnet server  
+# starting the softmodem with the telnet server
 By default the embedded telnet server, which is implemented in a shared library, is not built. It can be built after compiling the softmodem executable using the `build_oai` script:
 
 ```bash
- cd \<oai repository\>/openairinterface5g  
- source oaienv  
- cd cmake_targets  
- ./build_oai  --build-telnetsrv  
+ cd \<oai repository\>/openairinterface5g
+ source oaienv
+ cd cmake_targets
+ ./build_oai  --build-telnetsrv
 ```
 
 This will create the `libtelnetsrv.so` file in the `targets/bin` and `cmake_targets/lte_build_oai/build` sub directories of the oai repository.
 
 When starting the softmodem, you must specify the **_\-\-telnetsrv_** option to load and start the telnet server. The telnet server is loaded via the [oai shared library loader](loader).
 
-# using the Command Line Interface  
-By default the telnet server listen on all the ip addresses configured on the system and on port 9090.  This behavior can be changed using the `listenaddr` and `listenport` parameters. 
+# using the Command Line Interface
+By default the telnet server listen on all the ip addresses configured on the system and on port 9090.  This behavior can be changed using the `listenaddr` and `listenport` parameters.
 The telnet server includes a basic help, listing available commands and some commands also provide a specific detailed help sub-command.
-Below are  examples of telnet sessions:  
+Below are  examples of telnet sessions:
 
 *  [getting help](telnethelp.md)
 *  [using the history](telnethist.md)
 *  [using the get and set commands](telnetgetset.md)
 *  [using the loop command](telnetloop.md)
 *  [loader command](telnetloader.md)
-*  [log command](telnetlog.md)  
+*  [log command](telnetlog.md)
 
 # telnet server parameters
 The telnet server is using the [oai configuration module](Config/Rtusage). Telnet parameters must be specified in the `telnetsrv` section. Some parameters can be modified via the telnet telnet server command, as specified in the last column of the following table.
@@ -36,4 +36,4 @@ The telnet server is using the [oai configuration module](Config/Rtusage). Telne
 | `histfile` | `character string` | "oaitelnet.history" | file used for command history persistency | Y |
 | `histfsize` | `integer` | 50 | maximum number of commands saved in the history | Y |
 
-[oai telnet server home](telnetsrv.md)
\ No newline at end of file
+[oai telnet server home](telnetsrv.md)
diff --git a/common/utils/telnetsrv/telnetsrv_cpumeasur_def.h b/common/utils/telnetsrv/telnetsrv_cpumeasur_def.h
index 0b91ef1d4fccc063eba8d7b15128d48d03ab57d4..89ced509a4504a8c9b742bdbb3e1e9344936ab61 100644
--- a/common/utils/telnetsrv/telnetsrv_cpumeasur_def.h
+++ b/common/utils/telnetsrv/telnetsrv_cpumeasur_def.h
@@ -22,7 +22,7 @@
 /*! \file common/utils/telnetsrv/telnetsrv_cpumeasur_def.h
  * \brief: definitions of macro used to initialize the telnet_ltemeasurdef_t
  * \        strucures arrays which are then used by the display functions
- * \        in telnetsrv_measurements.c. 
+ * \        in telnetsrv_measurements.c.
  * \author Francois TABURET
  * \date 2019
  * \version 0.1
diff --git a/common/utils/threadPool/Makefile b/common/utils/threadPool/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..6f0e884886839933ee173e63c02042dde1d6cb23
--- /dev/null
+++ b/common/utils/threadPool/Makefile
@@ -0,0 +1,8 @@
+all: measurement_display thread-pool-test
+
+measurement_display: measurement_display.c thread-pool.h
+	gcc measurement_display.c -I /data/openairinterface5g.nr/common/utils/  -I. /data/openairinterface5g.nr/common/utils/backtrace.c -lpthread -D TEST_THREAD_POOL -I../LOG -I../../utils/T -o measurement_display
+
+thread-pool-test: thread-pool.c thread-pool.h
+	gcc -g thread-pool.c -I /data/openairinterface5g.nr/common/utils/  -I. /data/openairinterface5g.nr/common/utils/backtrace.c -lpthread -D TEST_THREAD_POOL -I../LOG -I../../utils/T -o thread-pool-test
+
diff --git a/common/utils/threadPool/measurement_display.c b/common/utils/threadPool/measurement_display.c
new file mode 100644
index 0000000000000000000000000000000000000000..ac7beca1fe00bac4b8d29d5906ded4cc5d7d1ea6
--- /dev/null
+++ b/common/utils/threadPool/measurement_display.c
@@ -0,0 +1,61 @@
+/*
+  Author: Laurent THOMAS, Open Cells
+  copyleft: OpenAirInterface Software Alliance and it's licence
+*/
+
+#define __USE_GNU
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <pthread.h>
+#include <sched.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/syscall.h>
+#include <sys/time.h>
+#include <stdint.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include "thread-pool.h"
+
+#define SEP "\t"
+
+uint64_t cpuCyclesMicroSec;
+
+int main(int argc, char *argv[]) {
+  if(argc != 2) {
+    printf("Need one paramter: the trace Linux pipe (fifo)");
+    exit(1);
+  }
+
+  mkfifo(argv[1],0666);
+  int fd=open(argv[1], O_RDONLY);
+
+  if ( fd == -1 ) {
+    perror("open read mode trace file:");
+    exit(1);
+  }
+
+  uint64_t deb=rdtsc();
+  usleep(100000);
+  cpuCyclesMicroSec=(rdtsc()-deb)/100000;
+  printf("Cycles per µs: %lu\n",cpuCyclesMicroSec);
+  printf("Key" SEP "delay to process" SEP "processing time" SEP "delay to be read answer\n");
+  notifiedFIFO_elt_t doneRequest;
+
+  while ( 1 ) {
+    if ( read(fd,&doneRequest, sizeof(doneRequest)) ==  sizeof(doneRequest)) {
+      printf("%lu" SEP "%lu" SEP "%lu" SEP "%lu" "\n",
+             doneRequest.key,
+             (doneRequest.startProcessingTime-doneRequest.creationTime)/cpuCyclesMicroSec,
+             (doneRequest.endProcessingTime-doneRequest.startProcessingTime)/cpuCyclesMicroSec,
+             (doneRequest.returnTime-doneRequest.endProcessingTime)/cpuCyclesMicroSec
+            );
+    } else {
+      printf("no measurements\n");
+      sleep(1);
+    }
+  }
+}
diff --git a/common/utils/threadPool/thread-pool.c b/common/utils/threadPool/thread-pool.c
new file mode 100644
index 0000000000000000000000000000000000000000..4cc56fc9b8126f8a5f88d03ce8be780563b7d116
--- /dev/null
+++ b/common/utils/threadPool/thread-pool.c
@@ -0,0 +1,230 @@
+/*
+  Author: Laurent THOMAS, Open Cells
+  copyleft: OpenAirInterface Software Alliance and it's licence
+*/
+
+#define _GNU_SOURCE
+#include <sched.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <string.h>
+#include <unistd.h>
+#include <ctype.h>
+#include <sys/sysinfo.h>
+#include <threadPool/thread-pool.h>
+
+void displayList(notifiedFIFO_t *nf) {
+  int n=0;
+  notifiedFIFO_elt_t *ptr=nf->outF;
+
+  while(ptr) {
+    printf("element: %d, key: %lu\n",++n,ptr->key);
+    ptr=ptr->next;
+  }
+
+  printf("End of list: %d elements\n",n);
+}
+
+static inline  notifiedFIFO_elt_t *pullNotifiedFifoRemember( notifiedFIFO_t *nf, struct one_thread *thr) {
+  mutexlock(nf->lockF);
+
+  while(!nf->outF)
+    condwait(nf->notifF, nf->lockF);
+
+  notifiedFIFO_elt_t *ret=nf->outF;
+  nf->outF=nf->outF->next;
+
+  if (nf->outF==NULL)
+    nf->inF=NULL;
+
+  // For abort feature
+  thr->runningOnKey=ret->key;
+  thr->abortFlag=false;
+  mutexunlock(nf->lockF);
+  return ret;
+}
+
+void *one_thread(void *arg) {
+  struct  one_thread *myThread=(struct  one_thread *) arg;
+  struct  thread_pool *tp=myThread->pool;
+
+  // configure the thread core assignment
+  // TBD: reserve the core for us exclusively
+  if ( myThread->coreID >= 0 &&  myThread->coreID < get_nprocs_conf()) {
+    cpu_set_t cpuset;
+    CPU_ZERO(&cpuset);
+    CPU_SET(myThread->coreID, &cpuset);
+    pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset);
+  }
+
+  //Configure the thread scheduler policy for Linux
+  struct sched_param sparam= {0};
+  sparam.sched_priority = sched_get_priority_max(SCHED_RR);
+  pthread_setschedparam(pthread_self(), SCHED_RR, &sparam);
+  // set the thread name for debugging
+  sprintf(myThread->name,"Tpool_%d",myThread->coreID);
+  pthread_setname_np(pthread_self(), myThread->name );
+
+  // Infinite loop to process requests
+  do {
+    notifiedFIFO_elt_t *elt=pullNotifiedFifoRemember(&tp->incomingFifo, myThread);
+
+    if (tp->measurePerf) elt->startProcessingTime=rdtsc();
+
+    elt->processingFunc(NotifiedFifoData(elt));
+
+    if (tp->measurePerf) elt->endProcessingTime=rdtsc();
+
+    if (elt->reponseFifo) {
+      // Check if the job is still alive, else it has been aborted
+      mutexlock(tp->incomingFifo.lockF);
+
+      if (myThread->abortFlag)
+        delNotifiedFIFO_elt(elt);
+      else
+        pushNotifiedFIFO(elt->reponseFifo, elt);
+
+      mutexunlock(tp->incomingFifo.lockF);
+    }
+  } while (true);
+}
+
+void initTpool(char *params,tpool_t *pool, bool performanceMeas) {
+  memset(pool,0,sizeof(*pool));
+  char *measr=getenv("threadPoolMeasurements");
+  pool->measurePerf=performanceMeas;
+  // force measurement if the output is defined
+  pool->measurePerf=measr!=NULL;
+
+  if (measr) {
+    mkfifo(measr,0666);
+    AssertFatal(-1 != (pool->dummyTraceFd=
+                         open(measr, O_RDONLY| O_NONBLOCK)),"");
+    AssertFatal(-1 != (pool->traceFd=
+                         open(measr, O_WRONLY|O_APPEND|O_NOATIME|O_NONBLOCK)),"");
+  } else
+    pool->traceFd=-1;
+
+  //Configure the thread scheduler policy for Linux
+  struct sched_param sparam= {0};
+  sparam.sched_priority = sched_get_priority_max(SCHED_RR)-1;
+  pthread_setschedparam(pthread_self(), SCHED_RR, &sparam);
+  pool->activated=true;
+  initNotifiedFIFO(&pool->incomingFifo);
+  char *saveptr, * curptr;
+  pool->nbThreads=0;
+  pool->restrictRNTI=false;
+  curptr=strtok_r(params,",",&saveptr);
+
+  while ( curptr!=NULL ) {
+    int c=toupper(curptr[0]);
+
+    switch (c) {
+      case 'U':
+        pool->restrictRNTI=true;
+        break;
+
+      case 'N':
+        pool->activated=false;
+        break;
+
+      default:
+        pool->allthreads=(struct one_thread *)malloc(sizeof(struct one_thread));
+        pool->allthreads->next=pool->allthreads;
+        printf("create a thread for core %d\n", atoi(curptr));
+        pool->allthreads->coreID=atoi(curptr);
+        pool->allthreads->id=pool->nbThreads;
+        pool->allthreads->pool=pool;
+        pthread_create(&pool->allthreads->threadID, NULL, one_thread, (void *)pool->allthreads);
+        pool->nbThreads++;
+    }
+
+    curptr=strtok_r(NULL,",",&saveptr);
+  }
+
+  if (pool->activated && pool->nbThreads==0) {
+    printf("No servers created in the thread pool, exit\n");
+    exit(1);
+  }
+}
+
+#ifdef TEST_THREAD_POOL
+
+struct testData {
+  int id;
+  char txt[30];
+};
+
+void processing(void *arg) {
+  struct testData *in=(struct testData *)arg;
+  printf("doing: %d, %s, in thr %ld\n",in->id, in->txt,pthread_self() );
+  sprintf(in->txt,"Done by %ld, job %d", pthread_self(), in->id);
+  usleep(rand()%100);
+  printf("done: %d, %s, in thr %ld\n",in->id, in->txt,pthread_self() );
+}
+
+int main() {
+  notifiedFIFO_t myFifo;
+  initNotifiedFIFO(&myFifo);
+  pushNotifiedFIFO(&myFifo,newNotifiedFIFO_elt(sizeof(struct testData), 1234,NULL,NULL));
+
+  for(int i=10; i>1; i--) {
+    pushNotifiedFIFO(&myFifo,newNotifiedFIFO_elt(sizeof(struct testData), 1000+i,NULL,NULL));
+  }
+
+  displayList(&myFifo);
+  notifiedFIFO_elt_t *tmp=pullNotifiedFIFO(&myFifo);
+  printf("pulled: %lu\n", tmp->key);
+  displayList(&myFifo);
+  tmp=pullNotifiedFIFO(&myFifo);
+  printf("pulled: %lu\n", tmp->key);
+  displayList(&myFifo);
+  abortNotifiedFIFO(&myFifo,1005);
+  printf("aborted 1005\n");
+  displayList(&myFifo);
+  pushNotifiedFIFO(&myFifo,newNotifiedFIFO_elt(sizeof(struct testData), 12345678, NULL, NULL));
+  displayList(&myFifo);
+  abortNotifiedFIFO(&myFifo,12345678);
+  printf("aborted 12345678\n");
+  displayList(&myFifo);
+
+  do {
+    tmp=pollNotifiedFIFO(&myFifo);
+
+    if (tmp) {
+      printf("pulled: %lu\n", tmp->key);
+      displayList(&myFifo);
+    } else
+      printf("Empty list \n");
+  } while(tmp);
+
+  tpool_t  pool;
+  char params[]="1,2,3,u";
+  initTpool(params,&pool, true);
+  notifiedFIFO_t worker_back;
+  initNotifiedFIFO(&worker_back);
+
+  for (int i=0; i <1000 ; i++) {
+    notifiedFIFO_elt_t *work=newNotifiedFIFO_elt(sizeof(struct testData), i, &worker_back, processing);
+    struct testData *x=(struct testData *)NotifiedFifoData(work);
+    x->id=i;
+    pushTpool(&pool, work);
+  }
+
+  do {
+    tmp=pullTpool(&worker_back,&pool);
+
+    if (tmp) {
+      struct testData *dd=NotifiedFifoData(tmp);
+      printf("Result: %s\n",dd->txt);
+      delNotifiedFIFO_elt(tmp);
+    } else
+      printf("Empty list \n");
+
+    abortTpool(&pool,510);
+  } while(tmp);
+
+  return 0;
+}
+#endif
diff --git a/common/utils/threadPool/thread-pool.h b/common/utils/threadPool/thread-pool.h
new file mode 100644
index 0000000000000000000000000000000000000000..6f34508c5a9023b23d3b15e4be9b036c09b2b06a
--- /dev/null
+++ b/common/utils/threadPool/thread-pool.h
@@ -0,0 +1,244 @@
+/*
+  Author: Laurent THOMAS, Open Cells
+  copyleft: OpenAirInterface Software Alliance and it's licence
+*/
+
+#ifndef THREAD_POOL_H
+#define THREAD_POOL_H
+#include <stdbool.h>
+#include <stdint.h>
+#include <pthread.h>
+#include <sys/syscall.h>
+#include <assertions.h>
+#include <LOG/log.h>
+
+#ifdef DEBUG
+  #define THREADINIT   PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP
+#else
+  #define THREADINIT   PTHREAD_MUTEX_INITIALIZER
+#endif
+#define mutexinit(mutex)   AssertFatal(pthread_mutex_init(&mutex,NULL)==0,"");
+#define condinit(signal)   AssertFatal(pthread_cond_init(&signal,NULL)==0,"");
+#define mutexlock(mutex)   AssertFatal(pthread_mutex_lock(&mutex)==0,"");
+#define mutextrylock(mutex)   pthread_mutex_trylock(&mutex)
+#define mutexunlock(mutex) AssertFatal(pthread_mutex_unlock(&mutex)==0,"");
+#define condwait(condition, mutex) AssertFatal(pthread_cond_wait(&condition, &mutex)==0,"");
+#define condbroadcast(signal) AssertFatal(pthread_cond_broadcast(&signal)==0,"");
+#define condsignal(signal)    AssertFatal(pthread_cond_broadcast(&signal)==0,"");
+
+typedef struct notifiedFIFO_elt_s {
+  struct notifiedFIFO_elt_s *next;
+  uint64_t key; //To filter out elements
+  struct notifiedFIFO_s *reponseFifo;
+  void (*processingFunc)(void *);
+  bool malloced;
+  uint64_t creationTime;
+  uint64_t startProcessingTime;
+  uint64_t endProcessingTime;
+  uint64_t returnTime;
+  void *msgData;
+}  notifiedFIFO_elt_t;
+
+typedef struct notifiedFIFO_s {
+  notifiedFIFO_elt_t *outF;
+  notifiedFIFO_elt_t *inF;
+  pthread_mutex_t lockF;
+  pthread_cond_t  notifF;
+} notifiedFIFO_t;
+
+// You can use this allocator or use any piece of memory
+static inline notifiedFIFO_elt_t *newNotifiedFIFO_elt(int size,
+    uint64_t key,
+    notifiedFIFO_t *reponseFifo,
+    void (*processingFunc)(void *)) {
+  notifiedFIFO_elt_t *ret;
+  AssertFatal( NULL != (ret=(notifiedFIFO_elt_t *) malloc(sizeof(notifiedFIFO_elt_t)+size+32)), "");
+  ret->next=NULL;
+  ret->key=key;
+  ret->reponseFifo=reponseFifo;
+  ret->processingFunc=processingFunc;
+  // We set user data piece aligend 32 bytes to be able to process it with SIMD
+  ret->msgData=(void *)ret+(sizeof(notifiedFIFO_elt_t)/32+1)*32;
+  ret->malloced=true;
+  return ret;
+}
+
+static inline void *NotifiedFifoData(notifiedFIFO_elt_t *elt) {
+  return elt->msgData;
+}
+
+static inline void delNotifiedFIFO_elt(notifiedFIFO_elt_t *elt) {
+  if (elt->malloced) {
+    elt->malloced=false;
+    free(elt);
+  } else
+    printf("delNotifiedFIFO on something not allocated by newNotifiedFIFO\n");
+
+  //LOG_W(UTIL,"delNotifiedFIFO on something not allocated by newNotifiedFIFO\n");
+}
+
+static inline void initNotifiedFIFO(notifiedFIFO_t *nf) {
+  mutexinit(nf->lockF);
+  condinit (nf->notifF);
+  nf->inF=NULL;
+  nf->outF=NULL;
+  // No delete function: the creator has only to free the memory
+}
+
+static inline void pushNotifiedFIFO(notifiedFIFO_t *nf, notifiedFIFO_elt_t *msg) {
+  mutexlock(nf->lockF);
+  msg->next=NULL;
+
+  if (nf->outF == NULL)
+    nf->outF = msg;
+
+  if (nf->inF)
+    nf->inF->next = msg;
+
+  nf->inF = msg;
+  condbroadcast(nf->notifF);
+  mutexunlock(nf->lockF);
+}
+
+static inline  notifiedFIFO_elt_t *pullNotifiedFIFO(notifiedFIFO_t *nf) {
+  mutexlock(nf->lockF);
+
+  while(!nf->outF)
+    condwait(nf->notifF, nf->lockF);
+
+  notifiedFIFO_elt_t *ret=nf->outF;
+  nf->outF=nf->outF->next;
+
+  if (nf->outF==NULL)
+    nf->inF=NULL;
+
+  mutexunlock(nf->lockF);
+  return ret;
+}
+
+static inline  notifiedFIFO_elt_t *pollNotifiedFIFO(notifiedFIFO_t *nf) {
+  int tmp=mutextrylock(nf->lockF);
+
+  if (tmp != 0 )
+    return NULL;
+
+  notifiedFIFO_elt_t *ret=nf->outF;
+
+  if (ret!=NULL)
+    nf->outF=nf->outF->next;
+
+  if (nf->outF==NULL)
+    nf->inF=NULL;
+
+  mutexunlock(nf->lockF);
+  return ret;
+}
+
+// This function aborts all messages matching the key
+// If the queue is used in thread pools, it doesn't cancels already running processing
+// because the message has already been picked
+static inline void abortNotifiedFIFO(notifiedFIFO_t *nf, uint64_t key) {
+  mutexlock(nf->lockF);
+  notifiedFIFO_elt_t **start=&nf->outF;
+
+  while(*start!=NULL) {
+    if ( (*start)->key == key ) {
+      notifiedFIFO_elt_t *request=*start;
+      *start=(*start)->next;
+      delNotifiedFIFO_elt(request);
+    }
+
+    if (*start != NULL)
+      start=&(*start)->next;
+  }
+
+  mutexunlock(nf->lockF);
+}
+
+struct one_thread {
+  pthread_t  threadID;
+  int id;
+  int coreID;
+  char name[256];
+  uint64_t runningOnKey;
+  bool abortFlag;
+  struct thread_pool *pool;
+  struct one_thread *next;
+};
+
+typedef struct thread_pool {
+  int activated;
+  bool measurePerf;
+  int traceFd;
+  int dummyTraceFd;
+  uint64_t cpuCyclesMicroSec;
+  uint64_t startProcessingUE;
+  int nbThreads;
+  bool restrictRNTI;
+  notifiedFIFO_t incomingFifo;
+  struct one_thread *allthreads;
+} tpool_t;
+
+static inline void pushTpool(tpool_t *t, notifiedFIFO_elt_t *msg) {
+  if (t->measurePerf) msg->creationTime=rdtsc();
+
+  pushNotifiedFIFO(&t->incomingFifo, msg);
+}
+
+static inline notifiedFIFO_elt_t *pullTpool(notifiedFIFO_t *responseFifo, tpool_t *t) {
+  notifiedFIFO_elt_t *msg= pullNotifiedFIFO(responseFifo);
+
+  if (t->measurePerf)
+    msg->returnTime=rdtsc();
+
+  if (t->traceFd)
+    if(write(t->traceFd, msg, sizeof(*msg)));
+
+  return msg;
+}
+
+static inline notifiedFIFO_elt_t *tryPullTpool(notifiedFIFO_t *responseFifo, tpool_t *t) {
+  notifiedFIFO_elt_t *msg= pollNotifiedFIFO(responseFifo);
+
+  if (msg == NULL)
+    return NULL;
+
+  if (t->measurePerf)
+    msg->returnTime=rdtsc();
+
+  if (t->traceFd)
+    if(write(t->traceFd, msg, sizeof(*msg)));
+
+  return msg;
+}
+
+static inline void abortTpool(tpool_t *t, uint64_t key) {
+  notifiedFIFO_t *nf=&t->incomingFifo;
+  mutexlock(nf->lockF);
+  notifiedFIFO_elt_t **start=&nf->outF;
+
+  while(*start!=NULL) {
+    if ( (*start)->key == key ) {
+      notifiedFIFO_elt_t *request=*start;
+      *start=(*start)->next;
+      delNotifiedFIFO_elt(request);
+    }
+
+    if (*start != NULL)
+      start=&(*start)->next;
+  }
+
+  struct one_thread *ptr=t->allthreads;
+
+  while(ptr!=NULL) {
+    if (ptr->runningOnKey==key)
+      ptr->abortFlag=true;
+
+    ptr=ptr->next;
+  }
+
+  mutexunlock(nf->lockF);
+}
+void initTpool(char *params,tpool_t *pool, bool performanceMeas);
+
+#endif
diff --git a/common/utils/threadPool/thread-pool.md b/common/utils/threadPool/thread-pool.md
new file mode 100644
index 0000000000000000000000000000000000000000..2b6336fb6093e7789d82aeb5ccef6cd5815b5f27
--- /dev/null
+++ b/common/utils/threadPool/thread-pool.md
@@ -0,0 +1,71 @@
+# Thread pool
+
+The thread pool is a working server, made of a set of worker threads that can be mapped on CPU cores.
+
+Each worker loop on pick from the same input queue jobs to do.
+When a job is done, the worker sends a return if a return is defined.
+
+A selective abort allows to cancel parallel jobs (usage: a client pushed jobs, but from a response of one job, the other linked jobs becomes useless).
+
+All the thread pool functions are thread safe, nevertheless the working functions are implemented by the thread pool client, so the client has to tackle the parallel execution of his functions called "processingFunc" hereafter.
+
+## license
+Author: Laurent Thomas, Open cells project 
+The owner share this piece code to Openairsoftware alliance as per OSA license terms
+
+# jobs
+
+A job is a message (notifiedFIFO_elt_t):
+next: internal FIFO chain, do not set it
+key:  a long int that the client can use to identify a message or a group of messages
+responseFifo: if the client defines a response FIFO, the message will be posted back after processing
+processingFunc: any funtion (type void processingFunc(void *)) that the worker will launch
+msgData: the data passed to processingFunc. It can be added automatically, or you can set it to a buffer you are managing
+malloced: a boolean that enable internal free in these cases: no return Fifo or Abort feature
+
+The job messages can be created with newNotifiedFIFO_elt() and delNotifiedFIFO_elt() or managed by the client.
+
+# Queues of jobs
+
+Queues are type of: notifiedFIFO_t that must be initialized by init_notifiedFIFO()
+No delete function is required, the creator has only to free the data of type notifiedFIFO_t
+
+push_notifiedFIFO() add a job in the queue
+pull_notifiedFIFO() is blocking, poll_notifiedFIFO() is non blocking
+
+abort_notifiedFIFO() allows the customer to delete all waiting jobs that match with the key (see key in jobs definition)
+
+# Thread pools
+
+## initialization
+The clients can create one or more thread pools with init_tpool()
+the params string structure: describes a list of cores, separated by "," that run a worker thread
+
+If the core exists on the CPU, the thread pool initialization sets the affinity between this thread and the related code (use negative values is allowed, so the thread will never be mapped on a specific core).
+
+The threads are all Linux real time scheduler, their name is set automatically is "Tpool_<core id>"
+
+## adding jobs
+The client create their jobs messages as a notifiedFIFO_elt_t, then they push it with pushTpool() (that internally calls push_notifiedFIFO())
+
+If they need a return, they have to create response queues with init_notifiedFIFO() and set this FIFO pointer in the notifiedFIFO_elt_t before pushing the job.
+
+## abort
+
+A abort service abortTpool() allows to abort all jobs that match a key (see jobs "key"). When the abort returns, it garanties no job (matching the key) response will be posted on response queues.
+
+Nevertheless, jobs already performed before the return of abortTpool() are pushed in the response Fifo queue.
+
+## Performance measurements
+
+A performance measurement is integrated: the pool will automacillay fill timestamps:
+
+* creationTime: time the request is push to the pool;
+* startProcessingTime: time a worker start to run on the job
+* endProcessingTime: time the worker finished the job
+* returnTime: time the client reads the result
+
+if you set the environement variable: thread-pool-measurements to a valid file name
+These measurements will be wrote to this Linux pipe.
+
+A tool to read the linux fifo and display it in ascii is provided: see the local directory Makefile for this tool and to compile the thread pool unitary tests.
diff --git a/doc/BUILD.md b/doc/BUILD.md
new file mode 100644
index 0000000000000000000000000000000000000000..6d3645948f1bc415011df6436da59fd4bdea79fb
--- /dev/null
+++ b/doc/BUILD.md
@@ -0,0 +1,121 @@
+# OAI build procedures
+
+## soft modem Build script
+
+oai EPC is developed in a distinct project with it's own [documentation](https://github.com/OPENAIRINTERFACE/openair-cn/wiki) , it is not described here. OAI UE and eNodeB sources can be downloaded from the Eurecom [gitlab repository](./GET_SOURCES.md). Sources  come with a build script [build_oai](../cmake_targets/build_oai) located at the root of the `openairinterface5g/cmake_targets` directory. This script is developed to build the oai binaries (executables,shared libraries) for different hardware platforms, and use cases. 
+
+the main oai binaries, which are tested by the Continuous Integration process are:
+
+- The LTE UE: `lte-uesoftmodem`
+-  The LTE eNodeB: `lte-softmodem`
+- The PHY simulators: `dlsim` and `ulsim`
+
+The build system for OAI uses [cmake](https://cmake.org/) which is a  tool to generate makefiles. The `build_oai` script is a wrapper using cmake, make and standard linux shell commands to ease the oai build and use . The file describing how to build the executables from source files is the [CMakeLists.txt](../cmake_targets/CMakeLists.txt), it is used as input by cmake to generate the makefiles.
+
+The oai softmodem supports many use cases, and new ones are regularly added. Most of them are accessible using the configuration file or the command line options and continuous effort is done to avoid introducing build options as it makes tests and usage more complicated than run-time options. The following functionalities, originally requiring a specific build are now accessible by configuration or command line options:
+
+- s1, noS1
+
+- all simulators, with exception of PHY simulators, which are distinct executables.
+
+
+Calling the `build_oai` script with the -h option gives the list of all available options, but a process to simplify and check the requirements of all these options is on-going. Check the 
+
+[table]: BUILD.md	"`build_oai` options"
+
+ at the end of this page to know the status of `buid_oai` options which are not described hereafter.
+
+
+
+## building PHY simulators
+
+detailed information about these simulators can be found  [in this dedicated page](https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/OpenAirLTEPhySimul
+
+## building UE and eNodeB executables
+
+After downloading the source files, a single build command can be used to get the binaries supporting all the oai softmodem use cases (UE and eNodeB):
+
+```
+cd <your oai installation directory>/openairinterface5g/
+source oaienv
+cd ../cmake_targets/
+./build_oai -I -w USRP --eNB --UE
+```
+
+- The -I option is to install pre-requisites, you only need it the first time you build the softmodem or when some oai dependencies have changed. 
+- The -w option is to select the radio head support you want to include in your build. Radio head support is provided via a shared library, which is called the "oai device" The build script creates a soft link from `liboai_device.so` to the true device which will be used at run-time (here the USRP one,`liboai_usrpdevif.so` . USRP is the only hardware tested today in the Continuous Integration process.
+- --eNB is to build the `lte-softmodem` executable and all required shared libraries
+- --UE is to build the `lte-uesoftmodem` executable and all required shared libraries
+
+You can build the eNodeB and the UE separately, you may not need both of them depending on your oai usage.
+
+After completing the build, the binaries are available in the `cmake_targets/lte_build_oai/build` directory. A copy is also available in the `target/bin` directory, with all binaries suffixed by the 3GPP release number, today .Rel14 by default. It must be noticed that the option for building for a specific 3GPP release number is not tested by the CI and may be removed in the future. 
+
+## building optional binaries
+
+### Telnet server
+
+​	The telnet server can be built  with the --build-telnet option, after building the softmodem or while building it.
+
+`./build_oai -I -w USRP --eNB --UE --build-telnetsrv`
+
+​	or
+
+`./build_oai  --build-telnetsrv`
+
+### USRP record player
+
+​	The USRP record player today needs a specific build. Work to make it available as a run time option is under consideration
+
+
+
+## `build_oai` options
+
+| Option                                                      | Status                                      | Description                                                  |
+| ----------------------------------------------------------- | ------------------------------------------- | :----------------------------------------------------------- |
+| -h                                                          | maintained                                  | get help                                                     |
+| -c                                                          | maintained                                  | erase all previously built files for this target before starting the new build. |
+| -C                                                          | maintained, needs improvement               | erase all previously built files for any target before starting the new build. |
+| --verbose-compile                                           | maintained                                  |                                                              |
+| --cflags_processor                                          | maintained                                  | used to pass options to the compiler                         |
+| --clean-kernel                                              | unknown                                     | no code in the script corresponding to this option           |
+| --install-system-files                                      | maintained                                  | install oai built binaries in linux system files repositories |
+| -w                                                          | maintained and tested in CI for USRP device | build corresponding oai device and create the soft link to enforce this device usage at run-time |
+| -t                                                          | maintained                                  | build the specified transport library, which is used in some simulators and in non monolithic eNodeB deployments. Now of little interest as transport library build is enforced when building the eNodeB. |
+| --phy_simulators                                            | maintained, tested in CI                    | build all PHY simulators, a set of executables allowing unitary tests of LTE channel implementation within oai. |
+| --core_simulators                                           |                                             |                                                              |
+| -s                                                          |                                             |                                                              |
+| --run-group                                                 |                                             |                                                              |
+| -I                                                          | maintained, tested in CI                    | install external dependencies before starting the build      |
+| --install-optional-packages                                 | maintained                                  | install optional packages, useful for developing and testing. look at the |
+|                                                             |                                             | check_install_additional_tools function in cmake_targets/tools/build_helper script to get the list |
+| -g                                                          | maintained                                  | build binaries with gdb support.                             |
+| --eNB                                                       | maintained and tested in CI                 | build `lte-softmodem` the LTE eNodeB                         |
+| --UE                                                        | maintained and tested in CI                 | build `lte-uesoftmodem` the LTE UE                           |
+| --usrp-recplay                                              | maintained                                  | build with support for the record player. Implementation will be soon reviewed to switch to a run-time option. |
+| --build-telnet                                              | maintained                                  | build the telnet server shared library, which can then be loaded at run time via the --telnetsrv command line option. |
+| --build-msc                                                 | unknown                                     | build the msc shared library, which can then be loaded at run time via the --msc command line option. msc is a tracing utility which status is unknown. |
+| --UE-conf-nvram                                             |                                             |                                                              |
+| --UE-gen-nvram                                              |                                             |                                                              |
+| -r                                                          | unknown, to be removed                      | specifies which 3GPP release to build for. Only the default (today rel14) is tested in CI and it is likely that future oai release will remove this option |
+| -V                                                          | deprecated                                  | Used to build with support for synchronization diagram utility. This is now available via the T-Tracer and is included if T-Tracer is not disabled. |
+| -x                                                          | deprecated                                  | Used to build with support for embedded signal analyzer. This is now available via the T-Tracer and is included if T-Tracer is not disabled. |
+| --noS1                                                      | deprecated, to be removed                   | build noS1 version of oai softmodem binaries. noS1 allows running oai eNodeB and UE without an LTE core network (EPC). This functionality is now available via a run-time option. |
+| --build-doxygen                                             | unknown                                     | build doxygen documentation, many oai source files do not include doxygen comments |
+| --disable-deadline --enable-deadline --disable-cpu-affinity | deprecated                                  | These options were used to activate or de-activate specific code depending on the choice of a specific linux scheduling  mode. This has not been tested for a while and should be implemented as configuration options |
+| --disable-T-Tracer                                          | maintained, to be tested                    | Remove T_Tracer and console LOG messages except error messages. |
+| --disable-hardware-dependency                               |                                             |                                                              |
+| --ue-autotest-trace --ue-timing --ue-trace                  | deprecated                                  | Were used to enable conditional code implementing debugging messages or debugging statistics. These functionalities are now either available from run-time options or not maintained. |
+| --disable-log                                               | deprecated, to be removed                   | Was used to disable LOG messages, replaced by `--disable-T-Tracer` build option to remove tracing code from the build or `--T-stdout 0` run time option to redirect LOG messages to T-Tracer client interface. |
+| --ue-nas-use-tun                                            | deprecated to be removed                    | Usage of tun  in place of specific kernel modules is now a run time option. `--nokrnmod 0` option disable the default behavior which is to use tun to send or receive ip packets to/from the linux ip stack. |
+| --build-eclipse                                             | unknown                                     |                                                              |
+| --basic-simulator                                           | deprecated tested in CI                     | builds the basic simulator device. Now of little interest as this device build is enforced when building the eNodeB and it can be used at run time with the `--basicsim` option. More over the rf simulator is an enhanced basic simulator. |
+| --rfsimulator                                               | maintained                                  | builds the rf simulator device. Now of little interest as this device build is enforced when building the eNodeB and it can be used at run time with the `--rfsim` option. |
+|                                                             |                                             |                                                              |
+
+[oai wiki home](https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/home)
+
+[oai softmodem features](FEATURE_SET.md)
+
+[running the oai softmodem ](RUNMODEM.md)
+
diff --git a/doc/FEATURE_SET.md b/doc/FEATURE_SET.md
index 3dd3605fb3cfe327d83a329a2981496028ed2faf..7e2cc3038861c5aa9e6432d39ae210c5bef07745 100644
--- a/doc/FEATURE_SET.md
+++ b/doc/FEATURE_SET.md
@@ -195,3 +195,10 @@ The NAS layer is based on **3GPP 24.301** and implements the following functions
 
 - EMM attach/detach, authentication, tracking area update, and more
 - ESM default/dedicated bearer, PDN connectivity, and more
+
+[oai wiki home](https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/home)
+
+[oai softmodem build procedure](BUILD.md)
+
+[running the oai softmodem ](RUNMODEM.md)
+
diff --git a/doc/GET_SOURCES.md b/doc/GET_SOURCES.md
new file mode 100644
index 0000000000000000000000000000000000000000..bd85c8a9265c16363788161cd37e225b7ddeeda6
--- /dev/null
+++ b/doc/GET_SOURCES.md
@@ -0,0 +1,103 @@
+# The OpenAirInterface repository
+
+The OpenAirInterface software can be obtained from our gitLab
+server. You will need a git client to get the sources. The repository
+is currently used for main developments.
+
+## Prerequisite
+
+You need to install the subversion/git using the following commands:
+
+```shell
+sudo apt-get update
+sudo apt-get install subversion git
+```
+
+## Using EURECOM Gitlab
+
+The [openairinterface5g repository](https://gitlab.eurecom.fr/oai/openairinterface5g.git)
+holds the source code for (eNB RAN + UE RAN).
+
+For legal issues (licenses), the core network (EPC) source code is now moved away from
+the above openairinterface5g git repository. This EPC code is now splitted into two git
+projects ([openair-cn](https://gitlab.eurecom.fr/oai/openair-cn.git) with apache license
+and [xtables-addons-oai](https://gitlab.eurecom.fr/oai/xtables-addons-oai.git) with GPL license).
+
+Configure git with your name/email address (only important if you are developer and want to checkin code to Git):
+
+```shell
+git config --global user.name "Your Name"
+git config --global user.email "Your email address"
+```
+
+- Add a certificate from gitlab.eurecom.fr to your Ubuntu 14.04 installation:
+
+```shell
+echo -n | openssl s_client -showcerts -connect gitlab.eurecom.fr:443 2>/dev/null | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' | sudo tee -a /etc/ssl/certs/ca-certificates.crt
+```
+
+- Disable certificate check completely if you do not have root access to /etc/ssl directory
+
+```shell
+git config --global http.sslverify false
+```
+
+### In order to checkout the Git repository (for OAI Users without login to gitlab server)
+
+Checkout RAN repository (eNB RAN + UE RAN):
+
+```shell
+git clone https://gitlab.eurecom.fr/oai/openairinterface5g.git
+```
+
+Checkout EPC (Core Network) repository:
+
+```shell
+git clone https://gitlab.eurecom.fr/oai/openair-cn.git
+```
+
+Optionally (openair-cn build script can install it for you):
+
+```shell
+git clone https://gitlab.eurecom.fr/oai/xtables-addons-oai.git
+```
+
+### In order to checkout the Git repository (for OAI Developers/admins with login to gitlab server)
+
+Please send email to {openair_tech (AT) eurecom (DOT) fr} to be added to the repository
+as a developer (only important for users who want to commit code to the repository). If
+you do not have account on gitlab.eurecom.fr, please register yourself to gitlab.eurecom.fr.
+
+* Checkout with using ssh keys:
+   * You will need to put your ssh keys in https://gitlab.eurecom.fr/profile/keys
+     to access to the git repo. Once that is done, checkout the git repository using:
+   * `git clone git@gitlab.eurecom.fr:oai/openairinterface5g.git`
+* Checkout with user name/password prompt:
+   * `git clone https://YOUR_USERNAME@gitlab.eurecom.fr/oai/openairinterface5g.git`
+   * `git clone https://YOUR_USERNAME@gitlab.eurecom.fr/oai/openair-cn.git`
+   * `git clone https://YOUR_USERNAME@gitlab.eurecom.fr/oai/xtables-addons-oai.git` (optional, openair-cn build script can do it for you)
+
+## Which branch to checkout?
+
+On the RAN side:
+
+* **master**: This branch is targeted for the user community. Since January 2019, it is also subject to a Continuous Integration process. The update frequency is about once every 2-3 months. We are also performing bug fixes on this branch.
+* **develop**: This branch contains recent commits that are tested on our CI test bench. The update frequency is about once a week.
+
+Please see the work flow and policies page :
+
+https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/oai-policies-home
+
+you can find the latest stable tag release here :
+
+https://gitlab.eurecom.fr/oai/openairinterface5g/tags
+
+The tag naming conventions are :
+
+- On `master` branch: **v1.`x`.`y`** where
+  * `x` is the minor release number, incremented every 2-3 months when we are merging `develop` into `master` branch.
+  * `y` is the maintenance number, starting at 0 when we do a minor release and being incremented when a bug fix is incorporated into `master` branch.
+- On `develop` branch **`yyyy`.w`xx`**
+  * `yyyy` is the calendar year
+  * `xx` the week number within the year
+
diff --git a/doc/L1SIM.md b/doc/L1SIM.md
new file mode 100644
index 0000000000000000000000000000000000000000..d63c0e5a3400213aad3b961de2485dd68c28da18
--- /dev/null
+++ b/doc/L1SIM.md
@@ -0,0 +1,99 @@
+<table style="border-collapse: collapse; border: none;">
+  <tr style="border-collapse: collapse; border: none;">
+    <td style="border-collapse: collapse; border: none;">
+      <a href="http://www.openairinterface.org/">
+         <img src="./images/oai_final_logo.png" alt="" border=3 height=50 width=150>
+         </img>
+      </a>
+    </td>
+    <td style="border-collapse: collapse; border: none; vertical-align: center;">
+      <b><font size = "5">Open Air LTE Emulation</font></b>
+    </td>
+  </tr>
+</table>
+
+This page is valid for the develop branch
+
+# Table of Contents: #
+
+* [How to build the eNB and the UE](#build)
+* [How to run an eNB built with the noS1 option](#run-noS1-eNB)
+* [How to run a UE built with the noS1 option](#run-noS1-UE)
+* [Continuous Integration notes](#CInote)
+* [How to ping an eNB from a UE and vice versa (with the noS1 option)](#noS1-pinging)
+
+The old oaisim is dead! Long live oaisim! :)
+
+If you are looking for a description of the old oaisim (which is still available in some branches/tags), please see [here](OpenAirLTEEmulation) and [here](how-to-run-oaisim-with-multiple-ue).
+
+oaisim has been scraped and replaced by the same programs that are used for the real-time operation, `lte-softmodem` and `lte-uesoftmodem`. The latter also now includes an optional channel model, just like oaisim did. 
+
+# <a name="build">[How to build the eNB and the UE](BUILD.md)</a>
+
+The following paragraph explains how to run the L1 simulator in noS1 mode and using the oai kernel modules. 
+
+# <a name="run-noS1-eNB">How to run an eNB with the noS1 option</a>
+
+Modify the configuration file for IF4p5 fronthaul, `/openairinterface5g/ci-scripts/conf_files/rcc.band7.nos1.simulator.conf`, and replace the loopback interface with a physical ethernet interface and the IP addresses to work on your network. Copy your modifications to a new file, let's call YYY.conf the resulting configuration file.
+
+Run lte-softmodem as usual with this configuration. 
+
+```bash
+$ source oaienv
+$ cd cmake_targets/tools
+$ sudo -E ./init_nas_nos1 eNB
+$ cd ../lte_build_oai/build
+$ sudo -E ./lte-softmodem -O YYY.conf --noS1 --nokrnmod 0
+```
+
+# <a name="run-noS1-UE">How to run a UE with the noS1 option</a>
+
+Similarly modify the example configuration file in `/openairinterface5g/ci-scripts/conf_files/rru.band7.nos1.simulator.conf` and replace loopback interface and IP addresses. Copy your modifications to a new file, let's call XXX.conf the resulting configuration file.
+
+Run it like:
+
+```bash
+$ source oaienv
+$ cd cmake_targets/tools
+$ sudo -E ./init_nas_nos1 UE
+$ cd ../lte_build_oai/build
+$ sudo ./lte-uesoftmodem -O XXX.conf -r 25 --siml1 --noS1 --nokrnmod 0
+```
+
+That should give you equivalent functionality to what you had with oaisim including noise and RF channel emulation (path loss / fading, etc.). You should also be able to run multiple UEs. 
+
+# <a name="CInote">Continuous Integration notes</a>
+The CI currently tests the noS1 build option with one eNB and one UE in the following scenarios:
+* pinging one UE from one eNB
+* pinging one eNB from one UE
+* iperf download between one eNB and one UE
+* iperf upload between one eNB and one UE
+* all the above tests are done in FDD 5Mhz mode.
+
+# <a name="noS1-pinging">How to ping an eNB from a UE and vice versa (with the noS1 option)</a>
+
+Once your eNB and UE (built with the noS1 option) are running and synchronised, you can ping the eNB from the UE with the following command:
+
+```bash
+ping -I oai0 -c 20 $eNB_ip_addr
+```
+where $eNB_ip_addr is the IP address of your eNB.
+
+Similarly, you can ping the UE from the eNB.
+
+The IP adresses of the eNB and the UE are set up by the init_nas_nos1 program and should have the following values:
+* eNB_ip_addr set to 20 10.0.1.1
+* ue_ip_addr set to 20 10.0.1.2
+
+
+
+
+
+
+
+[oai wiki home](https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/home)
+
+[oai softmodem features](FEATURE_SET.md)
+
+[oai softmodem build procedure](BUILD.md)
+
diff --git a/doc/L2NFAPI.md b/doc/L2NFAPI.md
new file mode 100644
index 0000000000000000000000000000000000000000..4dcaaef3bcf8771a4ae8108b11dd31dcadedd79c
--- /dev/null
+++ b/doc/L2NFAPI.md
@@ -0,0 +1,36 @@
+<table style="border-collapse: collapse; border: none;">
+  <tr style="border-collapse: collapse; border: none;">
+    <td style="border-collapse: collapse; border: none;">
+      <a href="http://www.openairinterface.org/">
+         <img src="./images/oai_final_logo.png" alt="" border=3 height=50 width=150>
+         </img>
+      </a>
+    </td>
+    <td style="border-collapse: collapse; border: none; vertical-align: center;">
+      <b><font size = "5">L2 nFAPI Simulator Usage</font></b>
+    </td>
+  </tr>
+</table>
+
+This simulator allows to test L2 and above Layers using the nFAPI interface.
+
+**This simulator is available starting the `v1.0.0` release on the `master` branch.**
+
+Currently the only validated deployment by CI and developers is *with S1 interface and eNB / UEs are on the same machine*.
+
+Others deployments will be supported later after bug fixes and validation in the CI process.
+
+1. [With S1 -- eNB and UE on same machine](L2NFAPI_S1.md)
+
+
+
+
+
+
+
+[oai wiki home](https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/home)
+
+[oai softmodem features](FEATURE_SET.md)
+
+[oai softmodem build procedure](BUILD.md)
+
diff --git a/doc/L2NFAPI_S1.md b/doc/L2NFAPI_S1.md
new file mode 100644
index 0000000000000000000000000000000000000000..c1c83211e19fedaa4e9c5b9ee8801053fb2ceeb0
--- /dev/null
+++ b/doc/L2NFAPI_S1.md
@@ -0,0 +1,304 @@
+<table style="border-collapse: collapse; border: none;">
+  <tr style="border-collapse: collapse; border: none;">
+    <td style="border-collapse: collapse; border: none;">
+      <a href="http://www.openairinterface.org/">
+         <img src="./images/oai_final_logo.png" alt="" border=3 height=50 width=150>
+         </img>
+      </a>
+    </td>
+    <td style="border-collapse: collapse; border: none; vertical-align: center;">
+      <b><font size = "5">L2 nFAPI Simulator (with S1 / same machine deployment)</font></b>
+    </td>
+  </tr>
+</table>
+
+## Table of Contents ##
+
+1.   [Environment](#1-environment)
+2.   [Prepare the EPC](#2-prepare-the-epc)
+3.   [Retrieve the OAI eNB-UE source code](#3-retrieve-the-oai-enb-ue-source-code)
+4.   [Setup of the USIM information in UE folder](#4-setup-of-the-usim-information-in-ue-folder)
+5.   [Setup of the Configuration files](#5-setup-of-the-configuration-files)
+     1.   [The eNB Configuration file](#51-the-enb-configuration-file)
+     2.   [The UE Configuration file](#52-the-ue-configuration-file)
+6.   [Bring Up a second loopback interface](#6-bring-up-a-second-loopback-interface)
+7.   [Build the eNB](#7-build-the-enb)
+8.   [Build the UE](#8-build-the-ue)
+9.   [Initialize the NAS UE Layer](#9-initialize-the-nas-ue-layer)
+10.   [Start the eNB](#10-start-the-enb)
+11.   [Start the UE](#11-start-the-ue)
+12.   [Test with ping](#12-test-with-ping)
+13.   [Limitations](#13-limitations)
+
+# 1. Environment #
+
+2 servers are used in this deployment. You can use Virtual Machines instead of each server; like it is done in the CI process.
+
+*  Machine A contains the EPC.
+*  Machine B contains the OAI eNB and the OAI UE(s)
+
+Example of L2 nFAPI Simulator testing environment:
+
+<img src="../l2-nfapi-simulator/L2-sim-single-server-deployment.png" alt="" border=3>
+
+Note that the IP addresses are indicative and need to be adapted to your environment.
+
+# 2. Prepare the EPC #
+
+Create the environment for the EPC and register all **USIM** information into the **HSS** database.
+
+If you are using OAI-EPC ([see on GitHub](https://github.com/OPENAIRINTERFACE/openair-cn)), build **HSS/MME/SPGW** and create config files.
+
+# 3. Retrieve the OAI eNB-UE source code #
+
+The eNB and the UE executables will compiled into 2 separate folders on the same machine `B`.
+
+```bash
+$ ssh sudousername@machineB
+$ git clone https://gitlab.eurecom.fr/oai/openairinterface5g/ enb_folder
+$ cd enb_folder
+$ git checkout -f v1.0.0
+$ cd ..
+$ cp -Rf enb_folder ue_folder
+```
+
+# 4. Setup of the USIM information in UE folder #
+
+```bash
+$ ssh sudousername@machineB
+$ cd ue_folder
+# Edit openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf with your preferred editor
+```
+
+Edit the USIM information within this file in order to match the HSS database. They **HAVE TO** match:
+
+*  PLMN+MSIN and IMSI of users table of HSS database **SHALL** be the same.
+*  OPC of this file and OPC of users table of HSS database **SHALL** be the same.
+*  USIM_API_K of this file and the key of users table of HSS database **SHALL** be the same.
+
+When testing multiple UEs, it is necessary to add other UEs information like described below for 2 Users. Only UE0 (first UE) information is written in the original file.
+
+```
+UE0:
+{
+    USER: {
+        IMEI="356113022094149";
+        MANUFACTURER="EURECOM";
+        MODEL="LTE Android PC";
+        PIN="0000";
+    };
+
+    SIM: {
+        MSIN="0000000001";  // <-- Modify here
+        USIM_API_K="8baf473f2f8fd09487cccbd7097c6862";
+        OPC="e734f8734007d6c5ce7a0508809e7e9c";
+        MSISDN="33611123456";
+    };
+...
+};
+// Copy the UE0 and edit
+UE1: // <- Edit here
+{
+    USER: {
+        IMEI="356113022094149";
+        MANUFACTURER="EURECOM";
+        MODEL="LTE Android PC";
+        PIN="0000";
+    };
+
+    SIM: {
+        MSIN="0000000002";  // <-- Modify here
+        USIM_API_K="8baf473f2f8fd09487cccbd7097c6862";
+        OPC="e734f8734007d6c5ce7a0508809e7e9c";
+        MSISDN="33611123456";
+    };
+...
+};
+```
+
+You can repeat the operation for as many users you want to test with.
+
+# 5. Setup of the Configuration files #
+
+**CAUTION: both proposed configuration files resides in the ci-scripts realm. You can copy them but you CANNOT push any modification on these 2 files as part of an MR without informing the CI team.**
+
+## 5.1. The eNB Configuration file ##
+
+```bash
+$ ssh sudousername@machineB
+$ cd enb_folder
+# Edit ci-scripts/conf_files/rcc.band7.tm1.nfapi.conf with your preferred editor
+```
+
+First verify the nFAPI interface setup on the 2nd loopback interface.
+
+```
+MACRLCs = (
+        {
+        num_cc = 1;
+        local_s_if_name  = "lo:";            // <-- HERE
+        remote_s_address = "127.0.0.1";      // <-- HERE
+        local_s_address  = "127.0.0.2";      // <-- HERE
+        local_s_portc    = 50001;
+        remote_s_portc   = 50000;
+        local_s_portd    = 50011;
+        remote_s_portd   = 50010;
+        tr_s_preference = "nfapi";
+        tr_n_preference = "local_RRC";
+        }
+);
+```
+
+If you are testing more than 16 UEs, a proper setting on the RUs is necessary. **Note that this part is NOT present in the original configuration file**.
+
+```
+RUs = (
+    {
+       local_rf       = "yes"
+         nb_tx          = 1
+         nb_rx          = 1
+         att_tx         = 20
+         att_rx         = 0;
+         bands          = [38];
+         max_pdschReferenceSignalPower = -23;
+         max_rxgain                    = 116;
+         eNB_instances  = [0];
+    }
+);
+```
+
+Last, the S1 interface shall be properly set.
+
+```
+    ////////// MME parameters:
+    mme_ip_address      = ( { ipv4       = "CI_MME_IP_ADDR"; // replace with 192.168.10.20
+                              ipv6       = "192:168:30::17";
+                              active     = "yes";
+                              preference = "ipv4";
+                            }
+                          );
+
+    NETWORK_INTERFACES :
+    {
+        ENB_INTERFACE_NAME_FOR_S1_MME            = "ens3";            // replace with the proper interface name
+        ENB_IPV4_ADDRESS_FOR_S1_MME              = "CI_ENB_IP_ADDR";  // replace with 192.168.10.10
+        ENB_INTERFACE_NAME_FOR_S1U               = "ens3";            // replace with the proper interface name
+        ENB_IPV4_ADDRESS_FOR_S1U                 = "CI_ENB_IP_ADDR";  // replace with 192.168.10.10
+        ENB_PORT_FOR_S1U                         = 2152; # Spec 2152
+        ENB_IPV4_ADDRESS_FOR_X2C                 = "CI_ENB_IP_ADDR";  // replace with 192.168.10.10
+        ENB_PORT_FOR_X2C                         = 36422; # Spec 36422
+
+    };
+```
+
+## 5.2. The UE Configuration file ##
+
+```bash
+$ ssh sudousername@machineB
+$ cd ue_folder
+# Edit ci-scripts/conf_files/ue.nfapi.conf with your preferred editor
+```
+
+Verify the nFAPI interface setup on the loopback interface.
+
+```
+L1s = (
+        {
+        num_cc = 1;
+        tr_n_preference = "nfapi";
+        local_n_if_name  = "lo";         // <- HERE
+        remote_n_address = "127.0.0.2";  // <- HERE
+        local_n_address  = "127.0.0.1";  // <- HERE
+        local_n_portc    = 50000;
+        remote_n_portc   = 50001;
+        local_n_portd    = 50010;
+        remote_n_portd   = 50011;
+        }
+);
+```
+
+# 6. Bring Up a second loopback interface #
+
+A second loopback interface is used to connect the eNB and the UEs.
+
+```bash
+$ ssh sudousername@machineB
+$ sudo ifconfig lo: 127.0.0.2 netmask 255.0.0.0 up
+```
+
+# 7. [Build OAI UE and eNodeB](BUILD.md) #
+
+
+
+# 8. Initialize the NAS UE Layer #
+
+Start the EPC on machine `A`.
+
+```bash
+$ ssh sudousername@machineA
+# Start the EPC
+```
+
+# 9. Start the eNB #
+
+In the first terminal (the one you used to build the eNB):
+
+```bash
+$ ssh sudousername@machineB
+$ cd enb_folder/cmake_targets
+$ sudo -E ./lte_build_oai/build/lte-softmodem -O ../ci-scripts/conf_files/rcc.band7.tm1.nfapi.conf > enb.log 2>&1
+```
+
+If you don't use redirection, you can test but many logs are printed on the console and this may affect performance of the L2-nFAPI simulator.
+
+We do recommend the redirection in steady mode once your setup is correct.
+
+# 10. Start the UE #
+
+In the second terminal (the one you used to build the UE):
+
+```bash
+$ ssh sudousername@machineB
+$ cd ue_folder/cmake_targets
+# Test 64 UEs, 64 threads in FDD mode
+$ sudo -E ./lte_build_oai/build/lte-uesoftmodem -O ../ci-scripts/conf_files/ue.nfapi.conf --L2-emul 3 --num-ues 64 --nums-ue-thread 64 > ue.log 2>&1
+# Test 64 UEs, 64 threads in TDD mode
+$ sudo -E ./lte_build_oai/build/lte-uesoftmodem -O ../ci-scripts/conf_files/ue.nfapi.conf --L2-emul 3 --num-ues 64 --nums-ue-thread 64 -T 1 > ue.log 2>&1
+# The "-T 1" option means TDD config
+```
+
+-   The number of UEs can set by using `--num-ues` option and the maximum UE number is 255 (with the `--mu*` options, otherwise 16).
+-   The umber of threads can set with the `--nums-ue-thread`. This number **SHALL NOT** be greater than the number of UEs.
+-   How many UE that can be tested depends on hardware (server , PC, etc) performance in your environment.
+
+# 11. Test with ping #
+
+In a third terminal, after around 10 seconds, the UE(s) shall be connected to the eNB:
+
+```bash
+$ ssh sudousername@machineA
+# Ping UE0 IP address based on the EPC pool used: in this example:
+$ ping -c 20 192.168.200.2
+# Ping UE1 IP address based on the EPC pool used: in this example:
+$ ping -c 20 192.168.200.4
+```
+
+# 12. Limitations #
+
+Testing on the CI process is currently limited at time of writing. Improvements will be made soon.
+
+
+
+
+
+
+
+
+
+[oai wiki home](https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/home)
+
+[oai softmodem features](FEATURE_SET.md)
+
+[oai softmodem build procedure](BUILD.md)
+
+[L2 nfapi simulator](L2NFAPI.md)
diff --git a/doc/RUNMODEM.md b/doc/RUNMODEM.md
new file mode 100644
index 0000000000000000000000000000000000000000..de2c53074b680bd7d0f8d7d66611e1dcec0a26cc
--- /dev/null
+++ b/doc/RUNMODEM.md
@@ -0,0 +1,55 @@
+# Running OAI softmodem
+
+After you have [built the softmodem executables](BUILD.md) you can set your default directory  to the build directory `cmake_targets/lte_build_oai/build/` and start testing some use cases. Below, the description of the different oai functionalities should help you choose the oai configuration that suits your need. 
+
+## rf simulator
+
+ The rf simulator is a oai device replacing the radio heads (for example the USRP device). It allows connecting the oai UE and the oai eNodeB through a network interface carrying the time-domain samples, getting rid of over the air unpredictable perturbations. This is the ideal tool to check signal processing algorithms and protocols implementation.
+
+It is planned to enhance this simulator with the following functionalities:
+
+- Support for multiple UE connections,each UE being a `lte-uesoftmodem` instance.
+- Support for multiple eNodeB for hand-over tests
+- Support for channel modeling
+
+   This is an easy use-case to setup and test, as no specific hardware is required. The [rfsimulator page](../targets/ARCH/rfsimulator/README.md ) contains the detailed documentation.
+
+## l2 nfapi simulator
+
+This simulator connects a eNodeB and UEs through a nfapi interface, short-cutting the L1 layer. The objective of this simulator is to allow multi UEs simulation, with a large number of UEs (ideally up to 255 ) .Here to ease the platform setup, UEs are simulated via a single `lte-uesoftmodem` instance. Today the CI tests just with one UE and architecture has to be reviewed to allow a number of UE above about 16. This work is on-going.
+
+  As for the rf simulator, no specific hardware is required. The [L2 nfapi simlator page](L2NFAPI.md) contains the detailed documentation.
+
+## l1 simulator
+
+The l1 simulator is using the ethernet fronthaul protocol, as used to connect a RRU and a RAU to connect UEs and a eNodeB. UEs are simulated in a single `lte-uesoftmodem` process, as for the nfapi simulator. 
+
+The [L1 simulator page](L1SIM.md) contains the detailed documentation.
+
+## noS1 mode
+
+The noS1 mode is now available via the `--noS1`command line option. It can be used with simulators, described above, or when using oai with true RF boards. Only the oai UE can be connected to the oai eNodeB in noS1 mode.
+
+By default the noS1 mode is using linux tun interfaces to send or receive ip packets to/from the linux ip stack. using the `--nokrnmod 0`option you can enforce kernel modules instead of tun.
+
+noS1 code has been revisited, it has been tested with the rf simulator, and tun interfaces. More tests are on going and CI will soon include noS1 tests.
+
+## Running with a true radio head
+
+oai supports [number of deployment](FEATURE_SET.md) model, the following are tested in the CI:
+
+1.  [Monolithic eNodeB](https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/HowToConnectCOTSUEwithOAIeNBNew) where the whole signal processing is performed in a single process
+2. if4p5 mode, where frequency domain samples are carried over ethernet, from the RRU which implement part of L1(FFT,IFFT,part of PRACH),  to a RAU
+
+
+
+
+
+
+
+[oai wiki home](https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/home)
+
+[oai softmodem features](FEATURE_SET.md)
+
+[oai softmodem build procedure](BUILD.md)
+
diff --git a/doc/images/oai_final_logo.png b/doc/images/oai_final_logo.png
new file mode 100644
index 0000000000000000000000000000000000000000..d2cc79f71ff4dd6495c74011a3849b20f54f1927
Binary files /dev/null and b/doc/images/oai_final_logo.png differ
diff --git a/nfapi/open-nFAPI/nfapi/src/nfapi_p7.c b/nfapi/open-nFAPI/nfapi/src/nfapi_p7.c
index 6fe9b47409b1108e11adee776540b1d5cec4506f..2daf1450c852c9bbb7b5ff1003e308903b494ba4 100644
--- a/nfapi/open-nFAPI/nfapi/src/nfapi_p7.c
+++ b/nfapi/open-nFAPI/nfapi/src/nfapi_p7.c
@@ -1545,7 +1545,7 @@ static uint8_t pack_tx_request_body_value(void* tlv, uint8_t **ppWritePackedMsg,
                         // DJP - if(pusharray8(pdu->segments[j].segment_data, (uint32_t)(-1), pdu->segments[j].segment_length, ppWritePackedMsg, end) == 0)
 			int push_ret = pusharray8(pdu->segments[j].segment_data, 65535, pdu->segments[j].segment_length, ppWritePackedMsg, end);
                         
-                        if (pdu->segments[j].segment_length == 3)
+                        if (pdu->segments[j].segment_length == 3)
                         {
                           NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() BCH? segment_data:%x %x %x\n", __FUNCTION__, 
                           pdu->segments[j].segment_data[0], 
@@ -4429,43 +4429,43 @@ static uint8_t unpack_tx_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *
 				for(i = 0; i < totalNumPdus; ++i)
 				{
 					nfapi_tx_request_pdu_t* pdu = &(pNfapiMsg->tx_request_body.tx_pdu_list[i]);
-					if (pdu) {
-					  uint16_t length = 0;
-					  uint16_t index = 0;
+					if (pdu) {
+					  uint16_t length = 0;
+					  uint16_t index = 0;
 					
-					  if(!(pull16(ppReadPackedMsg, &length, end) &&
+					  if(!(pull16(ppReadPackedMsg, &length, end) &&
 						 pull16(ppReadPackedMsg, &index, end)))
-						  return 0;
+						  return 0;
 
-					  pdu->pdu_length = length;
-					  pdu->pdu_index = index;
+                                          pdu->pdu_length = length;
+                                          pdu->pdu_index = index;
 					
 
 					// TODO : May need to rethink this bit
-					  pdu->num_segments = 1;
-					  pdu->segments[0].segment_length = pdu->pdu_length;
-					  pdu->segments[0].segment_data = nfapi_p7_allocate(pdu->pdu_length, config);
+					  pdu->num_segments = 1;
+					  pdu->segments[0].segment_length = pdu->pdu_length;
+					  pdu->segments[0].segment_data = nfapi_p7_allocate(pdu->pdu_length, config);
 
-					  if(pdu->segments[0].segment_data)
-					  {
-						  if(!pullarray8(ppReadPackedMsg, pdu->segments[0].segment_data, pdu->segments[0].segment_length, pdu->segments[0].segment_length, end))
+					  if(pdu->segments[0].segment_data)
+					  {
+						  if(!pullarray8(ppReadPackedMsg, pdu->segments[0].segment_data, pdu->segments[0].segment_length, pdu->segments[0].segment_length, end))
 							return 0;
-                                                  if (pdu->segments[0].segment_length == 3)
-                                                  {
+                                                  if (pdu->segments[0].segment_length == 3)
+                                                  {
                                                   NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() BCH? segment_data:%x %x %x\n", __FUNCTION__, 
                                                       pdu->segments[0].segment_data[0], 
                                                       pdu->segments[0].segment_data[1], 
                                                       pdu->segments[0].segment_data[2]
                                                       );
-                                                  }
-					  }
-					  else
-					  {
+                                                  }
+					  }
+					  else
+					  {
 						NFAPI_TRACE(NFAPI_TRACE_ERROR, "unpack_tx_request: Failed to allocate pdu (len:%d) %d/%d %d\n", pdu->pdu_length, totalNumPdus, i, pdu->pdu_index);
-					  }
-                                      } else {
-                                          NFAPI_TRACE(NFAPI_TRACE_ERROR, "NULL pdu\n");
-                                      }
+					  }
+                                      } else {
+                                          NFAPI_TRACE(NFAPI_TRACE_ERROR, "NULL pdu\n");
+                                      }
 				}
 			}
 			break;
diff --git a/openair1/PHY/CODING/crc_byte.c b/openair1/PHY/CODING/crc_byte.c
index 06a43fdb79242eed9636c489c00d6ef9c55758d3..29bddeb2cbb097f3d2496ef086c42749b59b3415 100644
--- a/openair1/PHY/CODING/crc_byte.c
+++ b/openair1/PHY/CODING/crc_byte.c
@@ -88,17 +88,17 @@ uint32_t crcbit (uint8_t * inputptr, int32_t octetlen, uint32_t poly)
 
  // Reference 38.212 V15.1.1 Section 5.1 (36-212 v8.6.0 , pp 8-9)
 // The highest degree is set by default
-// 1000 0110 0100 1100 1111 1011  D^24 + D^23 + D^18 + D^17 + D^14 + D^11 + D^10 + D^7 + D^6 + D^5 + D^4 + D^3 + D + 1 
+// 1000 0110 0100 1100 1111 1011  D^24 + D^23 + D^18 + D^17 + D^14 + D^11 + D^10 + D^7 + D^6 + D^5 + D^4 + D^3 + D + 1
 static const uint32_t poly24a = 0x864cfb00;
-// 1000 0000 0000 0000 0110 0011  D^24 + D^23 + D^6 + D^5 + D + 1 
+// 1000 0000 0000 0000 0110 0011  D^24 + D^23 + D^6 + D^5 + D + 1
 static const uint32_t poly24b = 0x80006300;
-// 0001 0000 0010 0001            D^16 + D^12 + D^5 + 1 
+// 0001 0000 0010 0001            D^16 + D^12 + D^5 + 1
 static const uint32_t poly16  = 0x10210000;
-// 1000 0000 1111                 D^12 + D^11 + D^3 + D^2 + D + 1 
+// 1000 0000 1111                 D^12 + D^11 + D^3 + D^2 + D + 1
 static const uint32_t poly12  = 0x80F00000;
-// 1001 1011                      D^8  + D^7  + D^4 + D^3 + D + 1 
+// 1001 1011                      D^8  + D^7  + D^4 + D^3 + D + 1
 static const uint32_t poly8   = 0x9B000000;
- 
+
 void crcTableInit (void)
 {
     uint8_t c = 0;
diff --git a/openair1/PHY/INIT/init_top.c b/openair1/PHY/INIT/init_top.c
index 698f34833d7d12995596530d3cc573d246816fa6..6421eebe28a0cda990683148489eda7633233433 100644
--- a/openair1/PHY/INIT/init_top.c
+++ b/openair1/PHY/INIT/init_top.c
@@ -83,4 +83,4 @@ void free_lte_top(void) {
 
 
 /*
-   @}*/
+ * @}*/
diff --git a/openair1/PHY/INIT/lte_init.c b/openair1/PHY/INIT/lte_init.c
index 6a062abcaee94bf06cbb217259be716eb3107c65..c39a81c7a54ac38b5f4018123ca9d2804a8f1004 100644
--- a/openair1/PHY/INIT/lte_init.c
+++ b/openair1/PHY/INIT/lte_init.c
@@ -965,3 +965,4 @@ void install_schedule_handlers(IF_Module_t *if_inst)
   if_inst->PHY_config_req = phy_config_request;
   if_inst->schedule_response = schedule_response;
 }
+
diff --git a/openair1/PHY/INIT/lte_init_ue.c b/openair1/PHY/INIT/lte_init_ue.c
index 1361c41087de62efeb04bd809add2ad929028104..bd3aefb1c36c847005bab1ab9918952e8f407170 100644
--- a/openair1/PHY/INIT/lte_init_ue.c
+++ b/openair1/PHY/INIT/lte_init_ue.c
@@ -974,4 +974,4 @@ void init_lte_ue_transport(PHY_VARS_UE *ue,int abstraction_flag) {
 
   ue->dlsch_MCH[0]  = new_ue_dlsch(1,NUMBER_OF_HARQ_PID_MAX,NSOFT,MAX_TURBO_ITERATIONS_MBSFN,ue->frame_parms.N_RB_DL,0);
 
-}
+}
\ No newline at end of file
diff --git a/openair1/PHY/LTE_ESTIMATION/lte_sync_time.c b/openair1/PHY/LTE_ESTIMATION/lte_sync_time.c
index 87abdfe19cb67567344ec6507b807290c8a2e33e..faffa3d88aadd282c27212aa9f48d5e5a029ad73 100644
--- a/openair1/PHY/LTE_ESTIMATION/lte_sync_time.c
+++ b/openair1/PHY/LTE_ESTIMATION/lte_sync_time.c
@@ -567,6 +567,31 @@ int lte_sync_time_eNB(int32_t **rxdata, ///rx data in time domain
 
 }
 
+#ifdef PHY_ABSTRACTION
+#include "SIMULATION/TOOLS/defs.h"
+#include "SIMULATION/RF/defs.h"
+//extern channel_desc_t *UE2eNB[NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX];
+
+int lte_sync_time_eNB_emul(PHY_VARS_eNB *phy_vars_eNB,
+                           uint8_t sect_id,
+                           int32_t *sync_val)
+{
+
+  uint8_t UE_id;
+  uint8_t CC_id = phy_vars_eNB->CC_id;
 
+  LOG_E(PHY,"[PHY] EMUL lte_sync_time_eNB_emul eNB %d, sect_id %d\n",phy_vars_eNB->Mod_id,sect_id);
+  *sync_val = 0;
 
+  for (UE_id=0; UE_id<NB_UE_INST; UE_id++) {
+    //LOG_E(PHY,"[PHY] EMUL : eNB %d checking UE %d (PRACH %d) PL %d dB\n",phy_vars_eNB->Mod_id,UE_id,PHY_vars_UE_g[UE_id]->generate_prach,UE2eNB[UE_id][phy_vars_eNB->Mod_id]->path_loss_dB);
+    if ((PHY_vars_UE_g[UE_id][CC_id]->generate_prach == 1) && (phy_vars_eNB->Mod_id == (UE_id % NB_eNB_INST))) {
+      *sync_val = 1;
+      return(0);
+    }
+  }
+
+  return(-1);
+}
+#endif
 
diff --git a/openair1/PHY/LTE_TRANSPORT/dci_tools.c b/openair1/PHY/LTE_TRANSPORT/dci_tools.c
index fc05aa649124f94fa9609649b3b9bc0b20b74c10..87720199ee91397cf596d40ab3d3101411facc8c 100644
--- a/openair1/PHY/LTE_TRANSPORT/dci_tools.c
+++ b/openair1/PHY/LTE_TRANSPORT/dci_tools.c
@@ -352,7 +352,7 @@ void fill_dci_and_dlsch(PHY_VARS_eNB *eNB,int frame,int subframe,L1_rxtx_proc_t
                 &rel8->resource_block_coding,rel8->resource_block_coding,rel8->rnti,rel8->rnti_type,rel8->dci_format,rel8->harq_process);
   
     dci_alloc->format = format1A;
-    
+
     switch (fp->N_RB_DL) {
     case 6:
       if (fp->frame_type == TDD) {
@@ -1726,8 +1726,8 @@ void fill_mdci_and_dlsch(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc,mDCI_ALLOC_t *dc
   dlsch0->subframe_tx[(subframe + 2) % 10] = 1;
   LOG_D(PHY,"PDSCH : resource_block_coding %x\n",rel13->resource_block_coding);
 
-  conv_eMTC_rballoc (rel13->resource_block_coding, 
-		     fp->N_RB_DL, 
+  conv_eMTC_rballoc (rel13->resource_block_coding,
+		     fp->N_RB_DL,
 		     dlsch0_harq->rb_alloc);
 
   dlsch0_harq->nb_rb = RIV2nb_rb_LUT6[rel13->resource_block_coding & 31];       // this is the 6PRB RIV
@@ -1767,7 +1767,7 @@ void fill_mdci_and_dlsch(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc,mDCI_ALLOC_t *dc
     else if (rel13->tpc == 0)  //N1A_PRB=2, get TBS from table using mcs and nb_rb=2
       dlsch0_harq->TBS         = TBStable[get_I_TBS(dlsch0_harq->mcs)][1];
     else if (rel13->tpc == 1)  //N1A_PRB=3, get TBS from table using mcs and nb_rb=3
-      dlsch0_harq->TBS         = TBStable[get_I_TBS(dlsch0_harq->mcs)][2];      
+      dlsch0_harq->TBS         = TBStable[get_I_TBS(dlsch0_harq->mcs)][2];
     LOG_D(PHY,"TBS = %d(%d)\n",dlsch0_harq->TBS,dlsch0_harq->mcs);
   }
   dlsch0->active = 1;
@@ -1968,7 +1968,7 @@ void fill_dci0(PHY_VARS_eNB *eNB,int frame,int subframe,L1_rxtx_proc_t *proc,
 
 #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
 int get_narrowband_index(int N_RB_UL,int rb) {
-  
+
   switch (N_RB_UL) {
   case 6: // 6 PRBs, N_NB=1, i_0=0
   case 25: // 25 PRBs, N_NB=4, i_0=0
@@ -2116,7 +2116,7 @@ void fill_ulsch(PHY_VARS_eNB *eNB,int UE_id,nfapi_ul_config_ulsch_pdu *ulsch_pdu
 #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
 
 int get_first_rb_in_narrowband(int N_RB_UL,int rb) {
-  
+
   switch (N_RB_UL) {
   case 6: // 6 PRBs, N_NB=1, i_0=0
   case 25: // 25 PRBs, N_NB=4, i_0=0
@@ -2288,6 +2288,3 @@ void fill_mpdcch_dci0 (PHY_VARS_eNB * eNB, L1_rxtx_proc_t * proc, mDCI_ALLOC_t *
   }
 }
 #endif
-
-
-
diff --git a/openair1/PHY/LTE_TRANSPORT/dci_tools_common.c b/openair1/PHY/LTE_TRANSPORT/dci_tools_common.c
index dbf5814f30ef2366ddcc6dbf930c8ca69999f7b9..583d12eedb4a6d86f99e4ec9bbddcc4f0fc80b6e 100644
--- a/openair1/PHY/LTE_TRANSPORT/dci_tools_common.c
+++ b/openair1/PHY/LTE_TRANSPORT/dci_tools_common.c
@@ -367,11 +367,11 @@ void conv_rballoc(uint8_t ra_header,uint32_t rb_alloc,uint32_t N_RB_DL,uint32_t
 	if ((rb_alloc&(1<<i)) != 0)
 	  rb_alloc2[(3*(16-i))>>5] |= (7<<((3*(16-i))%32));
       }
-      
+
       // bit mask across
       if ((rb_alloc2[0]>>31)==1)
 	rb_alloc2[1] |= 1;
-      
+
       if ((rb_alloc&1) != 0)
 	rb_alloc2[1] |= (3<<16);
     }
@@ -385,7 +385,7 @@ void conv_rballoc(uint8_t ra_header,uint32_t rb_alloc,uint32_t N_RB_DL,uint32_t
       for (i=0; i<25; i++) {
 	if ((rb_alloc&(1<<(24-i))) != 0)
 	  rb_alloc2[(4*i)>>5] |= (0xf<<((4*i)%32));
-	
+
 	//  printf("rb_alloc2[%d] (type 0) %x (%d)\n",(4*i)>>5,rb_alloc2[(4*i)>>5],rb_alloc&(1<<i));
       }
     }
diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c
index 0b27392fd1e9a1f5b974c8f7af2853937e837ccf..e8b56f3bdfe99292b3a5db85d91b5d99f1fba697 100644
--- a/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c
+++ b/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c
@@ -2034,7 +2034,7 @@ int allocate_REs_in_RB_MCH(int32_t **txdataF,
 
     break;
     default:
-        LOG_E(PHY,"Invalid modulation order %i_n",mod_order); 
+        LOG_E(PHY,"Invalid modulation order %i_n",mod_order);
     break;
     }
   }
diff --git a/openair1/PHY/LTE_TRANSPORT/prach.c b/openair1/PHY/LTE_TRANSPORT/prach.c
index 2639e318c9e117a8025e9d7984b919826ac8456e..1d665682e01e0d80ea098601da3b72353b165ddb 100644
--- a/openair1/PHY/LTE_TRANSPORT/prach.c
+++ b/openair1/PHY/LTE_TRANSPORT/prach.c
@@ -96,14 +96,14 @@ void rx_prach0(PHY_VARS_eNB *eNB,
   int prach_ifft_cnt=0;
 #endif
 
-  
+
   if(eNB)  {
     fp    = &(eNB->frame_parms);
     nb_rx = fp->nb_antennas_rx;
   } else {
     fp    = &(ru->frame_parms);
     nb_rx = ru->nb_rx;
-  } 
+  }
   AssertFatal(fp!=NULL,"rx_prach called without valid RU or eNB descriptor\n");
 
   frame_type          = fp->frame_type;
@@ -154,7 +154,7 @@ void rx_prach0(PHY_VARS_eNB *eNB,
 
       if (LOG_DEBUGFLAG(PRACH)){
         if (((eNB->proc.frame_prach)&1023) < 20) LOG_I(PHY,"PRACH (eNB) : running rx_prach (br_flag %d, ce_level %d) for frame %d subframe %d, prach_FreqOffset %d, prach_ConfigIndex %d, rootSequenceIndex %d, repetition number %d,numRepetitionsPrePreambleAttempt %d\n",
-			  	     br_flag,ce_level,eNB->proc.frame_prach,subframe,
+               br_flag,ce_level,eNB->proc.frame_prach,subframe,
 				     fp->prach_emtc_config_common.prach_ConfigInfo.prach_FreqOffset[ce_level],
 				     prach_ConfigIndex,rootSequenceIndex,
 				     eNB->prach_vars_br.repetition_number[ce_level],
diff --git a/openair1/PHY/LTE_TRANSPORT/prach_common.c b/openair1/PHY/LTE_TRANSPORT/prach_common.c
index 7e38d6a5907c9cb7fc25682b6b602c338f9deacb..5f7a904db16f522a8a34972063c0e2f5ffde9235 100644
--- a/openair1/PHY/LTE_TRANSPORT/prach_common.c
+++ b/openair1/PHY/LTE_TRANSPORT/prach_common.c
@@ -573,7 +573,7 @@ int is_prach_subframe(LTE_DL_FRAME_PARMS *frame_parms, uint32_t frame, uint8_t s
 #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
   for (int i=0; i<4; i++) {
     if (frame_parms->prach_emtc_config_common.prach_ConfigInfo.prach_CElevel_enable[i] == 1) 
-      prach_mask |= (is_prach_subframe0(frame_parms, frame_parms->prach_emtc_config_common.prach_ConfigInfo.prach_ConfigIndex[i], 
+      prach_mask |= (is_prach_subframe0(frame_parms, frame_parms->prach_emtc_config_common.prach_ConfigInfo.prach_ConfigIndex[i],
                                         frame, subframe) << (i+1));
   }
 #endif
diff --git a/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c b/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c
index b0d71e683003e941463c7a4ed646cce31f0e5205..1dcbec06640dbd34d638159d9eb2fb01fc958e37 100644
--- a/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c
+++ b/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c
@@ -748,7 +748,7 @@ unsigned int  ulsch_decoding(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc,
     }
 
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_ULSCH_DECODING0+harq_pid,1);
-  
+
   // x1 is set in lte_gold_generic
   x2 = ((uint32_t)ulsch->rnti<<14) + ((uint32_t)subframe<<9) + frame_parms->Nid_cell; //this is c_init in 36.211 Sec 6.3.1
   ulsch_harq = ulsch->harq_processes[harq_pid];
diff --git a/openair1/PHY/LTE_UE_TRANSPORT/dci_tools_ue.c b/openair1/PHY/LTE_UE_TRANSPORT/dci_tools_ue.c
index 89f0016c2396499fa55e03f9d95c6de34e695c01..dbade04739d562437862a70ace7ab0e28634278a 100644
--- a/openair1/PHY/LTE_UE_TRANSPORT/dci_tools_ue.c
+++ b/openair1/PHY/LTE_UE_TRANSPORT/dci_tools_ue.c
@@ -46,6 +46,7 @@
 
 //#define DEBUG_DCI
 
+
 #include "../LTE_TRANSPORT/dci_tools_common_extern.h"
 #include "../LTE_TRANSPORT/transport_proto.h"
 #include "transport_proto_ue.h"
@@ -1281,7 +1282,7 @@ void compute_llr_offset(LTE_DL_FRAME_PARMS *frame_parms,
         symbol_mod = (symbol >= (7-frame_parms->Ncp))? (symbol-(7-frame_parms->Ncp)) : symbol;
         if((symbol_mod == 0) || symbol_mod == (4-frame_parms->Ncp))
         {
-	  if (frame_parms->nb_antenna_ports_eNB == 2) 
+	  if (frame_parms->nb_antenna_ports_eNB == 2)
 	    crs_re = 4;
 	  else
 	    crs_re = 2;
diff --git a/openair1/PHY/LTE_UE_TRANSPORT/dlsch_llr_computation.c b/openair1/PHY/LTE_UE_TRANSPORT/dlsch_llr_computation.c
index 55407d8e2dcea9e8016f7bb3ca6be98054f390fb..4c74377ef6f4a323df9d96b46e993beadeac2908 100644
--- a/openair1/PHY/LTE_UE_TRANSPORT/dlsch_llr_computation.c
+++ b/openair1/PHY/LTE_UE_TRANSPORT/dlsch_llr_computation.c
@@ -672,7 +672,7 @@ int dlsch_qpsk_llr(LTE_DL_FRAME_PARMS *frame_parms,
     len = (nb_rb*12) - pbch_pss_sss_adjust;
   }
 
-  
+
   LOG_D(PHY,"[p %d : symb %d / FirstSym %d / Length %d]: @LLR Buff %p, @LLR Buff(symb) %p \n",
 	frame_parms->nb_antenna_ports_eNB,
 	symbol,
@@ -680,7 +680,7 @@ int dlsch_qpsk_llr(LTE_DL_FRAME_PARMS *frame_parms,
 	len,
 	dlsch_llr,
 	llr32);
- 
+
 
   qpsk_llr((short *)rxF,
            (short *)llr32,
diff --git a/openair1/PHY/LTE_UE_TRANSPORT/pch_ue.c b/openair1/PHY/LTE_UE_TRANSPORT/pch_ue.c
index aed3ddabc15b6279393c7405961edde780c51cd2..972dd839056a6d854fd61dc8ce8801a3f415985b 100644
--- a/openair1/PHY/LTE_UE_TRANSPORT/pch_ue.c
+++ b/openair1/PHY/LTE_UE_TRANSPORT/pch_ue.c
@@ -48,7 +48,7 @@ int init_ue_paging_info(PHY_VARS_UE *ue, long defaultPagingCycle, long nB) {
    else if (Ns==4)
      ue->PO = (fp->frame_type==FDD) ? (4*(i_s&1)+(5*(i_s>>1))) : ((i_s&1)+(5*(i_s>>1))); 
    else
-     AssertFatal(1==0,"init_ue_paging_info: Ns is %d\n",Ns);
+     AssertFatal(1==0,"init_ue_paging_info: Ns is %u\n",Ns);
 
    return(0);
 }
diff --git a/openair1/PHY/defs_eNB.h b/openair1/PHY/defs_eNB.h
index 271d54fdce5c9eaa20a3376611f5089af4f06018..d3157d5e822c8141b8ec9d24d26471c88aff3012 100644
--- a/openair1/PHY/defs_eNB.h
+++ b/openair1/PHY/defs_eNB.h
@@ -312,6 +312,10 @@ typedef struct RU_t_s{
   LTE_DL_FRAME_PARMS frame_parms;
   ///timing offset used in TDD
   int              N_TA_offset; 
+  /// SF extension used in TDD (unit: number of samples at 30.72MHz) (this is an expert option)
+  int              sf_extension;
+  /// "end of burst delay" used in TDD (unit: number of samples at 30.72MHz) (this is an expert option)
+  int              end_of_burst_delay;
   /// RF device descriptor
   openair0_device rfdevice;
   /// HW configuration
diff --git a/openair1/README.TXT b/openair1/README.TXT
index 69912b4ecff0d7d98bd84ed1643ca79f94c0d3ae..98ec8984c425a3683070f42b91f3166f70feacad 100644
--- a/openair1/README.TXT
+++ b/openair1/README.TXT
@@ -9,7 +9,7 @@ General remarks: every directory contains at least defs.h (for declaration of st
 |   |-- INIT		   // variables defined in vars.h are initialzed here (memory allocation)
 |   |-- LTE_ESTIMATION     // estimation for LTE
 |   |-- LTE_REFSIG 	   // reference signals for LTE (sync and pilot sequences) reference signals from 36-211 
-|   |-- NR_REFSIG 	   // reference signals for NR (sync and pilot sequences) reference signals from 38-211 
+|   |-- NR_REFSIG 	   // reference signals for NR (sync and pilot sequences) reference signals from 38-211
 |   |-- LTE_TRANSPORT      // these are the top level routines for different transport and physical channels (for example DL-SCH, PSS) implements a subset of 36-211,36-212
 |   |-- LTE_UE_TRANSPORT      // these are the top level routines for different transport and physical channels (for example DL-SCH, PSS) implements a subset of 36-211,36-212
 |   |-- NR_TRANSPORT      // these are the top level routines for different transport and physical channels (for example DL-SCH, PSS) implements a subset of 38-211,38-212
@@ -27,18 +27,18 @@ General remarks: every directory contains at least defs.h (for declaration of st
 |   |-- spec_defs_top.h
 |   |-- types.h
 |   `-- vars.h		  
-|-- SCHED		  // schedules the different LTE eNB functions 
+|-- SCHED		  // schedules the different LTE eNB functions
 |   |-- defs.h
 |   |-- extern.h
 |   |-- phy_procedures_lte_eNb.c // LTE PHY procedures for eNB (from 36-213) 
 |   |-- phy_procedures_lte_common.c  // LTE PHY procedures common for UE and eNB (from 36-213)
 |   |-- prach_procedures.c  //LTE PRACH  procedures (from 36-213)
-|   |-- ru_procedures.c  //RU  procedures 
+|   |-- ru_procedures.c  //RU  procedures
 |   |-- fapi_l1.c  //L1 side of the FAPI interface
 |   |-- phy_mac_stub.c  //MAC stub that generates channels when used in phy-test-mode
 |   |-- rt_compat.h
 |   `-- vars.h
-|-- SCHED_UE		  // schedules the different LTE UE functions 
+|-- SCHED_UE		  // schedules the different LTE UE functions
 |   |-- phy_procedures_lte_ue.c  // LTE PHY procedures for UE (from 36-213)
 |   |-- pucch_pc.c // power control for PUCCH
 |   |-- pusch_pc.c // power control for PUSCH
@@ -53,7 +53,7 @@ General remarks: every directory contains at least defs.h (for declaration of st
 |   |   |-- dlsim.c         // PDSCH simulation testbench
 |   |   |-- ulsim.c         // PUSCH simulation testbench
 |   |   |-- pucchsim.c      // PUCCH simulation testbench
-|   |-- RF  		    // RF simulation tools 
+|   |-- RF  		    // RF simulation tools
 |   |-- ETH_TRANSPORT
 |   `-- TOOLS
 
diff --git a/openair1/SIMULATION/LTE_PHY/common_sim.h b/openair1/SIMULATION/LTE_PHY/common_sim.h
index e9ad4dc888f8573874d8aa1f8d4bf271978d8196..ff8406b0c1a4cab7f759a7aa1573f20752b050ad 100644
--- a/openair1/SIMULATION/LTE_PHY/common_sim.h
+++ b/openair1/SIMULATION/LTE_PHY/common_sim.h
@@ -25,7 +25,7 @@ void dumpVarArray(varArray_t *input) {
   printf("\n");
 }
 void sumUpStats(time_stats_t * res, time_stats_t * src, int lastActive) {
-  	reset_meas(res);
+  reset_meas(res);
 	for (int i=0; i<RX_NB_TH; i++) {
 	  res->diff+=src[i].diff;
 	  res->diff_square+=src[i].diff_square;
@@ -36,7 +36,7 @@ void sumUpStats(time_stats_t * res, time_stats_t * src, int lastActive) {
 	res->p_time=src[lastActive].p_time;
 }
 void sumUpStatsSlot(time_stats_t *res, time_stats_t src[RX_NB_TH][2], int lastActive) {
-  	reset_meas(res);
+  reset_meas(res);
 	for (int i=0; i<RX_NB_TH; i++) {
 	  res->diff+=src[i][0].diff+src[i][1].diff;
 	  res->diff_square+=src[i][0].diff_square+src[i][1].diff_square;
@@ -94,7 +94,7 @@ void logDistribution(FILE* fd, time_stats_t *ptr, varArray_t *sortedList, int dr
 	  squareRoot(ptr),
 	  (double)ptr->max, *(double*)dataArray(sortedList),
 	  median(sortedList),q1(sortedList),q3(sortedList),
-	  dropped); 
+	  dropped);
 }
 
 struct option * parse_oai_options(paramdef_t *options) {
@@ -125,7 +125,7 @@ struct option * parse_oai_options(paramdef_t *options) {
       case TYPE_UINT16:
 	*options[i].u16ptr=options[i].defintval;
 	break;
-	
+
       default:
 	printf("not parsed type for default value %s\n", options[i].optname );
 	exit(1);
@@ -155,11 +155,11 @@ void display_options_values(paramdef_t *options, int verbose) {
 	case TYPE_UINT8:
 	  sprintf(varText,"%d",(int)*ptr->u8ptr);
 	  break;
-	  
+
 	case TYPE_UINT16:
 	  sprintf(varText,"%d",(int)*ptr->u16ptr);
 	  break;
-	  
+
 	default:
 	  printf("not decoded type\n");
 	  exit(1);
diff --git a/openair1/SIMULATION/LTE_PHY/dlsim_tm7.c b/openair1/SIMULATION/LTE_PHY/dlsim_tm7.c
index 87b17fbf3f8c25a75b71b464fbfe33d57293453b..5973f80b55a59f662490e960cb5f295e3ae2267b 100644
--- a/openair1/SIMULATION/LTE_PHY/dlsim_tm7.c
+++ b/openair1/SIMULATION/LTE_PHY/dlsim_tm7.c
@@ -3167,7 +3167,7 @@ PMI_FEEDBACK:
 
                         if (n_frames==1)
                           printf("DCI misdetection trial %u\n",trials);
->>>>>>> new set of cppcheck fixes
+
                       }
 
                       //      for (i=1;i<=round;i++)
diff --git a/openair1/SIMULATION/LTE_PHY/unitary_defs.h b/openair1/SIMULATION/LTE_PHY/unitary_defs.h
index 1f91df1306e0f71e0165bec462c482b9130703c3..10a5366082fbf61fe9b47430cc4c91cc1a811c75 100644
--- a/openair1/SIMULATION/LTE_PHY/unitary_defs.h
+++ b/openair1/SIMULATION/LTE_PHY/unitary_defs.h
@@ -22,10 +22,10 @@
 openair0_device openair0;
 volatile int oai_exit=0;
 
-void exit_function(const char* file, const char* function, const int line,const char *s) { 
+void exit_function(const char* file, const char* function, const int line,const char *s) {
    const char * msg= s==NULL ? "no comment": s;
-   printf("Exiting at: %s:%d %s(), %s\n", file, line, function, msg); 
-   exit(-1); 
+   printf("Exiting at: %s:%d %s(), %s\n", file, line, function, msg);
+   exit(-1);
 }
 
 extern unsigned int dlsch_tbs25[27][25],TBStable[27][110];
diff --git a/openair2/COMMON/f1ap_messages_def.h b/openair2/COMMON/f1ap_messages_def.h
new file mode 100644
index 0000000000000000000000000000000000000000..9e341f9bcbc87c2a19f1e28ba7d994b31153f96a
--- /dev/null
+++ b/openair2/COMMON/f1ap_messages_def.h
@@ -0,0 +1,48 @@
+/*
+ * 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
+ */
+
+/* F1AP -> SCTP */
+MESSAGE_DEF(F1AP_CU_SCTP_REQ        , MESSAGE_PRIORITY_MED, f1ap_cu_setup_req_t       , f1ap_cu_setup_req)
+
+/* eNB_DU application layer -> F1AP messages or CU F1AP -> RRC*/
+MESSAGE_DEF(F1AP_SETUP_REQ          , MESSAGE_PRIORITY_MED, f1ap_setup_req_t          , f1ap_setup_req)
+
+/* F1AP -> eNB_DU or eNB_CU_RRC -> F1AP application layer messages */
+MESSAGE_DEF(F1AP_SETUP_RESP         , MESSAGE_PRIORITY_MED, f1ap_setup_resp_t          , f1ap_setup_resp)
+MESSAGE_DEF(F1AP_SETUP_FAILURE         , MESSAGE_PRIORITY_MED, f1ap_setup_failure_t          , f1ap_setup_failure)
+
+/* MAC -> F1AP messages */
+MESSAGE_DEF(F1AP_INITIAL_UL_RRC_MESSAGE           , MESSAGE_PRIORITY_MED, f1ap_initial_ul_rrc_message_t             , f1ap_initial_ul_rrc_message)
+MESSAGE_DEF(F1AP_UL_RRC_MESSAGE                , MESSAGE_PRIORITY_MED, f1ap_ul_rrc_message_t                , f1ap_ul_rrc_message)
+//MESSAGE_DEF(F1AP_INITIAL_CONTEXT_SETUP_RESP, MESSAGE_PRIORITY_MED, f1ap_initial_context_setup_resp_t, f1ap_initial_context_setup_resp)
+//MESSAGE_DEF(F1AP_INITIAL_CONTEXT_SETUP_FAILURE, MESSAGE_PRIORITY_MED, f1ap_initial_context_setup_failure_t, f1ap_initial_context_setup_failure)
+MESSAGE_DEF(F1AP_UE_CONTEXT_RELEASE_REQ, MESSAGE_PRIORITY_MED, f1ap_ue_context_release_req_t, f1ap_ue_context_release_req)
+MESSAGE_DEF(F1AP_UE_CONTEXT_RELEASE_CMD, MESSAGE_PRIORITY_MED, f1ap_ue_context_release_cmd_t, f1ap_ue_context_release_cmd)
+
+
+/* RRC -> F1AP  messages */
+MESSAGE_DEF(F1AP_DL_RRC_MESSAGE              , MESSAGE_PRIORITY_MED, f1ap_dl_rrc_message_t              , f1ap_dl_rrc_message )
+//MESSAGE_DEF(F1AP_INITIAL_CONTEXT_SETUP_REQ , MESSAGE_PRIORITY_MED, f1ap_initial_context_setup_req_t , f1ap_initial_context_setup_req )
+MESSAGE_DEF(F1AP_UE_CONTEXT_SETUP_REQ, MESSAGE_PRIORITY_MED, f1ap_ue_context_setup_req_t, f1ap_ue_context_setup_req)
+
+
+
+
diff --git a/openair2/COMMON/f1ap_messages_types.h b/openair2/COMMON/f1ap_messages_types.h
new file mode 100644
index 0000000000000000000000000000000000000000..d83f9cb71d74c9f00ba6ef2a6d7ee32e1665103a
--- /dev/null
+++ b/openair2/COMMON/f1ap_messages_types.h
@@ -0,0 +1,308 @@
+/*
+ * 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
+ */
+
+#ifndef F1AP_MESSAGES_TYPES_H_
+#define F1AP_MESSAGES_TYPES_H_
+
+#include "rlc.h"
+
+//-------------------------------------------------------------------------------------------//
+// Defines to access message fields.
+
+#define F1AP_CU_SCTP_REQ(mSGpTR)                   (mSGpTR)->ittiMsg.f1ap_cu_sctp_req
+
+#define F1AP_SETUP_REQ(mSGpTR)                     (mSGpTR)->ittiMsg.f1ap_setup_req
+#define F1AP_SETUP_RESP(mSGpTR)                    (mSGpTR)->ittiMsg.f1ap_setup_resp
+#define F1AP_SETUP_FAILURE(mSGpTR)                 (mSGpTR)->ittiMsg.f1ap_setup_failure
+
+#define F1AP_INITIAL_UL_RRC_MESSAGE(mSGpTR)        (mSGpTR)->ittiMsg.f1ap_initial_ul_rrc_message
+#define F1AP_UL_RRC_MESSAGE(mSGpTR)                (mSGpTR)->ittiMsg.f1ap_ul_rrc_message
+#define F1AP_UE_CONTEXT_SETUP_REQ(mSGpTR)          (mSGpTR)->ittiMsg.f1ap_ue_context_setup_req
+#define F1AP_UE_CONTEXT_RELEASE_RESP(mSGpTR)       (mSGpTR)->ittiMsg.f1ap_ue_context_release_resp
+#define F1AP_UE_CONTEXT_MODIFICATION_RESP(mSGpTR)  (mSGpTR)->ittiMsg.f1ap_ue_context_modification_resp
+#define F1AP_UE_CONTEXT_MODIFICATION_FAIL(mSGpTR)  (mSGpTR)->ittiMsg.f1ap_ue_context_modification_fail
+
+#define F1AP_DL_RRC_MESSAGE(mSGpTR)                (mSGpTR)->ittiMsg.f1ap_dl_rrc_message
+#define F1AP_UE_CONTEXT_RELEASE_REQ(mSGpTR)        (mSGpTR)->ittiMsg.f1ap_ue_context_release_req
+#define F1AP_UE_CONTEXT_RELEASE_CMD(mSGpTR)        (mSGpTR)->ittiMsg.f1ap_ue_context_release_req
+#define F1AP_UE_CONTEXT_MODIFICATION_REQ(mSGpTR)   (mSGpTR)->ittiMsg.f1ap_ue_context_modification_req
+
+/* Length of the transport layer address string
+ * 160 bits / 8 bits by char.
+ */
+#define F1AP_TRANSPORT_LAYER_ADDRESS_SIZE (160 / 8)
+
+#define F1AP_MAX_NB_CU_IP_ADDRESS 10
+
+// Note this should be 512 from maxval in 38.473
+#define F1AP_MAX_NB_CELLS 2
+
+typedef struct f1ap_net_ip_address_s {
+  unsigned ipv4:1;
+  unsigned ipv6:1;
+  char ipv4_address[16];
+  char ipv6_address[46];
+} f1ap_net_ip_address_t;
+
+typedef struct f1ap_cu_setup_req_s {
+   //
+} f1ap_cu_setup_req_t;
+
+typedef struct f1ap_setup_req_s {
+
+  // Midhaul networking parameters
+
+  /* Connexion id used between SCTP/F1AP */
+  uint16_t cnx_id;
+
+  /* SCTP association id */
+  int32_t  assoc_id;
+
+  /* The eNB IP address to bind */
+  f1ap_net_ip_address_t CU_f1_ip_address;
+  f1ap_net_ip_address_t DU_f1_ip_address;
+
+  /* Number of SCTP streams used for a mme association */
+  uint16_t sctp_in_streams;
+  uint16_t sctp_out_streams;
+
+  uint16_t default_sctp_stream_id;
+
+  // F1_Setup_Req payload
+  uint64_t gNB_DU_id;
+  char *gNB_DU_name;
+
+  /* The type of the cell */
+  enum cell_type_e cell_type;
+  
+  /// number of DU cells available
+  uint16_t num_cells_available; //0< num_cells_available <= 512;
+
+  // Served Cell Information
+  /* Tracking area code */
+  uint16_t tac[F1AP_MAX_NB_CELLS];
+
+  /* Mobile Country Codes
+   * Mobile Network Codes
+   */
+  uint16_t mcc[F1AP_MAX_NB_CELLS];//[6];
+  uint16_t mnc[F1AP_MAX_NB_CELLS];//[6];
+  uint8_t  mnc_digit_length[F1AP_MAX_NB_CELLS];//[6];
+
+  // NR Global Cell Id
+  uint64_t nr_cellid[F1AP_MAX_NB_CELLS];
+  // NR Physical Cell Ids
+  uint16_t nr_pci[F1AP_MAX_NB_CELLS];
+  // Number of slide support items (max 16, could be increased to as much as 1024)
+  uint16_t num_ssi[F1AP_MAX_NB_CELLS];//[6];
+  uint8_t sst[F1AP_MAX_NB_CELLS];//[16][6];
+  uint8_t sd[F1AP_MAX_NB_CELLS];//[16][6];
+  // fdd_flag = 1 means FDD, 0 means TDD
+  int  fdd_flag;
+
+  union {
+    struct {
+      uint32_t ul_nr_arfcn;
+      uint8_t ul_scs;
+      uint8_t ul_nrb;
+
+      uint32_t dl_nr_arfcn;
+      uint8_t dl_scs;
+      uint8_t dl_nrb;
+
+      uint32_t sul_active;
+      uint32_t sul_nr_arfcn;
+      uint8_t sul_scs;
+      uint8_t sul_nrb;
+
+      uint8_t ul_num_frequency_bands;
+      uint16_t ul_nr_band[32];
+      uint8_t ul_num_sul_frequency_bands;
+      uint16_t ul_nr_sul_band[32];
+
+      uint8_t dl_num_frequency_bands;
+      uint16_t dl_nr_band[32];
+      uint8_t dl_num_sul_frequency_bands;
+      uint16_t dl_nr_sul_band[32];
+    } fdd;
+    struct {
+
+      uint32_t nr_arfcn;
+      uint8_t scs;
+      uint8_t nrb;
+
+      uint32_t sul_active;
+      uint32_t sul_nr_arfcn;
+      uint8_t sul_scs;
+      uint8_t sul_nrb;
+
+      uint8_t num_frequency_bands;
+      uint16_t nr_band[32];
+      uint8_t num_sul_frequency_bands;
+      uint16_t nr_sul_band[32];
+
+    } tdd;
+  } nr_mode_info[F1AP_MAX_NB_CELLS];
+
+  char *measurement_timing_information[F1AP_MAX_NB_CELLS];
+  uint8_t ranac[F1AP_MAX_NB_CELLS];
+
+  // System Information
+  uint8_t *mib[F1AP_MAX_NB_CELLS];
+  int     mib_length[F1AP_MAX_NB_CELLS];
+  uint8_t *sib1[F1AP_MAX_NB_CELLS];
+  int     sib1_length[F1AP_MAX_NB_CELLS];
+
+
+} f1ap_setup_req_t;
+
+typedef struct f1ap_setup_resp_s {
+  /* Connexion id used between SCTP/F1AP */
+  uint16_t cnx_id;
+
+  /* SCTP association id */
+  int32_t  assoc_id;
+
+  /* Number of SCTP streams used for a mme association */
+  uint16_t sctp_in_streams;
+  uint16_t sctp_out_streams;
+
+  /// string holding gNB_CU_name
+  char     *gNB_CU_name;
+  /// number of DU cells to activate
+  uint16_t num_cells_to_activate; //0< num_cells_to_activate <= 512;
+  /// mcc of DU cells
+  uint16_t mcc[F1AP_MAX_NB_CELLS];
+  /// mnc of DU cells
+  uint16_t mnc[F1AP_MAX_NB_CELLS];
+  /// mnc digit length of DU cells
+  uint8_t mnc_digit_length[F1AP_MAX_NB_CELLS];
+  // NR Global Cell Id
+  uint64_t nr_cellid[F1AP_MAX_NB_CELLS];
+  /// NRPCI
+  uint16_t nrpci[F1AP_MAX_NB_CELLS];
+  /// num SI messages per DU cell
+  uint8_t num_SI[F1AP_MAX_NB_CELLS];
+  /// SI message containers (up to 21 messages per cell)
+  uint8_t *SI_container[F1AP_MAX_NB_CELLS][21];
+  int      SI_container_length[F1AP_MAX_NB_CELLS][21];
+} f1ap_setup_resp_t;
+
+typedef struct f1ap_setup_failure_s {
+  uint16_t cause;
+  uint16_t time_to_wait;
+  uint16_t criticality_diagnostics; 
+} f1ap_setup_failure_t;
+
+typedef struct f1ap_dl_rrc_message_s {
+
+  uint32_t gNB_CU_ue_id;
+  uint32_t gNB_DU_ue_id;
+  uint32_t old_gNB_DU_ue_id;
+  uint16_t rnti; 
+  uint8_t  srb_id;
+  uint8_t  execute_duplication;
+  uint8_t *rrc_container;
+  int      rrc_container_length;
+  union {
+    // both map 0..255 => 1..256
+    uint8_t en_dc;
+    uint8_t ngran;
+  } RAT_frequency_priority_information;
+} f1ap_dl_rrc_message_t;
+
+typedef struct f1ap_initial_ul_rrc_message_s {
+  uint32_t gNB_DU_ue_id;
+  /// mcc of DU cell
+  uint16_t mcc;
+  /// mnc of DU cell
+  uint16_t mnc;
+  /// mnc digit length of DU cells
+  uint8_t mnc_digit_length;
+  /// nr cell id
+  uint64_t nr_cellid;
+  /// crnti
+  uint16_t crnti;
+  uint8_t *rrc_container;
+  int      rrc_container_length;
+  uint8_t *du2cu_rrc_container;
+  int      du2cu_rrc_container_length;
+} f1ap_initial_ul_rrc_message_t;
+
+typedef struct f1ap_ul_rrc_message_s {
+  uint16_t rnti;
+  uint8_t  srb_id;
+  uint8_t *rrc_container;
+  int      rrc_container_length;
+} f1ap_ul_rrc_message_t;
+
+typedef struct f1ap_up_tnl_s {
+  in_addr_t tl_address; // currently only IPv4 supported
+  uint32_t  gtp_teid;
+} f1ap_up_tnl_t;
+
+typedef struct f1ap_drb_to_be_setup_s {
+  uint8_t        drb_id;
+  f1ap_up_tnl_t  up_ul_tnl[2];
+  uint8_t        up_ul_tnl_length;
+  rlc_mode_t     rlc_mode;
+} f1ap_drb_to_be_setup_t;
+
+typedef struct f1ap_ue_context_setup_req_s {
+  uint32_t gNB_CU_ue_id;    // BK: need to replace by use from rnti
+  uint32_t *gNB_DU_ue_id;
+  uint16_t rnti; 
+  // SpCell Info
+  uint16_t mcc;
+  uint16_t mnc;
+  uint8_t  mnc_digit_length;
+  uint64_t nr_cellid;
+  uint8_t servCellIndex;
+  uint8_t *cellULConfigured;
+  uint32_t servCellId;
+  uint8_t *cu_to_du_rrc_information;
+  uint8_t  cu_to_du_rrc_information_length;
+  f1ap_drb_to_be_setup_t *drbs_to_be_setup; // BK: need to replace by s1ap_initial_context_setup_req
+  uint8_t  drbs_to_be_setup_length;       // BK: need to replace by s1ap_initial_context_setup_req
+  s1ap_initial_context_setup_req_t *s1ap_initial_context_setup_req;
+   // coniatner for the rrc_eNB_generate_SecurityModeCommand message
+  uint8_t *rrc_container;
+  int      rrc_container_length;
+} f1ap_ue_context_setup_req_t;
+
+typedef enum F1ap_Cause_e {
+  F1AP_CAUSE_NOTHING,  /* No components present */
+  F1AP_CAUSE_RADIO_NETWORK,
+  F1AP_CAUSE_TRANSPORT,
+  F1AP_CAUSE_PROTOCOL,
+  F1AP_CAUSE_MISC,
+} f1ap_Cause_t;
+
+typedef struct f1ap_ue_context_release_s {
+  uint16_t      rnti;
+  f1ap_Cause_t  cause;
+  long          cause_value;
+  uint8_t      *rrc_container;
+  int           rrc_container_length;
+} f1ap_ue_context_release_req_t, f1ap_ue_context_release_cmd_t,
+  f1ap_ue_context_release_cplt_t;
+
+#endif /* F1AP_MESSAGES_TYPES_H_ */
diff --git a/openair2/COMMON/mac_rrc_primitives.h b/openair2/COMMON/mac_rrc_primitives.h
index 014122023530eabb6eca70c9c1f2f3b405fc83b8..ab05f394a1c9d04d2490ba5a9527f448dd834034 100644
--- a/openair2/COMMON/mac_rrc_primitives.h
+++ b/openair2/COMMON/mac_rrc_primitives.h
@@ -390,7 +390,7 @@ typedef struct {
 
 
 
-#define IDLE 0
+//#define IDLE 0
 #define NEED_RADIO_CONFIG 3
 #define RADIO_CONFIG_TX 2
 #define RADIO_CONFIG_OK 1
diff --git a/openair2/COMMON/messages_def.h b/openair2/COMMON/messages_def.h
index f6e2dd0f4b0159defbbdc18c065957045972a3ec..b0219db50a284739c41f86c49b40523baddc62af 100644
--- a/openair2/COMMON/messages_def.h
+++ b/openair2/COMMON/messages_def.h
@@ -34,6 +34,7 @@
 #include "ral_messages_def.h"
 #endif
 #include "s1ap_messages_def.h"
+#include "f1ap_messages_def.h"
 #include "x2ap_messages_def.h"
 #include "sctp_messages_def.h"
 #include "udp_messages_def.h"
diff --git a/openair2/COMMON/rrc_messages_types.h b/openair2/COMMON/rrc_messages_types.h
index 4a5851873b83b26e5fc429afc948fe6222eff3e1..5b33923b92cc5f13f5bb92f798ea69c8387cc8dc 100644
--- a/openair2/COMMON/rrc_messages_types.h
+++ b/openair2/COMMON/rrc_messages_types.h
@@ -32,7 +32,8 @@
 #include "as_message.h"
 #include "rrc_types.h"
 #include "s1ap_messages_types.h"
-  #include "LTE_SystemInformationBlockType2.h"
+#include "f1ap_messages_types.h"
+#include "LTE_SystemInformationBlockType2.h"
 #include "LTE_SL-OffsetIndicator-r12.h"
 #include "LTE_SubframeBitmapSL-r12.h"
 #include "LTE_SL-CP-Len-r12.h"
@@ -191,7 +192,7 @@ typedef struct RrcConfigurationReq_s {
 
   RadioResourceConfig     radioresourceconfig[MAX_NUM_CCs];
   RadioResourceConfig     radioresourceconfig_BR[MAX_NUM_CCs];
-   
+
 #if (LTE_RRC_VERSION >= MAKE_VERSION(13, 0, 0))
   //MIB
   long	 		  schedulingInfoSIB1_BR_r13[MAX_NUM_CCs];
@@ -254,11 +255,11 @@ typedef struct RrcConfigurationReq_s {
   bool  sib2_freq_hoppingParameters_r13_exists             [MAX_NUM_CCs];
   long  *sib2_mpdcch_pdsch_hoppingNB_r13                   [MAX_NUM_CCs];
   long  *sib2_interval_DLHoppingConfigCommonModeA_r13      [MAX_NUM_CCs];
-  long  sib2_interval_DLHoppingConfigCommonModeA_r13_val  [MAX_NUM_CCs];         
-  long  *sib2_interval_DLHoppingConfigCommonModeB_r13      [MAX_NUM_CCs]; 
-  long  sib2_interval_DLHoppingConfigCommonModeB_r13_val  [MAX_NUM_CCs];        
+  long  sib2_interval_DLHoppingConfigCommonModeA_r13_val  [MAX_NUM_CCs];
+  long  *sib2_interval_DLHoppingConfigCommonModeB_r13      [MAX_NUM_CCs];
+  long  sib2_interval_DLHoppingConfigCommonModeB_r13_val  [MAX_NUM_CCs];
   long  *sib2_interval_ULHoppingConfigCommonModeA_r13      [MAX_NUM_CCs];
-  long  sib2_interval_ULHoppingConfigCommonModeA_r13_val  [MAX_NUM_CCs];         
+  long  sib2_interval_ULHoppingConfigCommonModeA_r13_val  [MAX_NUM_CCs];
   long  *sib2_interval_ULHoppingConfigCommonModeB_r13      [MAX_NUM_CCs];
   long  sib2_interval_ULHoppingConfigCommonModeB_r13_val  [MAX_NUM_CCs];
   long  *sib2_mpdcch_pdsch_hoppingOffset_r13               [MAX_NUM_CCs];
diff --git a/openair2/COMMON/tasks_def.h b/openair2/COMMON/tasks_def.h
index 318c4649e411fe51dc40ff7b3e6b27be252a97a3..2ccb7b1c29059395641813059ba1c39100f85641 100644
--- a/openair2/COMMON/tasks_def.h
+++ b/openair2/COMMON/tasks_def.h
@@ -46,6 +46,8 @@ TASK_DEF(TASK_UDP,      TASK_PRIORITY_MED,          1000)
 // GTP_V1U task
 TASK_DEF(TASK_GTPV1_U,  TASK_PRIORITY_MED,          1000)
 TASK_DEF(TASK_S1AP,     TASK_PRIORITY_MED,          200)
+TASK_DEF(TASK_CU_F1,     TASK_PRIORITY_MED,          200)
+TASK_DEF(TASK_DU_F1,     TASK_PRIORITY_MED,          200)
 ///   X2ap task, acts as both source and target
 TASK_DEF(TASK_X2AP,     TASK_PRIORITY_MED,          200)
 ///   Sctp task (Used by both S1AP and X2AP)
@@ -54,7 +56,7 @@ TASK_DEF(TASK_SCTP,     TASK_PRIORITY_MED,          200)
 TASK_DEF(TASK_ENB_APP,  TASK_PRIORITY_MED,          200)
 ///   eNB Agent task
 TASK_DEF(TASK_FLEXRAN_AGENT,  TASK_PRIORITY_MED,          200)
-
+TASK_DEF(TASK_PROTO_AGENT,  TASK_PRIORITY_MED,          200)
 // UE tasks and sub-tasks:
 
 ///   Radio Resource Control task
diff --git a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c
index 6cc3caced61a7f8324d0bf1fe2d7ccec01c6a25e..7110f681d78efa51f03c25a809c467100c59a515 100644
--- a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c
+++ b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c
@@ -40,9 +40,6 @@
 
 #include "common/utils/LOG/log.h"
 
-/*Flags showing if a mac agent has already been registered*/
-unsigned int mac_agent_registered[NUM_MAX_ENB];
-
 /*Array containing the Agent-MAC interfaces*/
 AGENT_MAC_xface *agent_mac_xface[NUM_MAX_ENB];
 
@@ -83,7 +80,7 @@ int flexran_agent_mac_stats_reply(mid_t mod_id,
 
           for (i = 0; i < report_config->nr_ue; i++) {
 
-                UE_id = flexran_get_ue_id(mod_id, i);
+                UE_id = flexran_get_mac_ue_id(mod_id, i);
 
                 ue_report[i]->rnti = report_config->ue_report_type[i].ue_rnti;
                 ue_report[i]->has_rnti = 1;
@@ -102,12 +99,14 @@ int flexran_agent_mac_stats_reply(mid_t mod_id,
                         }
 
                         ue_report[i]->bsr = elem;
+                        ue_report[i]->flags |= PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_BSR;
                 }
 
                 /* Check flag for creation of PHR report */
                 if (report_config->ue_report_type[i].ue_report_flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_PHR) {
                         ue_report[i]->phr = flexran_get_ue_phr (enb_id, UE_id); // eNB_UE_list->UE_template[UE_PCCID(enb_id,UE_id)][UE_id].phr_info;
                         ue_report[i]->has_phr = 1;
+                        ue_report[i]->flags |= PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_PHR;
 
                 }
 
@@ -148,7 +147,7 @@ int flexran_agent_mac_stats_reply(mid_t mod_id,
                         // Add RLC buffer status reports to the full report
                         if (ue_report[i]->n_rlc_report > 0)
                             ue_report[i]->rlc_report = rlc_reports;
-
+                        ue_report[i]->flags |= PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_RLC_BS;
 
                 }
 
@@ -161,7 +160,7 @@ int flexran_agent_mac_stats_reply(mid_t mod_id,
                                        // found in stats_common.pb-c.h. See
                                        // flex_ce_type in FlexRAN specification
                         ue_report[i]->has_pending_mac_ces = 1;
-
+                        ue_report[i]->flags |= PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_MAC_CE_BS;
                 }
 
                 /* Check flag for creation of DL CQI report */
@@ -386,7 +385,7 @@ int flexran_agent_mac_stats_reply(mid_t mod_id,
                     dl_report->csi_report = csi_reports;
                     //Add the DL CQI report to the stats report
                      ue_report[i]->dl_cqi_report = dl_report;
-
+                    ue_report[i]->flags |= PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_DL_CQI;
                 }
 
                 /* Check flag for creation of paging buffer status report */
@@ -431,6 +430,7 @@ int flexran_agent_mac_stats_reply(mid_t mod_id,
                             paging_report->paging_info = p_info;
                             //Add the paging report to the UE report
                             ue_report[i]->pbr = paging_report;
+                            ue_report[i]->flags |= PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_PBS;
                 }
 
                   /* Check flag for creation of UL CQI report */
@@ -502,7 +502,7 @@ int flexran_agent_mac_stats_reply(mid_t mod_id,
                           }
                         //  Add full UL CQI report to the UE report
                         ue_report[i]->ul_cqi_report = full_ul_report;
-
+                        ue_report[i]->flags |= PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_UL_CQI;
 
                      }
                       if (report_config->ue_report_type[i].ue_report_flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_MAC_STATS) {
@@ -598,7 +598,7 @@ int flexran_agent_mac_stats_reply(mid_t mod_id,
 
 
                         ue_report[i]->mac_stats = macstats;
-
+                        ue_report[i]->flags |= PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_MAC_STATS;
                }
 
 
@@ -640,6 +640,7 @@ int flexran_agent_mac_stats_reply(mid_t mod_id,
                             ni_report->p0_nominal_pucch = flexran_get_p0_nominal_pucch(enb_id, 0);
                             ni_report->has_p0_nominal_pucch = 1;
                             cell_report[i]->noise_inter_report = ni_report;
+                            cell_report[i]->flags |= PROTOCOL__FLEX_CELL_STATS_TYPE__FLCST_NOISE_INTERFERENCE;
                       }
             }
 
@@ -660,14 +661,9 @@ int flexran_agent_mac_stats_reply(mid_t mod_id,
   return -1;
 }
 
-int flexran_agent_mac_destroy_stats_reply(Protocol__FlexranMessage *msg) {
-  //TODO: Need to deallocate memory for the stats reply message
-  if(msg->msg_case != PROTOCOL__FLEXRAN_MESSAGE__MSG_STATS_REPLY_MSG)
-    goto error;
-  free(msg->stats_reply_msg->header);
+int flexran_agent_mac_destroy_stats_reply(Protocol__FlexStatsReply *reply) {
   int i, j, k;
 
-  Protocol__FlexStatsReply *reply = msg->stats_reply_msg;
   Protocol__FlexDlCqiReport *dl_report;
   Protocol__FlexUlCqiReport *ul_report;
   Protocol__FlexPagingBufferReport *paging_report;
@@ -758,25 +754,24 @@ int flexran_agent_mac_destroy_stats_reply(Protocol__FlexranMessage *msg) {
 	free(ul_report->pucch_dbm[j]);
       }
       free(ul_report->pucch_dbm);
+      free(ul_report);
+    }
+    if (reply->ue_report[i]->flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_MAC_STATS) {
+      for (j = 0; j < reply->ue_report[i]->mac_stats->n_mac_sdus_dl; j++)
+        free(reply->ue_report[i]->mac_stats->mac_sdus_dl[j]);
+      free(reply->ue_report[i]->mac_stats->mac_sdus_dl);
+      free(reply->ue_report[i]->mac_stats);
     }
-    free(reply->ue_report[i]);
   }
-  free(reply->ue_report);
 
   // Free memory for all Cell reports
   for (i = 0; i < reply->n_cell_report; i++) {
-    free(reply->cell_report[i]->noise_inter_report);
-    free(reply->cell_report[i]);
+    if (reply->cell_report[i]->flags & PROTOCOL__FLEX_CELL_STATS_TYPE__FLCST_NOISE_INTERFERENCE) {
+      free(reply->cell_report[i]->noise_inter_report);
+    }
   }
-  free(reply->cell_report);
 
-  free(reply);
-  free(msg);
   return 0;
-
- error:
-  //LOG_E(MAC, "%s: an error occured\n", __FUNCTION__);
-  return -1;
 }
 
 int flexran_agent_mac_sr_info(mid_t mod_id, const void *params, Protocol__FlexranMessage **msg) {
@@ -905,7 +900,7 @@ int flexran_agent_mac_sf_trigger(mid_t mod_id, const void *params, Protocol__Fle
 
   //  LOG_I(FLEXRAN_AGENT, "Sending subframe trigger for frame %d and subframe %d\n", flexran_get_current_frame(mod_id), (flexran_get_current_subframe(mod_id) + 1) % 10);
 
-  sf_trigger_msg->n_dl_info = flexran_get_num_ues(mod_id);
+  sf_trigger_msg->n_dl_info = flexran_get_mac_num_ues(mod_id);
 
   Protocol__FlexDlInfo **dl_info = NULL;
 
@@ -921,9 +916,9 @@ int flexran_agent_mac_sf_trigger(mid_t mod_id, const void *params, Protocol__Fle
       dl_info[i] = malloc(sizeof(Protocol__FlexDlInfo));
       if(dl_info[i] == NULL)
 	goto error;
-      UE_id = flexran_get_ue_id(mod_id, i);
+      UE_id = flexran_get_mac_ue_id(mod_id, i);
       protocol__flex_dl_info__init(dl_info[i]);
-      dl_info[i]->rnti = flexran_get_ue_crnti(mod_id, UE_id);
+      dl_info[i]->rnti = flexran_get_mac_ue_crnti(mod_id, UE_id);
       dl_info[i]->has_rnti = 1;
       /*Fill in the right id of this round's HARQ process for this UE*/
       //      uint8_t harq_id;
@@ -957,7 +952,7 @@ int flexran_agent_mac_sf_trigger(mid_t mod_id, const void *params, Protocol__Fle
   /* Fill in the number of UL reception status related info, based on the number of currently
    * transmitting UEs
    */
-  sf_trigger_msg->n_ul_info = flexran_get_num_ues(mod_id);
+  sf_trigger_msg->n_ul_info = flexran_get_mac_num_ues(mod_id);
 
   Protocol__FlexUlInfo **ul_info = NULL;
 
@@ -972,9 +967,9 @@ int flexran_agent_mac_sf_trigger(mid_t mod_id, const void *params, Protocol__Fle
 	goto error;
       protocol__flex_ul_info__init(ul_info[i]);
 
-      UE_id = flexran_get_ue_id(mod_id, i);
+      UE_id = flexran_get_mac_ue_id(mod_id, i);
 
-      ul_info[i]->rnti = flexran_get_ue_crnti(mod_id, UE_id);
+      ul_info[i]->rnti = flexran_get_mac_ue_crnti(mod_id, UE_id);
       ul_info[i]->has_rnti = 1;
       /* Fill in the Tx power control command for this UE (if available),
        * primary carrier */
@@ -1357,11 +1352,17 @@ void flexran_agent_send_sf_trigger(mid_t mod_id) {
 
 
 
-int flexran_agent_register_mac_xface(mid_t mod_id, AGENT_MAC_xface *xface) {
-  if (mac_agent_registered[mod_id]) {
+int flexran_agent_register_mac_xface(mid_t mod_id)
+{
+  if (agent_mac_xface[mod_id]) {
     LOG_E(MAC, "MAC agent for eNB %d is already registered\n", mod_id);
     return -1;
   }
+  AGENT_MAC_xface *xface = malloc(sizeof(AGENT_MAC_xface));
+  if (!xface) {
+    LOG_E(FLEXRAN_AGENT, "could not allocate memory for MAC agent xface %d\n", mod_id);
+    return -1;
+  }
 
   //xface->agent_ctxt = &shared_ctxt[mod_id];
   xface->flexran_agent_send_sr_info = flexran_agent_send_sr_info;
@@ -1371,14 +1372,125 @@ int flexran_agent_register_mac_xface(mid_t mod_id, AGENT_MAC_xface *xface) {
 
   xface->dl_scheduler_loaded_lib = NULL;
   xface->ul_scheduler_loaded_lib = NULL;
-  mac_agent_registered[mod_id] = 1;
   agent_mac_xface[mod_id] = xface;
 
   return 0;
 }
 
-int flexran_agent_unregister_mac_xface(mid_t mod_id, AGENT_MAC_xface *xface) {
+void flexran_agent_fill_mac_cell_config(mid_t mod_id, uint8_t cc_id,
+    Protocol__FlexCellConfig *conf) {
+  if (!conf->si_config) {
+    conf->si_config = malloc(sizeof(Protocol__FlexSiConfig));
+    if (conf->si_config)
+      protocol__flex_si_config__init(conf->si_config);
+  }
+
+  if (conf->si_config) {
+    conf->si_config->sfn = flexran_get_current_system_frame_num(mod_id);
+    conf->si_config->has_sfn = 1;
+  }
+
+  /* get a pointer to the config which is maintained in the agent throughout
+  * its lifetime */
+  conf->slice_config = flexran_agent_get_slice_config(mod_id);
+}
 
+void flexran_agent_fill_mac_ue_config(mid_t mod_id, mid_t ue_id,
+    Protocol__FlexUeConfig *ue_conf)
+{
+  if (ue_conf->has_rnti && ue_conf->rnti != flexran_get_mac_ue_crnti(mod_id, ue_id)) {
+    LOG_E(FLEXRAN_AGENT, "ue_config existing RNTI %x does not match MAC RNTI %x\n",
+          ue_conf->rnti, flexran_get_mac_ue_crnti(mod_id, ue_id));
+    return;
+  }
+  ue_conf->rnti = flexran_get_mac_ue_crnti(mod_id, ue_id);
+  ue_conf->has_rnti = 1;
+
+  ue_conf->dl_slice_id = flexran_get_ue_dl_slice_id(mod_id, ue_id);
+  ue_conf->has_dl_slice_id = 1;
+  ue_conf->ul_slice_id = flexran_get_ue_ul_slice_id(mod_id, ue_id);
+  ue_conf->has_ul_slice_id = 1;
+
+  ue_conf->ue_aggregated_max_bitrate_ul = flexran_get_ue_aggregated_max_bitrate_ul(mod_id, ue_id);
+  ue_conf->has_ue_aggregated_max_bitrate_ul = 1;
+
+  ue_conf->ue_aggregated_max_bitrate_dl = flexran_get_ue_aggregated_max_bitrate_dl(mod_id, ue_id);
+  ue_conf->has_ue_aggregated_max_bitrate_dl = 1;
+
+  /* TODO update through RAN API */
+  //config->has_pcell_carrier_index = 1;
+  //config->pcell_carrier_index = UE_PCCID(mod_id, i);
+
+  //TODO: Set carrier aggregation support (boolean)
+}
+
+void flexran_agent_fill_mac_lc_ue_config(mid_t mod_id, mid_t ue_id,
+    Protocol__FlexLcUeConfig *lc_ue_conf)
+{
+  lc_ue_conf->rnti = flexran_get_mac_ue_crnti(mod_id, ue_id);
+  lc_ue_conf->has_rnti = 1;
+
+  lc_ue_conf->n_lc_config = flexran_get_num_ue_lcs(mod_id, ue_id);
+  if (lc_ue_conf->n_lc_config == 0)
+    return;
+
+  Protocol__FlexLcConfig **lc_config =
+    calloc(lc_ue_conf->n_lc_config, sizeof(Protocol__FlexLcConfig *));
+  if (!lc_config) {
+    LOG_E(FLEXRAN_AGENT, "could not allocate memory for lc_config of UE %x\n", lc_ue_conf->rnti);
+    lc_ue_conf->n_lc_config = 0;
+    return; // can not allocate memory, skip rest
+  }
+  for (int j = 0; j < lc_ue_conf->n_lc_config; j++) {
+    lc_config[j] = malloc(sizeof(Protocol__FlexLcConfig));
+    if (!lc_config[j]) continue; // go over this error, try entry
+    protocol__flex_lc_config__init(lc_config[j]);
+
+    lc_config[j]->has_lcid = 1;
+    lc_config[j]->lcid = j+1;
+
+    const int lcg = flexran_get_lcg(mod_id, ue_id, j+1);
+    if (lcg >= 0 && lcg <= 3) {
+      lc_config[j]->has_lcg = 1;
+      lc_config[j]->lcg = flexran_get_lcg(mod_id, ue_id, j+1);
+    }
+
+    lc_config[j]->has_direction = 1;
+    lc_config[j]->direction = flexran_get_direction(ue_id, j+1);
+    //TODO: Bearer type. One of FLQBT_* values. Currently only default bearer supported
+    lc_config[j]->has_qos_bearer_type = 1;
+    lc_config[j]->qos_bearer_type = PROTOCOL__FLEX_QOS_BEARER_TYPE__FLQBT_NON_GBR;
+
+    //TODO: Set the QCI defined in TS 23.203, coded as defined in TS 36.413
+    // One less than the actual QCI value. Needs to be generalized
+    lc_config[j]->has_qci = 1;
+    lc_config[j]->qci = 1;
+    if (lc_config[j]->direction == PROTOCOL__FLEX_QOS_BEARER_TYPE__FLQBT_GBR) {
+      /* TODO all of the need to be taken from API */
+      //TODO: Set the max bitrate (UL)
+      lc_config[j]->has_e_rab_max_bitrate_ul = 0;
+      lc_config[j]->e_rab_max_bitrate_ul = 0;
+      //TODO: Set the max bitrate (DL)
+      lc_config[j]->has_e_rab_max_bitrate_dl = 0;
+      lc_config[j]->e_rab_max_bitrate_dl = 0;
+      //TODO: Set the guaranteed bitrate (UL)
+      lc_config[j]->has_e_rab_guaranteed_bitrate_ul = 0;
+      lc_config[j]->e_rab_guaranteed_bitrate_ul = 0;
+      //TODO: Set the guaranteed bitrate (DL)
+      lc_config[j]->has_e_rab_guaranteed_bitrate_dl = 0;
+      lc_config[j]->e_rab_guaranteed_bitrate_dl = 0;
+    }
+  }
+  lc_ue_conf->lc_config = lc_config;
+}
+
+int flexran_agent_unregister_mac_xface(mid_t mod_id)
+{
+  if (!agent_mac_xface[mod_id]) {
+    LOG_E(FLEXRAN_AGENT, "MAC agent CM for eNB %d is not registered\n", mod_id);
+    return -1;
+  }
+  AGENT_MAC_xface *xface = agent_mac_xface[mod_id];
   //xface->agent_ctxt = NULL;
   xface->flexran_agent_send_sr_info = NULL;
   xface->flexran_agent_send_sf_trigger = NULL;
@@ -1387,12 +1499,17 @@ int flexran_agent_unregister_mac_xface(mid_t mod_id, AGENT_MAC_xface *xface) {
 
   xface->dl_scheduler_loaded_lib = NULL;
   xface->ul_scheduler_loaded_lib = NULL;
-  mac_agent_registered[mod_id] = 0;
+  free(xface);
   agent_mac_xface[mod_id] = NULL;
 
   return 0;
 }
 
+AGENT_MAC_xface *flexran_agent_get_mac_xface(mid_t mod_id)
+{
+  return agent_mac_xface[mod_id];
+}
+
 void flexran_create_config_structures(mid_t mod_id)
 {
   int i;
diff --git a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.h b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.h
index 0d686a53eed6fa5c13fc39129e0aff4508b86056..8ca855a6b34de6903f3a5251e7e794fdc6544947 100644
--- a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.h
+++ b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.h
@@ -36,6 +36,8 @@
 
 #include "flexran_agent_common.h"
 #include "flexran_agent_extern.h"
+// for flexran_agent_get_mac_xface()
+#include "flexran_agent_extern.h"
 
 
 /* Initialization function for the agent structures etc */
@@ -51,7 +53,7 @@ int flexran_agent_mac_destroy_sf_trigger(Protocol__FlexranMessage *msg);
 
 /* Statistics reply protocol message constructor and destructor */
 int flexran_agent_mac_stats_reply(mid_t mod_id, const report_config_t *report_config, Protocol__FlexUeStatsReport **ue_report, Protocol__FlexCellStatsReport **cell_report);
-int flexran_agent_mac_destroy_stats_reply(Protocol__FlexranMessage *msg);
+int flexran_agent_mac_destroy_stats_reply(Protocol__FlexStatsReply *reply);
 
 /* DL MAC scheduling decision protocol message constructor (empty command) and destructor */ 
 int flexran_agent_mac_create_empty_dl_config(mid_t mod_id, Protocol__FlexranMessage **msg);
@@ -81,11 +83,23 @@ void flexran_agent_send_update_mac_stats(mid_t mod_id);
 /// Provide to the scheduler a pending dl_mac_config message
 void flexran_agent_get_pending_dl_mac_config(mid_t mod_id, Protocol__FlexranMessage **msg);
 
+/* Fill the MAC part of an cell_config message */
+void flexran_agent_fill_mac_cell_config(mid_t mod_id, uint8_t cc_id,
+    Protocol__FlexCellConfig *conf);
+
+/* Fill the MAC part of a ue_config message */
+void flexran_agent_fill_mac_ue_config(mid_t mod_id, mid_t ue_id,
+    Protocol__FlexUeConfig *ue_conf);
+
+/* Fill the lc_ue_config->lc_config message */
+void flexran_agent_fill_mac_lc_ue_config(mid_t mod_id, mid_t ue_id,
+    Protocol__FlexLcUeConfig *lc_ue_conf);
+
 /*Register technology specific interface callbacks*/
-int flexran_agent_register_mac_xface(mid_t mod_id, AGENT_MAC_xface *xface);
+int flexran_agent_register_mac_xface(mid_t mod_id);
 
 /*Unregister technology specific callbacks*/
-int flexran_agent_unregister_mac_xface(mid_t mod_id, AGENT_MAC_xface*xface);
+int flexran_agent_unregister_mac_xface(mid_t mod_id);
 
 /***************************************
  * FlexRAN agent - slice configuration *
diff --git a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.c b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.c
index 8e0dc5726979861f68ae8fc707447774059a86d9..6ce9038923f21f5ede29e012cd8468c9f8e1726e 100644
--- a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.c
+++ b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.c
@@ -790,9 +790,9 @@ int parse_dl_scheduler_parameters(mid_t mod_id, yaml_parser_t *parser) {
 	goto error;
       }
       // Check what key needs to be set
-      if (mac_agent_registered[mod_id]) {
+      if (flexran_agent_get_mac_xface(mod_id)) {
 	LOG_D(ENB_APP, "Setting parameter %s\n", event.data.scalar.value);
-	param = dlsym(agent_mac_xface[mod_id]->dl_scheduler_loaded_lib,
+	param = dlsym(flexran_agent_get_mac_xface(mod_id)->dl_scheduler_loaded_lib,
 		      (char *) event.data.scalar.value);
 	if (param == NULL) {
 	  goto error;
@@ -845,9 +845,9 @@ int parse_ul_scheduler_parameters(mid_t mod_id, yaml_parser_t *parser) {
   goto error;
       }
       // Check what key needs to be set
-      if (mac_agent_registered[mod_id]) {
+      if (flexran_agent_get_mac_xface(mod_id)) {
   LOG_D(ENB_APP, "Setting parameter %s\n", event.data.scalar.value);
-  param = dlsym(agent_mac_xface[mod_id]->ul_scheduler_loaded_lib,
+        param = dlsym(flexran_agent_get_mac_xface(mod_id)->ul_scheduler_loaded_lib,
           (char *) event.data.scalar.value);
   if (param == NULL) {
     goto error;
@@ -891,11 +891,11 @@ int load_dl_scheduler_function(mid_t mod_id, const char *function_name) {
   LOG_I(FLEXRAN_AGENT, "Loading function: %s\n", function_name);
   void *loaded_scheduler = dlsym(lib, function_name);
   if (loaded_scheduler) {
-    if (mac_agent_registered[mod_id]) {
-      if (agent_mac_xface[mod_id]->dl_scheduler_loaded_lib != NULL) {
-	dlclose(agent_mac_xface[mod_id]->dl_scheduler_loaded_lib);
+    if (flexran_agent_get_mac_xface(mod_id)) {
+      if (flexran_agent_get_mac_xface(mod_id)->dl_scheduler_loaded_lib != NULL) {
+        dlclose(flexran_agent_get_mac_xface(mod_id)->dl_scheduler_loaded_lib);
       }
-      agent_mac_xface[mod_id]->dl_scheduler_loaded_lib = lib;
+      flexran_agent_get_mac_xface(mod_id)->dl_scheduler_loaded_lib = lib;
       LOG_I(FLEXRAN_AGENT, "New DL UE scheduler: %s\n", function_name);
     }
   } else {
diff --git a/openair2/ENB_APP/CONTROL_MODULES/PDCP/flexran_agent_pdcp.c b/openair2/ENB_APP/CONTROL_MODULES/PDCP/flexran_agent_pdcp.c
index 7cb39fb7239a17af935fa026ab0d20c12b866dbb..293ebab7a8c376f07f20432144fd4662c1ee4166 100644
--- a/openair2/ENB_APP/CONTROL_MODULES/PDCP/flexran_agent_pdcp.c
+++ b/openair2/ENB_APP/CONTROL_MODULES/PDCP/flexran_agent_pdcp.c
@@ -28,42 +28,36 @@
 
 #include "flexran_agent_pdcp.h"
 
-
-/*Trigger boolean for PDCP measurement*/
-bool triggered_pdcp = false;
-/*Flags showing if a pdcp agent has already been registered*/
-unsigned int pdcp_agent_registered[NUM_MAX_ENB];
-
 /*Array containing the Agent-PDCP interfaces*/
 AGENT_PDCP_xface *agent_pdcp_xface[NUM_MAX_ENB];
 
 // MAX_MOBILES_PER_ENB
 
 void flexran_agent_pdcp_aggregate_stats(const mid_t mod_id,
-					const mid_t ue_id,
+					uint16_t uid,
 					Protocol__FlexPdcpStats *pdcp_aggr_stats){
 
   int lcid=0;
   /* only calculate the DRBs */ 
-  //LOG_I(FLEXRAN_AGENT, "enb %d ue %d \n", mod_id, ue_id);
+  //LOG_I(FLEXRAN_AGENT, "enb %d ue %d \n", mod_id, uid);
   
   for (lcid=NUM_MAX_SRB ; lcid < NUM_MAX_SRB + NUM_MAX_DRB; lcid++){
     
-    pdcp_aggr_stats->pkt_tx += flexran_get_pdcp_tx(mod_id,ue_id,lcid);
-    pdcp_aggr_stats->pkt_tx_bytes += flexran_get_pdcp_tx_bytes(mod_id,ue_id,lcid);
-    pdcp_aggr_stats->pkt_tx_w += flexran_get_pdcp_tx_w(mod_id,ue_id,lcid);
-    pdcp_aggr_stats->pkt_tx_bytes_w += flexran_get_pdcp_tx_bytes_w(mod_id,ue_id,lcid);
-    pdcp_aggr_stats->pkt_tx_aiat += flexran_get_pdcp_tx_aiat(mod_id,ue_id,lcid);
-    pdcp_aggr_stats->pkt_tx_aiat_w += flexran_get_pdcp_tx_aiat_w(mod_id,ue_id,lcid);
+    pdcp_aggr_stats->pkt_tx += flexran_get_pdcp_tx(mod_id, uid, lcid);
+    pdcp_aggr_stats->pkt_tx_bytes += flexran_get_pdcp_tx_bytes(mod_id, uid, lcid);
+    pdcp_aggr_stats->pkt_tx_w += flexran_get_pdcp_tx_w(mod_id, uid, lcid);
+    pdcp_aggr_stats->pkt_tx_bytes_w += flexran_get_pdcp_tx_bytes_w(mod_id, uid, lcid);
+    pdcp_aggr_stats->pkt_tx_aiat += flexran_get_pdcp_tx_aiat(mod_id, uid, lcid);
+    pdcp_aggr_stats->pkt_tx_aiat_w += flexran_get_pdcp_tx_aiat_w(mod_id, uid, lcid);
     
       
-    pdcp_aggr_stats->pkt_rx += flexran_get_pdcp_rx(mod_id,ue_id,lcid);
-    pdcp_aggr_stats->pkt_rx_bytes += flexran_get_pdcp_rx_bytes(mod_id,ue_id,lcid);
-    pdcp_aggr_stats->pkt_rx_w += flexran_get_pdcp_rx_w(mod_id,ue_id,lcid);
-    pdcp_aggr_stats->pkt_rx_bytes_w += flexran_get_pdcp_rx_bytes_w(mod_id,ue_id,lcid);
-    pdcp_aggr_stats->pkt_rx_aiat += flexran_get_pdcp_rx_aiat(mod_id,ue_id,lcid);
-    pdcp_aggr_stats->pkt_rx_aiat_w += flexran_get_pdcp_rx_aiat_w(mod_id,ue_id,lcid);
-    pdcp_aggr_stats->pkt_rx_oo += flexran_get_pdcp_rx_oo(mod_id,ue_id,lcid);
+    pdcp_aggr_stats->pkt_rx += flexran_get_pdcp_rx(mod_id, uid, lcid);
+    pdcp_aggr_stats->pkt_rx_bytes += flexran_get_pdcp_rx_bytes(mod_id, uid, lcid);
+    pdcp_aggr_stats->pkt_rx_w += flexran_get_pdcp_rx_w(mod_id, uid, lcid);
+    pdcp_aggr_stats->pkt_rx_bytes_w += flexran_get_pdcp_rx_bytes_w(mod_id, uid, lcid);
+    pdcp_aggr_stats->pkt_rx_aiat += flexran_get_pdcp_rx_aiat(mod_id, uid, lcid);
+    pdcp_aggr_stats->pkt_rx_aiat_w += flexran_get_pdcp_rx_aiat_w(mod_id, uid, lcid);
+    pdcp_aggr_stats->pkt_rx_oo += flexran_get_pdcp_rx_oo(mod_id, uid, lcid);
     
   }
   
@@ -78,7 +72,6 @@ int flexran_agent_pdcp_stats_reply(mid_t mod_id,
   
   // Protocol__FlexHeader *header;
   int i;
-  int UE_id;
   // int cc_id = 0;
  
   
@@ -86,7 +79,8 @@ int flexran_agent_pdcp_stats_reply(mid_t mod_id,
   if (report_config->nr_ue > 0) {
     
     for (i = 0; i < report_config->nr_ue; i++) {
-      UE_id = flexran_get_ue_id(mod_id, i);
+      const rnti_t rnti = report_config->ue_report_type[i].ue_rnti;
+      const uint16_t uid = flexran_get_pdcp_uid_from_rnti(mod_id, rnti);
 
       /* Check flag for creation of buffer status report */
       if (report_config->ue_report_type[i].ue_report_flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_PDCP_STATS) {
@@ -97,7 +91,7 @@ int flexran_agent_pdcp_stats_reply(mid_t mod_id,
 	  goto error;
 	protocol__flex_pdcp_stats__init(pdcp_aggr_stats);
 	
-	flexran_agent_pdcp_aggregate_stats(mod_id, UE_id, pdcp_aggr_stats);
+	flexran_agent_pdcp_aggregate_stats(mod_id, uid, pdcp_aggr_stats);
 
 	pdcp_aggr_stats->has_pkt_tx=1;
 	pdcp_aggr_stats->has_pkt_tx_bytes =1;
@@ -106,7 +100,7 @@ int flexran_agent_pdcp_stats_reply(mid_t mod_id,
 	pdcp_aggr_stats->has_pkt_tx_aiat =1; 
 	pdcp_aggr_stats->has_pkt_tx_aiat_w =1;
 
-	pdcp_aggr_stats->pkt_tx_sn = flexran_get_pdcp_tx_sn(mod_id, UE_id, DEFAULT_DRB);
+	pdcp_aggr_stats->pkt_tx_sn = flexran_get_pdcp_tx_sn(mod_id, uid, DEFAULT_DRB);
 	pdcp_aggr_stats->has_pkt_tx_sn =1;
 	
 	pdcp_aggr_stats->has_pkt_rx =1;
@@ -117,14 +111,14 @@ int flexran_agent_pdcp_stats_reply(mid_t mod_id,
 	pdcp_aggr_stats->has_pkt_rx_aiat_w =1;
 	pdcp_aggr_stats->has_pkt_rx_oo =1;
 
-	pdcp_aggr_stats->pkt_rx_sn = flexran_get_pdcp_rx_sn(mod_id, UE_id, DEFAULT_DRB);
+	pdcp_aggr_stats->pkt_rx_sn = flexran_get_pdcp_rx_sn(mod_id, uid, DEFAULT_DRB);
 	pdcp_aggr_stats->has_pkt_rx_sn =1;
 
 	pdcp_aggr_stats->sfn = flexran_get_pdcp_sfn(mod_id);
 	pdcp_aggr_stats->has_sfn =1;
 
 	ue_report[i]->pdcp_stats = pdcp_aggr_stats;
-
+        ue_report[i]->flags |= PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_PDCP_STATS;
       }
     }
   }  else {
@@ -144,30 +138,51 @@ int flexran_agent_pdcp_stats_reply(mid_t mod_id,
   return -1;
 }
 
+int flexran_agent_pdcp_destroy_stats_reply(Protocol__FlexStatsReply *reply)
+{
+  for (int i = 0; i < reply->n_ue_report; ++i) {
+    if (reply->ue_report[i]->pdcp_stats)
+      free(reply->ue_report[i]->pdcp_stats);
+  }
+  return 0;
+}
 
 
-int flexran_agent_register_pdcp_xface(mid_t mod_id, AGENT_PDCP_xface *xface) {
-  if (pdcp_agent_registered[mod_id]) {
-    LOG_E(PDCP, "PDCP agent for eNB %d is already registered\n", mod_id);
+int flexran_agent_register_pdcp_xface(mid_t mod_id)
+{
+  if (agent_pdcp_xface[mod_id]) {
+    LOG_E(FLEXRAN_AGENT, "PDCP agent CM for eNB %d is already registered\n", mod_id);
+    return -1;
+  }
+  AGENT_PDCP_xface *xface = malloc(sizeof(AGENT_PDCP_xface));
+  if (!xface) {
+    LOG_E(FLEXRAN_AGENT, "could not allocate memory for PDCP agent xface %d\n", mod_id);
     return -1;
   }
 
   //xface->flexran_pdcp_stats_measurement = NULL;
 
-  pdcp_agent_registered[mod_id] = 1;
   agent_pdcp_xface[mod_id] = xface;
 
   return 0;
 }
 
-int flexran_agent_unregister_pdcp_xface(mid_t mod_id, AGENT_PDCP_xface *xface) {
-
+int flexran_agent_unregister_pdcp_xface(mid_t mod_id)
+{
+  if (!agent_pdcp_xface[mod_id]) {
+    LOG_E(FLEXRAN_AGENT, "PDCP agent CM for eNB %d is not registered\n", mod_id);
+    return -1;
+  }
   //xface->agent_ctxt = NULL;
   //xface->flexran_pdcp_stats_measurement = NULL;
 
-  
-  pdcp_agent_registered[mod_id] = 0;
+  free(agent_pdcp_xface[mod_id]);
   agent_pdcp_xface[mod_id] = NULL;
 
   return 0;
 }
+
+AGENT_PDCP_xface *flexran_agent_get_pdcp_xface(mid_t mod_id)
+{
+  return agent_pdcp_xface[mod_id];
+}
diff --git a/openair2/ENB_APP/CONTROL_MODULES/PDCP/flexran_agent_pdcp.h b/openair2/ENB_APP/CONTROL_MODULES/PDCP/flexran_agent_pdcp.h
index 83aac45406e17b5f5526898e45a5212475cd2e9b..246f9709b512e5e90ad4058a85a0a9377ff15de9 100644
--- a/openair2/ENB_APP/CONTROL_MODULES/PDCP/flexran_agent_pdcp.h
+++ b/openair2/ENB_APP/CONTROL_MODULES/PDCP/flexran_agent_pdcp.h
@@ -39,6 +39,8 @@
 #include "flexran_agent_defs.h"
 #include "flexran_agent_pdcp_defs.h"
 #include "flexran_agent_ran_api.h"
+// for flexran_agent_get_pdcp_xface()
+#include "flexran_agent_extern.h"
 
 /**********************************
  * FlexRAN agent - technology PDCP API
@@ -49,16 +51,17 @@ int flexran_agent_pdcp_stats_reply(mid_t mod_id,
           const report_config_t *report_config,
            Protocol__FlexUeStatsReport **ue_report,
            Protocol__FlexCellStatsReport **cell_report);
+int flexran_agent_pdcp_destroy_stats_reply(Protocol__FlexStatsReply *reply);
 
 /* Get the stats from RAN API and aggregate them per USER*/
 void flexran_agent_pdcp_aggregate_stats(const mid_t mod_id,
-					const mid_t ue_id,
+                                        uint16_t uid,
 					Protocol__FlexPdcpStats *pdcp_aggr_stats);
 
 /*Register technology specific interface callbacks*/
-int flexran_agent_register_pdcp_xface(mid_t mod_id, AGENT_PDCP_xface *xface);
+int flexran_agent_register_pdcp_xface(mid_t mod_id);
 
 /*Unregister technology specific callbacks*/
-int flexran_agent_unregister_pdcp_xface(mid_t mod_id, AGENT_PDCP_xface*xface);
+int flexran_agent_unregister_pdcp_xface(mid_t mod_id);
 
 #endif
diff --git a/openair2/ENB_APP/CONTROL_MODULES/PHY/flexran_agent_phy.c b/openair2/ENB_APP/CONTROL_MODULES/PHY/flexran_agent_phy.c
new file mode 100644
index 0000000000000000000000000000000000000000..2f8726293813d900635ed893584c2ecb16049c1e
--- /dev/null
+++ b/openair2/ENB_APP/CONTROL_MODULES/PHY/flexran_agent_phy.c
@@ -0,0 +1,179 @@
+/*
+ * 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
+ */
+
+/*! \file flexran_agent_phy.c
+ * \brief FlexRAN agent Control Module PHY
+ * \author Robert Schmidt
+ * \date Oct 2018
+ */
+
+#include "flexran_agent_phy.h"
+#include "flexran_agent_ran_api.h"
+
+/* Array containing the Agent-PHY interfaces */
+AGENT_PHY_xface *agent_phy_xface[NUM_MAX_ENB];
+
+void flexran_agent_fill_phy_cell_config(mid_t mod_id, uint8_t cc_id,
+                                        Protocol__FlexCellConfig *conf) {
+  conf->phy_cell_id = flexran_get_cell_id(mod_id, cc_id);
+  conf->has_phy_cell_id = 1;
+
+  conf->pusch_hopping_offset = flexran_get_hopping_offset(mod_id, cc_id);
+  conf->has_pusch_hopping_offset = 1;
+
+  conf->hopping_mode = flexran_get_hopping_mode(mod_id, cc_id);
+  conf->has_hopping_mode = 1;
+
+  conf->n_sb = flexran_get_n_SB(mod_id, cc_id);
+  conf->has_n_sb = 1;
+
+  conf->phich_resource = flexran_get_phich_resource(mod_id, cc_id);
+  conf->has_phich_resource = 1;
+
+  conf->phich_duration = flexran_get_phich_duration(mod_id, cc_id);
+  conf->has_phich_duration = 1;
+
+  conf->init_nr_pdcch_ofdm_sym = flexran_get_num_pdcch_symb(mod_id, cc_id);
+  conf->has_init_nr_pdcch_ofdm_sym = 1;
+
+  conf->dl_bandwidth = flexran_get_N_RB_DL(mod_id, cc_id);
+  conf->has_dl_bandwidth = 1;
+
+  conf->ul_bandwidth = flexran_get_N_RB_UL(mod_id, cc_id);
+  conf->has_ul_bandwidth = 1;
+
+  conf->ul_cyclic_prefix_length = flexran_get_ul_cyclic_prefix_length(mod_id,  cc_id);
+  conf->has_ul_cyclic_prefix_length = 1;
+
+  conf->dl_cyclic_prefix_length = flexran_get_dl_cyclic_prefix_length(mod_id, cc_id);
+  conf->has_dl_cyclic_prefix_length = 1;
+
+  conf->antenna_ports_count = flexran_get_antenna_ports(mod_id,  cc_id);
+  conf->has_antenna_ports_count = 1;
+
+  conf->duplex_mode = flexran_get_duplex_mode(mod_id, cc_id);
+  conf->has_duplex_mode = 1;
+
+  conf->subframe_assignment = flexran_get_subframe_assignment(mod_id,  cc_id);
+  conf->has_subframe_assignment = 1;
+
+  conf->special_subframe_patterns = flexran_get_special_subframe_assignment(mod_id, cc_id);
+  conf->has_special_subframe_patterns = 1;
+
+  //TODO: Fill in with actual value, The MBSFN radio frame period
+  conf->n_mbsfn_subframe_config_rfperiod = 0;
+  uint32_t *elem_rfperiod = malloc(sizeof(uint32_t) * conf->n_mbsfn_subframe_config_rfperiod);
+  if (elem_rfperiod)
+    for(int j = 0; j < conf->n_mbsfn_subframe_config_rfperiod; j++)
+      elem_rfperiod[j] = 1;
+  conf->mbsfn_subframe_config_rfperiod = elem_rfperiod;
+
+  //TODO: Fill in with actual value, The MBSFN radio frame offset
+  conf->n_mbsfn_subframe_config_rfoffset = 0;
+  uint32_t *elem_rfoffset = malloc(sizeof(uint32_t) * conf->n_mbsfn_subframe_config_rfoffset);
+  if (elem_rfoffset)
+    for(int j = 0; j < conf->n_mbsfn_subframe_config_rfoffset; j++)
+      elem_rfoffset[j] = 1;
+  conf->mbsfn_subframe_config_rfoffset = elem_rfoffset;
+
+  //TODO: Fill in with actual value, Bitmap indicating the MBSFN subframes
+  conf->n_mbsfn_subframe_config_sfalloc = 0;
+  uint32_t *elem_sfalloc = malloc(sizeof(uint32_t) * conf->n_mbsfn_subframe_config_sfalloc);
+  if (elem_sfalloc)
+    for(int j = 0; j < conf->n_mbsfn_subframe_config_sfalloc; j++)
+      elem_sfalloc[j] = 1;
+  conf->mbsfn_subframe_config_sfalloc = elem_sfalloc;
+
+  conf->prach_config_index = flexran_get_prach_ConfigIndex(mod_id, cc_id);
+  conf->has_prach_config_index = 1;
+
+  conf->prach_freq_offset = flexran_get_prach_FreqOffset(mod_id, cc_id);
+  conf->has_prach_freq_offset = 1;
+
+  conf->max_harq_msg3tx = flexran_get_maxHARQ_Msg3Tx(mod_id, cc_id);
+  conf->has_max_harq_msg3tx = 1;
+
+  conf->n1pucch_an = flexran_get_n1pucch_an(mod_id, cc_id);
+  conf->has_n1pucch_an = 1;
+
+  conf->deltapucch_shift = flexran_get_deltaPUCCH_Shift(mod_id, cc_id);
+  conf->has_deltapucch_shift = 1;
+
+  conf->nrb_cqi = flexran_get_nRB_CQI(mod_id, cc_id);
+  conf->has_nrb_cqi = 1;
+
+  conf->srs_subframe_config = flexran_get_srs_SubframeConfig(mod_id, cc_id);
+  conf->has_srs_subframe_config = 1;
+
+  conf->srs_bw_config = flexran_get_srs_BandwidthConfig(mod_id, cc_id);
+  conf->has_srs_bw_config = 1;
+
+  conf->srs_mac_up_pts = flexran_get_srs_MaxUpPts(mod_id, cc_id);
+  conf->has_srs_mac_up_pts = 1;
+
+  conf->dl_freq = flexran_agent_get_operating_dl_freq (mod_id, cc_id);
+  conf->has_dl_freq = 1;
+
+  conf->ul_freq = flexran_agent_get_operating_ul_freq (mod_id,  cc_id);
+  conf->has_ul_freq = 1;
+
+  conf->eutra_band = flexran_agent_get_operating_eutra_band (mod_id, cc_id);
+  conf->has_eutra_band = 1;
+
+  conf->dl_pdsch_power = flexran_agent_get_operating_pdsch_refpower(mod_id,  cc_id);
+  conf->has_dl_pdsch_power = 1;
+
+  conf->enable_64qam = flexran_get_enable64QAM(mod_id, cc_id);
+  conf->has_enable_64qam = 1;
+}
+
+int flexran_agent_register_phy_xface(mid_t mod_id) {
+  if (agent_phy_xface[mod_id]) {
+    LOG_E(PHY, "PHY agent for eNB %d is already registered\n", mod_id);
+    return -1;
+  }
+
+  AGENT_PHY_xface *xface = malloc(sizeof(AGENT_PHY_xface));
+
+  if (!xface) {
+    LOG_E(FLEXRAN_AGENT, "could not allocate memory for PHY agent xface %d\n", mod_id);
+    return -1;
+  }
+
+  agent_phy_xface[mod_id] = xface;
+  return 0;
+}
+
+int flexran_agent_unregister_phy_xface(mid_t mod_id)
+{
+  if (!agent_phy_xface[mod_id]) {
+    LOG_E(FLEXRAN_AGENT, "PHY agent for eNB %d is not registered\n", mod_id);
+    return -1;
+  }
+  free(agent_phy_xface[mod_id]);
+  agent_phy_xface[mod_id] = NULL;
+  return 0;
+}
+
+AGENT_PHY_xface *flexran_agent_get_phy_xface(mid_t mod_id)
+{
+  return agent_phy_xface[mod_id];
+}
diff --git a/openair2/ENB_APP/CONTROL_MODULES/PHY/flexran_agent_phy.h b/openair2/ENB_APP/CONTROL_MODULES/PHY/flexran_agent_phy.h
new file mode 100644
index 0000000000000000000000000000000000000000..25b3deac35fbb9b27f3f143c700bb7f4a8148e10
--- /dev/null
+++ b/openair2/ENB_APP/CONTROL_MODULES/PHY/flexran_agent_phy.h
@@ -0,0 +1,58 @@
+/*
+ * 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
+ */
+
+/*! \file flexran_agent_phy.h
+ * \brief FlexRAN agent Control Module PHY header
+ * \author Robert Schmidt
+ * \date Oct 2018
+ */
+
+#ifndef FLEXRAN_AGENT_PHY_H_
+#define FLEXRAN_AGENT_PHY_H_
+
+#include "header.pb-c.h"
+#include "flexran.pb-c.h"
+#include "stats_messages.pb-c.h"
+#include "stats_common.pb-c.h"
+
+
+#include "flexran_agent_common.h"
+#include "flexran_agent_defs.h"
+#include "flexran_agent_phy_defs.h"
+#include "flexran_agent_ran_api.h"
+// for flexran_agent_get_phy_xface()
+#include "flexran_agent_extern.h"
+
+/**********************************
+ * FlexRAN agent - technology PHY API
+ **********************************/
+
+/* Fill the PHY part of an cell_config message */
+void flexran_agent_fill_phy_cell_config(mid_t mod_id, uint8_t cc_id,
+    Protocol__FlexCellConfig *conf);
+
+/* Register technology specific interface callbacks */
+int flexran_agent_register_phy_xface(mid_t mod_id);
+
+/* Unregister technology specific callbacks */
+int flexran_agent_unregister_phy_xface(mid_t mod_id);
+
+#endif
diff --git a/openair2/ENB_APP/CONTROL_MODULES/PHY/flexran_agent_phy_defs.h b/openair2/ENB_APP/CONTROL_MODULES/PHY/flexran_agent_phy_defs.h
new file mode 100644
index 0000000000000000000000000000000000000000..06c262ef7fafc8c912177b27e0fdb2648a51742f
--- /dev/null
+++ b/openair2/ENB_APP/CONTROL_MODULES/PHY/flexran_agent_phy_defs.h
@@ -0,0 +1,35 @@
+/*
+ * 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
+ */
+#ifndef __FLEXRAN_AGENT_PHY_PRIMITIVES_H__
+#define __FLEXRAN_AGENT_PHY_PRIMITIVES_H__
+
+#include "flexran_agent_defs.h"
+#include "flexran.pb-c.h"
+#include "header.pb-c.h"
+
+/* FLEXRAN AGENT-PHY Interface */
+typedef struct {
+
+  /* currently empty, will be used to control RU */
+
+} AGENT_PHY_xface;
+
+#endif /* __FLEXRAN_AGENT_PHY_PRIMITIVES_H__ */
diff --git a/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc.c b/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc.c
index 7d7f48a61008608100d074492b9bf738c7ee4f5e..a785c681635f2db9d0c6cb83b8a80a5f531dd5ae 100644
--- a/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc.c
+++ b/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc.c
@@ -27,7 +27,7 @@
  */
 
 #include "flexran_agent_rrc.h"
-
+#include "flexran_agent_ran_api.h"
 
 #include "liblfds700.h"
 
@@ -36,9 +36,6 @@
 /*Trigger boolean for RRC measurement*/
 bool triggered_rrc = false;
 
-/*Flags showing if an rrc agent has already been registered*/
-unsigned int rrc_agent_registered[NUM_MAX_ENB];
-
 /*Array containing the Agent-RRC interfaces*/
 AGENT_RRC_xface *agent_rrc_xface[NUM_MAX_ENB];
 
@@ -71,154 +68,21 @@ void flexran_agent_ue_state_change(mid_t mod_id, uint32_t rnti, uint8_t state_ch
     goto error;
   }
   protocol__flex_ue_config__init(config);
-  if (state_change == PROTOCOL__FLEX_UE_STATE_CHANGE_TYPE__FLUESC_DEACTIVATED) {
-    // Simply set the rnti of the UE
-    config->has_rnti = 1;
-    config->rnti = rnti;
-  } else if (state_change == PROTOCOL__FLEX_UE_STATE_CHANGE_TYPE__FLUESC_UPDATED
-      || state_change == PROTOCOL__FLEX_UE_STATE_CHANGE_TYPE__FLUESC_ACTIVATED) {
-    int i = find_UE_id(mod_id, rnti);
+  switch (state_change) {
+  case PROTOCOL__FLEX_UE_STATE_CHANGE_TYPE__FLUESC_DEACTIVATED:
     config->has_rnti = 1;
     config->rnti = rnti;
-    config->imsi = flexran_get_ue_imsi(mod_id, i);
-    config->has_imsi = 1;
-    config->dl_slice_id = flexran_get_ue_dl_slice_id(mod_id, i);
-    config->has_dl_slice_id = 1;
-    config->ul_slice_id = flexran_get_ue_ul_slice_id(mod_id, i);
-    config->has_ul_slice_id = 1;
-    if(flexran_get_time_alignment_timer(mod_id,i) != -1) {
-      config->time_alignment_timer = flexran_get_time_alignment_timer(mod_id,i);
-      config->has_time_alignment_timer = 1;
-    }
-    if(flexran_get_meas_gap_config(mod_id,i) != -1){
-      config->meas_gap_config_pattern = flexran_get_meas_gap_config(mod_id,i);
-      config->has_meas_gap_config_pattern = 1;
-    }
-    if(config->has_meas_gap_config_pattern == 1 &&
-        config->meas_gap_config_pattern != PROTOCOL__FLEX_MEAS_GAP_CONFIG_PATTERN__FLMGCP_OFF) {
-      config->meas_gap_config_sf_offset = flexran_get_meas_gap_config_offset(mod_id,i);
-      config->has_meas_gap_config_sf_offset = 1;
-    }
-    //TODO: Set the SPS configuration (Optional)
-    //Not supported for now, so we do not set it
-
-    //TODO: Set the SR configuration (Optional)
-    //We do not set it for now
-
-    //TODO: Set the CQI configuration (Optional)
-    //We do not set it for now
-
-    if(flexran_get_ue_transmission_mode(mod_id,i) != -1) {
-      config->transmission_mode = flexran_get_ue_transmission_mode(mod_id,i);
-      config->has_transmission_mode = 1;
-    }
-
-    config->ue_aggregated_max_bitrate_ul = flexran_get_ue_aggregated_max_bitrate_ul(mod_id,i);
-    config->has_ue_aggregated_max_bitrate_ul = 1;
-
-    config->ue_aggregated_max_bitrate_dl = flexran_get_ue_aggregated_max_bitrate_dl(mod_id,i);
-    config->has_ue_aggregated_max_bitrate_dl = 1;
-
-    Protocol__FlexUeCapabilities *c_capabilities;
-    c_capabilities = malloc(sizeof(Protocol__FlexUeCapabilities));
-    protocol__flex_ue_capabilities__init(c_capabilities);
-    c_capabilities->has_half_duplex = 1;
-    c_capabilities->half_duplex = flexran_get_half_duplex(mod_id, i);
-    c_capabilities->has_intra_sf_hopping = 1;
-    c_capabilities->intra_sf_hopping = flexran_get_intra_sf_hopping(mod_id, i);
-    c_capabilities->has_type2_sb_1 = 1;
-    c_capabilities->type2_sb_1 = flexran_get_type2_sb_1(mod_id, i);
-    c_capabilities->has_ue_category = 1;
-    c_capabilities->ue_category = flexran_get_ue_category(mod_id, i);
-    c_capabilities->has_res_alloc_type1 = 1;
-    c_capabilities->res_alloc_type1 = flexran_get_res_alloc_type1(mod_id, i);
-    //Set the capabilites to the message
-    config->capabilities = c_capabilities;
-
-    if(flexran_get_ue_transmission_antenna(mod_id,i) != -1) {
-      config->has_ue_transmission_antenna = 1;
-      config->ue_transmission_antenna = flexran_get_ue_transmission_antenna(mod_id,i);
-    }
-
-    if(flexran_get_tti_bundling(mod_id,i) != -1) {
-      config->has_tti_bundling = 1;
-      config->tti_bundling = flexran_get_tti_bundling(mod_id,i);
-    }
-
-    if(flexran_get_maxHARQ_TX(mod_id,i) != -1){
-      config->has_max_harq_tx = 1;
-      config->max_harq_tx = flexran_get_maxHARQ_TX(mod_id,i);
-    }
-
-    if(flexran_get_beta_offset_ack_index(mod_id,i) != -1) {
-      config->has_beta_offset_ack_index = 1;
-      config->beta_offset_ack_index = flexran_get_beta_offset_ack_index(mod_id,i);
-    }
-
-    if(flexran_get_beta_offset_ri_index(mod_id,i) != -1) {
-      config->has_beta_offset_ri_index = 1;
-      config->beta_offset_ri_index = flexran_get_beta_offset_ri_index(mod_id,i);
-    }
-
-    if(flexran_get_beta_offset_cqi_index(mod_id,i) != -1) {
-      config->has_beta_offset_cqi_index = 1;
-      config->beta_offset_cqi_index = flexran_get_beta_offset_cqi_index(mod_id,i);
-    }
-
-    /* assume primary carrier */
-    if(flexran_get_ack_nack_simultaneous_trans(mod_id,i,0) != -1) {
-      config->has_ack_nack_simultaneous_trans = 1;
-      config->ack_nack_simultaneous_trans = flexran_get_ack_nack_simultaneous_trans(mod_id,i,0);
-    }
-
-    if(flexran_get_simultaneous_ack_nack_cqi(mod_id,i) != -1) {
-      config->has_simultaneous_ack_nack_cqi = 1;
-      config->simultaneous_ack_nack_cqi = flexran_get_simultaneous_ack_nack_cqi(mod_id,i);
-    }
-
-    if(flexran_get_aperiodic_cqi_rep_mode(mod_id,i) != -1) {
-      config->has_aperiodic_cqi_rep_mode = 1;
-      int mode = flexran_get_aperiodic_cqi_rep_mode(mod_id,i);
-      if (mode > 4) {
-        config->aperiodic_cqi_rep_mode = PROTOCOL__FLEX_APERIODIC_CQI_REPORT_MODE__FLACRM_NONE;
-      } else {
-        config->aperiodic_cqi_rep_mode = mode;
-      }
-    }
-
-    if(flexran_get_tdd_ack_nack_feedback_mode(mod_id, i) != -1) {
-      config->has_tdd_ack_nack_feedback = 1;
-      config->tdd_ack_nack_feedback = flexran_get_tdd_ack_nack_feedback_mode(mod_id,i);
-    }
-
-    if(flexran_get_ack_nack_repetition_factor(mod_id, i) != -1) {
-      config->has_ack_nack_repetition_factor = 1;
-      config->ack_nack_repetition_factor = flexran_get_ack_nack_repetition_factor(mod_id,i);
-    }
-
-    if(flexran_get_extended_bsr_size(mod_id, i) != -1) {
-      config->has_extended_bsr_size = 1;
-      config->extended_bsr_size = flexran_get_extended_bsr_size(mod_id,i);
-    }
-
-    config->has_pcell_carrier_index = 1;
-    config->pcell_carrier_index = UE_PCCID(mod_id, i);
-    //TODO: Set carrier aggregation support (boolean)
-    config->has_ca_support = 0;
-    config->ca_support = 0;
-    if(config->has_ca_support){
-      //TODO: Set cross carrier scheduling support (boolean)
-      config->has_cross_carrier_sched_support = 1;
-      config->cross_carrier_sched_support = 0;
-      //TODO: Set secondary cells configuration
-      // We do not set it for now. No carrier aggregation support
-
-      //TODO: Set deactivation timer for secondary cell
-      config->has_scell_deactivation_timer = 0;
-      config->scell_deactivation_timer = 0;
-    }
-  } else if (state_change == PROTOCOL__FLEX_UE_STATE_CHANGE_TYPE__FLUESC_MOVED) {
-    // TODO: Not supported for now. Leave blank
+    break;
+  case PROTOCOL__FLEX_UE_STATE_CHANGE_TYPE__FLUESC_UPDATED:
+  case PROTOCOL__FLEX_UE_STATE_CHANGE_TYPE__FLUESC_ACTIVATED:
+    flexran_agent_fill_rrc_ue_config(mod_id, rnti, config);
+    /* we don't call into the MAC CM here; it will be called later through an
+     * ue_config_request */
+    break;
+  case PROTOCOL__FLEX_UE_STATE_CHANGE_TYPE__FLUESC_MOVED:
+  default:
+    LOG_E(FLEXRAN_AGENT, "state change FLUESC_MOVED or unknown state occured for RNTI %x\n",
+          rnti);
   }
 
   ue_state_change_msg->config = config;
@@ -242,16 +106,18 @@ void flexran_agent_ue_state_change(mid_t mod_id, uint32_t rnti, uint8_t state_ch
   return;
  error:
   if (err_code != 0)
-     LOG_E(FLEXRAN_AGENT, "Could not send UE state message becasue of %d \n",err_code);
+     LOG_E(FLEXRAN_AGENT, "Could not send UE state message becasue of %d for RNTI %x\n",
+           err_code, rnti);
 }
 
 
-
 int flexran_agent_destroy_ue_state_change(Protocol__FlexranMessage *msg) {
   if(msg->msg_case != PROTOCOL__FLEXRAN_MESSAGE__MSG_UE_STATE_CHANGE_MSG)
     goto error;
   free(msg->ue_state_change_msg->header);
-  //TODO: Free the contents of the UE config structure
+  if (msg->ue_state_change_msg->config->capabilities)
+    free(msg->ue_state_change_msg->config->capabilities);
+  free(msg->ue_state_change_msg->config);
   free(msg->ue_state_change_msg);
   free(msg);
   return 0;
@@ -264,30 +130,27 @@ int flexran_agent_destroy_ue_state_change(Protocol__FlexranMessage *msg) {
 /* this is called by RRC as a part of rrc xface  . The controller previously requested  this*/ 
 void flexran_trigger_rrc_measurements (mid_t mod_id, LTE_MeasResults_t*  measResults) {
 
-  //int i;
   // int                   priority = 0; // Warning Preventing
   // void                  *data;
   // int                   size;
   // err_code_t             err_code = -100;
   triggered_rrc = true;
-  //int num;
 
   /* TODO do we need this at the current state? meas_stats is never put into a
    * protobuf message?!
-  num = flexran_get_num_ues (mod_id);
+  int num = flexran_get_rrc_num_ues (mod_id);
+  rnti_t rntis[num];
+  flexran_get_rrc_rnti_list(mod_id, rntis, num);
 
   meas_stats = malloc(sizeof(rrc_meas_stats) * num); 
 
-  for (i = 0; i < num; i++){
-    UE_id = flexran_get_ue_id(mod_id, i);
-    meas_stats[i].rnti = flexran_get_ue_crnti(mod_id, UE_id);
-    meas_stats[i].meas_id = flexran_get_rrc_pcell_measid(mod_id, UE_id);
-    meas_stats[i].rsrp =  flexran_get_rrc_pcell_rsrp(mod_id, UE_id) - 140;
+  for (int i = 0; i < num; i++){
+    const rnti_t rnti = rntis[i];
+    meas_stats[i].rnti = rnti;
+    meas_stats[i].meas_id = flexran_get_rrc_pcell_measid(mod_id, rnti);
+    meas_stats[i].rsrp =  flexran_get_rrc_pcell_rsrp(mod_id, rnti) - 140;
     // measResults->measResultPCell.rsrpResult - 140;
-    meas_stats[i].rsrq =  flexran_get_rrc_pcell_rsrq(mod_id, UE_id)/2 - 20;
-    // (measResults->measResultPCell.rsrqResult)/2 - 20;                          
-    
-  }
+    meas_stats[i].rsrq =  flexran_get_rrc_pcell_rsrq(mod_id, rnti)/2 - 20;
   */
     // repl->neigh_meas = NULL;
 
@@ -496,17 +359,11 @@ int flexran_agent_rrc_stats_reply(mid_t mod_id,
            Protocol__FlexUeStatsReport **ue_report,
            Protocol__FlexCellStatsReport **cell_report) {
 
-
-  // Protocol__FlexHeader *header;
-  int i,j;
-  int UE_id;
-
-  /* Allocate memory for list of UE reports */
   if (report_config->nr_ue > 0) {
-
-    for (i = 0; i < report_config->nr_ue; i++) {
-
-      UE_id = flexran_get_ue_id(mod_id, i);
+    rnti_t rntis[report_config->nr_ue];
+    flexran_get_rrc_rnti_list(mod_id, rntis, report_config->nr_ue);
+    for (int i = 0; i < report_config->nr_ue; i++) {
+      const rnti_t rnti = rntis[i];
       
       /* Check flag for creation of buffer status report */
       if (report_config->ue_report_type[i].ue_report_flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_RRC_MEASUREMENTS) {
@@ -518,15 +375,14 @@ int flexran_agent_rrc_stats_reply(mid_t mod_id,
       	  goto error;
       	protocol__flex_rrc_measurements__init(rrc_measurements);
       	
-        rrc_measurements->measid = flexran_get_rrc_pcell_measid(mod_id, UE_id);
-        rrc_measurements->has_measid = 1;
-
-        rrc_measurements->pcell_rsrp = flexran_get_rrc_pcell_rsrp(mod_id, UE_id);
-        rrc_measurements->has_pcell_rsrp = 1;
-
-        rrc_measurements->pcell_rsrq = flexran_get_rrc_pcell_rsrq(mod_id, UE_id);
-        rrc_measurements->has_pcell_rsrq = 1 ;
-
+        rrc_measurements->measid = flexran_get_rrc_pcell_measid(mod_id, rnti);
+      	rrc_measurements->has_measid = 1;
+      	
+        rrc_measurements->pcell_rsrp = flexran_get_rrc_pcell_rsrp(mod_id, rnti);
+      	rrc_measurements->has_pcell_rsrp = 1;
+      	
+        rrc_measurements->pcell_rsrq = flexran_get_rrc_pcell_rsrq(mod_id, rnti);
+      	rrc_measurements->has_pcell_rsrq = 1 ;
         
         /* Target Cell, Neghibouring*/
         Protocol__FlexNeighCellsMeasurements *neigh_meas;
@@ -536,7 +392,7 @@ int flexran_agent_rrc_stats_reply(mid_t mod_id,
         protocol__flex_neigh_cells_measurements__init(neigh_meas);
          
         
-        neigh_meas->n_eutra_meas = flexran_get_rrc_num_ncell(mod_id, UE_id);
+        neigh_meas->n_eutra_meas = flexran_get_rrc_num_ncell(mod_id, rnti);
 
         Protocol__FlexEutraMeasurements **eutra_meas = NULL;
 
@@ -546,7 +402,7 @@ int flexran_agent_rrc_stats_reply(mid_t mod_id,
           if (eutra_meas == NULL)
             goto error;
           
-          for (j = 0; j < neigh_meas->n_eutra_meas; j++ ){
+          for (int j = 0; j < neigh_meas->n_eutra_meas; j++ ){
 
               eutra_meas[j] = malloc(sizeof(Protocol__FlexEutraMeasurements));
               if (eutra_meas[j] == NULL)
@@ -554,7 +410,7 @@ int flexran_agent_rrc_stats_reply(mid_t mod_id,
 
               protocol__flex_eutra_measurements__init(eutra_meas[j]);
 
-              eutra_meas[j]->phys_cell_id = flexran_get_rrc_neigh_phy_cell_id(mod_id, UE_id, j);
+              eutra_meas[j]->phys_cell_id = flexran_get_rrc_neigh_phy_cell_id(mod_id, rnti, j);
               eutra_meas[j]->has_phys_cell_id = 1;
 
 
@@ -565,10 +421,10 @@ int flexran_agent_rrc_stats_reply(mid_t mod_id,
 
               protocol__flex_eutra_ref_signal_meas__init(meas_result);     
 
-              meas_result->rsrp = flexran_get_rrc_neigh_rsrp(mod_id, UE_id, eutra_meas[j]->phys_cell_id);
+              meas_result->rsrp = flexran_get_rrc_neigh_rsrp(mod_id, rnti, eutra_meas[j]->phys_cell_id);
               meas_result->has_rsrp = 1;
 
-              meas_result->rsrq = flexran_get_rrc_neigh_rsrq(mod_id, UE_id, eutra_meas[j]->phys_cell_id);
+              meas_result->rsrq = flexran_get_rrc_neigh_rsrq(mod_id, rnti, eutra_meas[j]->phys_cell_id);
               meas_result->has_rsrq = 1;
 
               eutra_meas[j]->meas_result = meas_result;
@@ -582,6 +438,7 @@ int flexran_agent_rrc_stats_reply(mid_t mod_id,
         }
 
       	 ue_report[i]->rrc_measurements = rrc_measurements;
+         ue_report[i]->flags |= PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_RRC_MEASUREMENTS;
       	
       }
 
@@ -618,6 +475,7 @@ int flexran_agent_rrc_stats_reply(mid_t mod_id,
   //                           ni_report->p0_nominal_pucch = flexran_get_p0_nominal_pucch(enb_id, 0);
   //                           ni_report->has_p0_nominal_pucch = 1;
   //                           cell_report[i]->noise_inter_report = ni_report;
+  //                           cell_report[i]->flags |= PROTOCOL__FLEX_CELL_STATS_TYPE__FLCST_NOISE_INTERFERENCE;
   //                     }
   //           }
             
@@ -630,12 +488,10 @@ int flexran_agent_rrc_stats_reply(mid_t mod_id,
 
  error:
 
-  for (i = 0; i < report_config->nr_ue; i++){
+  for (int i = 0; i < report_config->nr_ue; i++){
 
-      UE_id = flexran_get_ue_id(mod_id, i);
-
-      if (ue_report[i]->rrc_measurements->neigh_meas != NULL){
-          for (j = 0; j < flexran_get_rrc_num_ncell(mod_id, UE_id); j++){
+      if (ue_report[i]->rrc_measurements && ue_report[i]->rrc_measurements->neigh_meas != NULL){
+          for (int j = 0; j < ue_report[i]->rrc_measurements->neigh_meas->n_eutra_meas; j++){
 
              free(ue_report[i]->rrc_measurements->neigh_meas->eutra_meas[j]);
         }
@@ -651,10 +507,131 @@ int flexran_agent_rrc_stats_reply(mid_t mod_id,
   return -1;
 }
 
+int flexran_agent_rrc_destroy_stats_reply(Protocol__FlexStatsReply *reply)
+{
+  for (int i = 0; i < reply->n_ue_report; i++){
+    if (reply->ue_report[i]->rrc_measurements && reply->ue_report[i]->rrc_measurements->neigh_meas){
+      for (int j = 0; j < reply->ue_report[i]->rrc_measurements->neigh_meas->n_eutra_meas; j++){
+        free(reply->ue_report[i]->rrc_measurements->neigh_meas->eutra_meas[j]->meas_result);
+        free(reply->ue_report[i]->rrc_measurements->neigh_meas->eutra_meas[j]);
+      }
+      free(reply->ue_report[i]->rrc_measurements->neigh_meas->eutra_meas);
+      free(reply->ue_report[i]->rrc_measurements->neigh_meas);
+      free(reply->ue_report[i]->rrc_measurements);
+    }
+  }
+  return 0;
+}
+
+void flexran_agent_fill_rrc_ue_config(mid_t mod_id, rnti_t rnti,
+    Protocol__FlexUeConfig *ue_conf)
+{
+  if (ue_conf->has_rnti && ue_conf->rnti != rnti) {
+    LOG_E(FLEXRAN_AGENT, "ue_config existing RNTI %x does not match RRC RNTI %x\n",
+          ue_conf->rnti, rnti);
+    return;
+  }
+  ue_conf->has_rnti = 1;
+  ue_conf->rnti = rnti;
+  ue_conf->imsi = flexran_get_ue_imsi(mod_id, rnti);
+  ue_conf->has_imsi = 1;
+
+  //TODO: Set the DRX configuration (optional)
+  //Not supported for now, so we do not set it
+
+  ue_conf->time_alignment_timer = flexran_get_time_alignment_timer(mod_id, rnti);
+  ue_conf->has_time_alignment_timer = 1;
+
+  ue_conf->meas_gap_config_pattern = flexran_get_meas_gap_config(mod_id, rnti);
+  ue_conf->has_meas_gap_config_pattern = 1;
+
+  if(ue_conf->meas_gap_config_pattern != PROTOCOL__FLEX_MEAS_GAP_CONFIG_PATTERN__FLMGCP_OFF) {
+    ue_conf->meas_gap_config_sf_offset = flexran_get_meas_gap_config_offset(mod_id, rnti);
+    ue_conf->has_meas_gap_config_sf_offset = 1;
+  }
+
+  //TODO: Set the SPS configuration (Optional)
+  //Not supported for now, so we do not set it
+
+  //TODO: Set the SR configuration (Optional)
+  //We do not set it for now
+
+  //TODO: Set the CQI configuration (Optional)
+  //We do not set it for now
+
+  ue_conf->transmission_mode = flexran_get_ue_transmission_mode(mod_id, rnti);
+  ue_conf->has_transmission_mode = 1;
+
+  Protocol__FlexUeCapabilities *c_capabilities;
+  c_capabilities = malloc(sizeof(Protocol__FlexUeCapabilities));
+  if (c_capabilities) {
+    protocol__flex_ue_capabilities__init(c_capabilities);
+
+    c_capabilities->has_half_duplex = 1;
+    c_capabilities->half_duplex = flexran_get_half_duplex(mod_id, rnti);
+
+    c_capabilities->has_intra_sf_hopping = 1;
+    c_capabilities->intra_sf_hopping = flexran_get_intra_sf_hopping(mod_id, rnti);
+
+    c_capabilities->has_type2_sb_1 = 1;
+    c_capabilities->type2_sb_1 = flexran_get_type2_sb_1(mod_id, rnti);
+
+    c_capabilities->has_ue_category = 1;
+    c_capabilities->ue_category = flexran_get_ue_category(mod_id, rnti);
+
+    c_capabilities->has_res_alloc_type1 = 1;
+    c_capabilities->res_alloc_type1 = flexran_get_res_alloc_type1(mod_id, rnti);
+
+    ue_conf->capabilities = c_capabilities;
+  }
+
+  ue_conf->has_ue_transmission_antenna = 1;
+  ue_conf->ue_transmission_antenna = flexran_get_ue_transmission_antenna(mod_id, rnti);
+
+  ue_conf->has_tti_bundling = 1;
+  ue_conf->tti_bundling = flexran_get_tti_bundling(mod_id, rnti);
+
+  ue_conf->has_max_harq_tx = 1;
+  ue_conf->max_harq_tx = flexran_get_maxHARQ_TX(mod_id, rnti);
+
+  ue_conf->has_beta_offset_ack_index = 1;
+  ue_conf->beta_offset_ack_index = flexran_get_beta_offset_ack_index(mod_id, rnti);
+
+  ue_conf->has_beta_offset_ri_index = 1;
+  ue_conf->beta_offset_ri_index = flexran_get_beta_offset_ri_index(mod_id, rnti);
+
+  ue_conf->has_beta_offset_cqi_index = 1;
+  ue_conf->beta_offset_cqi_index = flexran_get_beta_offset_cqi_index(mod_id, rnti);
+
+  /* assume primary carrier */
+  ue_conf->has_ack_nack_simultaneous_trans = 1;
+  ue_conf->ack_nack_simultaneous_trans = flexran_get_ack_nack_simultaneous_trans(mod_id,0);
+
+  ue_conf->has_simultaneous_ack_nack_cqi = 1;
+  ue_conf->simultaneous_ack_nack_cqi = flexran_get_simultaneous_ack_nack_cqi(mod_id, rnti);
+
+  ue_conf->has_aperiodic_cqi_rep_mode = 1;
+  ue_conf->aperiodic_cqi_rep_mode = flexran_get_aperiodic_cqi_rep_mode(mod_id, rnti);
+
+  ue_conf->has_tdd_ack_nack_feedback = 1;
+  ue_conf->tdd_ack_nack_feedback = flexran_get_tdd_ack_nack_feedback_mode(mod_id, rnti);
+
+  ue_conf->has_ack_nack_repetition_factor = 1;
+  ue_conf->ack_nack_repetition_factor = flexran_get_ack_nack_repetition_factor(mod_id, rnti);
+
+  ue_conf->has_extended_bsr_size = 1;
+  ue_conf->extended_bsr_size = flexran_get_extended_bsr_size(mod_id, rnti);
+}
 
-int flexran_agent_register_rrc_xface(mid_t mod_id, AGENT_RRC_xface *xface) {
-  if (rrc_agent_registered[mod_id]) {
-    LOG_E(RRC, "RRC agent for eNB %d is already registered\n", mod_id);
+int flexran_agent_register_rrc_xface(mid_t mod_id)
+{
+  if (agent_rrc_xface[mod_id]) {
+    LOG_E(FLEXRAN_AGENT, "RRC agent for eNB %d is already registered\n", mod_id);
+    return -1;
+  }
+  AGENT_RRC_xface *xface = malloc(sizeof(AGENT_RRC_xface));
+  if (!xface) {
+    LOG_E(FLEXRAN_AGENT, "could not allocate memory for RRC agent xface %d\n", mod_id);
     return -1;
   }
 
@@ -663,21 +640,98 @@ int flexran_agent_register_rrc_xface(mid_t mod_id, AGENT_RRC_xface *xface) {
   xface->flexran_agent_notify_ue_state_change = flexran_agent_ue_state_change;
   xface->flexran_trigger_rrc_measurements = flexran_trigger_rrc_measurements;
 
-  rrc_agent_registered[mod_id] = 1;
   agent_rrc_xface[mod_id] = xface;
 
   return 0;
 }
 
-int flexran_agent_unregister_rrc_xface(mid_t mod_id, AGENT_RRC_xface *xface) {
+void flexran_agent_fill_rrc_cell_config(mid_t mod_id, uint8_t cc_id,
+    Protocol__FlexCellConfig *conf) {
+
+  if (!conf->si_config) {
+    conf->si_config = malloc(sizeof(Protocol__FlexSiConfig));
+    if (conf->si_config)
+      protocol__flex_si_config__init(conf->si_config);
+  }
+
+  if (conf->si_config) {
+    // TODO THIS IS DU RRC
+    conf->si_config->sib1_length = flexran_get_sib1_length(mod_id, cc_id);
+    conf->si_config->has_sib1_length = 1;
+
+    conf->si_config->si_window_length = (uint32_t) flexran_get_si_window_length(mod_id,  cc_id);
+    conf->si_config->has_si_window_length = 1;
+
+    conf->si_config->n_si_message = 0;
+
+    /* Protocol__FlexSiMessage **si_message; */
+    /* si_message = malloc(sizeof(Protocol__FlexSiMessage *) * si_config->n_si_message); */
+    /* if(si_message == NULL) */
+    /* 	goto error; */
+    /* for(j = 0; j < si_config->n_si_message; j++){ */
+    /* 	si_message[j] = malloc(sizeof(Protocol__FlexSiMessage)); */
+    /* 	if(si_message[j] == NULL) */
+    /* 	  goto error; */
+    /* 	protocol__flex_si_message__init(si_message[j]); */
+    /* 	//TODO: Fill in with actual value, Periodicity of SI msg in radio frames */
+    /* 	si_message[j]->periodicity = 1;				//SIPeriod */
+    /* 	si_message[j]->has_periodicity = 1; */
+    /* 	//TODO: Fill in with actual value, rhe length of the SI message in bytes */
+    /* 	si_message[j]->length = 10; */
+    /* 	si_message[j]->has_length = 1; */
+    /* } */
+    /* if(si_config->n_si_message > 0){ */
+    /* 	si_config->si_message = si_message; */
+    /* } */
+  }
+
+  conf->ra_response_window_size = flexran_get_ra_ResponseWindowSize(mod_id, cc_id);
+  conf->has_ra_response_window_size = 1;
+
+  // belongs to MAC but is read in RRC
+  conf->mac_contention_resolution_timer = flexran_get_mac_ContentionResolutionTimer(mod_id, cc_id);
+  conf->has_mac_contention_resolution_timer = 1;
+
+  conf->ul_pusch_power = flexran_agent_get_operating_pusch_p0 (mod_id, cc_id);
+  conf->has_ul_pusch_power = 1;
+
+  conf->n_plmn_id = flexran_get_rrc_num_plmn_ids(mod_id);
+  conf->plmn_id = calloc(conf->n_plmn_id, sizeof(Protocol__FlexPlmn *));
+  if (conf->plmn_id) {
+    for (int i = 0; i < conf->n_plmn_id; i++) {
+      conf->plmn_id[i] = malloc(sizeof(Protocol__FlexPlmn));
+      if (!conf->plmn_id[i]) continue;
+      protocol__flex_plmn__init(conf->plmn_id[i]);
+      conf->plmn_id[i]->mcc = flexran_get_rrc_mcc(mod_id, i);
+      conf->plmn_id[i]->has_mcc = 1;
+      conf->plmn_id[i]->mnc = flexran_get_rrc_mnc(mod_id, i);
+      conf->plmn_id[i]->has_mnc = 1;
+      conf->plmn_id[i]->mnc_length = flexran_get_rrc_mnc_digit_length(mod_id, i);
+      conf->plmn_id[i]->has_mnc_length = 1;
+    }
+  } else {
+    conf->n_plmn_id = 0;
+  }
+}
 
+int flexran_agent_unregister_rrc_xface(mid_t mod_id)
+{
+  if (!agent_rrc_xface[mod_id]) {
+    LOG_E(FLEXRAN_AGENT, "RRC agent for eNB %d is not registered\n", mod_id);
+    return -1;
+  }
   //xface->agent_ctxt = NULL;
 //  xface->flexran_agent_send_update_rrc_stats = NULL;
 
-  xface->flexran_agent_notify_ue_state_change = NULL;
-  xface->flexran_trigger_rrc_measurements = NULL;
-  rrc_agent_registered[mod_id] = 0;
+  agent_rrc_xface[mod_id]->flexran_agent_notify_ue_state_change = NULL;
+  agent_rrc_xface[mod_id]->flexran_trigger_rrc_measurements = NULL;
+  free(agent_rrc_xface[mod_id]);
   agent_rrc_xface[mod_id] = NULL;
 
   return 0;
 }
+
+AGENT_RRC_xface *flexran_agent_get_rrc_xface(mid_t mod_id)
+{
+  return agent_rrc_xface[mod_id];
+}
diff --git a/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc.h b/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc.h
index b6cb674ce985085efb617a178548eac1c1a23d9d..4b9cec861427871ec0c4973f03062564c78e081a 100644
--- a/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc.h
+++ b/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc.h
@@ -37,11 +37,10 @@
 
 #include "flexran_agent_common.h"
 #include "flexran_agent_rrc_defs.h"
+// for flexran_agent_get_rrc_xface()
+#include "flexran_agent_extern.h"
 
 
-/* Initialization function for the agent structures etc */
-void flexran_agent_init_rrc_agent(mid_t mod_id);
-
 /* UE state change message constructor and destructor */
 void flexran_agent_ue_state_change(mid_t mod_id, uint32_t rnti, uint8_t state_change);
 int flexran_agent_destroy_ue_state_change(Protocol__FlexranMessage *msg);
@@ -59,12 +58,20 @@ void flexran_trigger_rrc_measurements (mid_t mod_id, LTE_MeasResults_t *);
 
 /* Statistics reply protocol message constructor and destructor */
 int flexran_agent_rrc_stats_reply(mid_t mod_id, const report_config_t *report_config, Protocol__FlexUeStatsReport **ue_report, Protocol__FlexCellStatsReport **cell_report);
-int flexran_agent_rrc_destroy_stats_reply(Protocol__FlexranMessage *msg);
+int flexran_agent_rrc_destroy_stats_reply(Protocol__FlexStatsReply *reply);
+
+/* Fill the RRC part of a ue_config message */
+void flexran_agent_fill_rrc_ue_config(mid_t mod_id, rnti_t rnti,
+    Protocol__FlexUeConfig *ue_conf);
+
+/* Fill the RRC part of an cell_config message */
+void flexran_agent_fill_rrc_cell_config(mid_t mod_id, uint8_t cc_id,
+    Protocol__FlexCellConfig *conf);
 
 /*Register technology specific interface callbacks*/
-int flexran_agent_register_rrc_xface(mid_t mod_id, AGENT_RRC_xface *xface);
+int flexran_agent_register_rrc_xface(mid_t mod_id);
 
 /*Unregister technology specific callbacks*/
-int flexran_agent_unregister_rrc_xface(mid_t mod_id, AGENT_RRC_xface*xface);
+int flexran_agent_unregister_rrc_xface(mid_t mod_id);
 
 #endif
diff --git a/openair2/ENB_APP/MESSAGES/V2/config_common.proto b/openair2/ENB_APP/MESSAGES/V2/config_common.proto
index 3af59c1537691b5ac40104cfab714106a770a257..695d7bcdb1f07378779a674b3d29a3001dfc2544 100644
--- a/openair2/ENB_APP/MESSAGES/V2/config_common.proto
+++ b/openair2/ENB_APP/MESSAGES/V2/config_common.proto
@@ -218,6 +218,9 @@ enum flex_aperiodic_cqi_report_mode {
      FLACRM_RM30 = 3;
      FLACRM_RM31 = 4;
      FLACRM_NONE = 5;
+     FLACRM_RM32_v1250 = 6;
+     FLACRM_RM10_v1310 = 7;
+     FLACRM_RM11_v1310 = 8;
 }
 
 enum flex_tdd_ack_nack_feedback_mode {
@@ -259,3 +262,9 @@ enum flex_ue_state_change_type {
      FLUESC_DEACTIVATED = 2;
      FLUESC_MOVED = 3;
 }
+
+message flex_plmn {
+        optional uint32 mcc = 1;
+        optional uint32 mnc = 2;
+        optional uint32 mnc_length = 3;
+}
diff --git a/openair2/ENB_APP/MESSAGES/V2/config_messages.proto b/openair2/ENB_APP/MESSAGES/V2/config_messages.proto
index 1d5da8dd2abc0e756615096aee666e54125053dc..dd983aa09c700f82931834b70a003ee091280d77 100644
--- a/openair2/ENB_APP/MESSAGES/V2/config_messages.proto
+++ b/openair2/ENB_APP/MESSAGES/V2/config_messages.proto
@@ -5,7 +5,6 @@ import "config_common.proto";
 
 message flex_cell_config {
 	optional uint32 phy_cell_id = 1;		// The PCI of this cell
-	optional uint32 cell_id = 2;			// The PLMN cell id of this cell
 	optional uint32 pusch_hopping_offset = 3;	// PUSCH resources in RBs for hopping
 	optional uint32 hopping_mode = 4;		// One of the FLHM_* enum values
 	optional uint32 n_sb = 5;			// The number of subbands
@@ -43,6 +42,7 @@ message flex_cell_config {
 	optional uint32 eutra_band= 37;       // operating band 
 	optional int32 dl_pdsch_power = 38;       // operating downlink power 
 	optional int32 ul_pusch_power = 39;       // operating uplink power
+	repeated flex_plmn plmn_id = 40;                   // The PLMN cell id of this cell
 
 	optional flex_slice_config slice_config = 42;
 }
diff --git a/openair2/ENB_APP/MESSAGES/V2/flexran.proto b/openair2/ENB_APP/MESSAGES/V2/flexran.proto
index 9255372340283d8ce89bb0c1c4cfc6c19a2710a9..b1702f949e4af2204a546975387da8913ca71de0 100644
--- a/openair2/ENB_APP/MESSAGES/V2/flexran.proto
+++ b/openair2/ENB_APP/MESSAGES/V2/flexran.proto
@@ -31,6 +31,7 @@ message flexran_message {
 	      flex_agent_reconfiguration agent_reconfiguration_msg = 17;
 	      flex_rrc_triggering rrc_triggering = 18;
 	      flex_ul_mac_config ul_mac_config_msg = 19;
+              flex_disconnect disconnect_msg = 20;
 	}
 }
 
@@ -64,9 +65,21 @@ enum flexran_err {
 //
 // Maintenance and discovery messages
 //
+enum flex_bs_capability {
+    LOPHY = 0;
+    HIPHY = 1;
+    LOMAC = 2;
+    HIMAC = 3;
+    RLC   = 4;
+    PDCP  = 5;
+    SDAP  = 6;
+    RRC   = 7;
+}
 
 message flex_hello {
-	optional flex_header header = 1;
+    optional flex_header header = 1;
+    optional uint64 bs_id = 2;        // Unique id to distinguish the eNB
+    repeated flex_bs_capability capabilities = 3;
 }
 
 message flex_echo_request {
@@ -131,7 +144,6 @@ message flex_enb_config_request {
 
 message flex_enb_config_reply {
 	optional flex_header header = 1;
-	optional uint64 eNB_id = 2;		// Unique id to distinguish the eNB
 	repeated flex_cell_config cell_config = 3;
         optional uint32 device_spec = 4;
 }
@@ -223,4 +235,6 @@ message flex_echo_reply_latency {
 	}
 }
 
-
+message flex_disconnect {
+        optional flex_header header = 1;
+}
diff --git a/openair2/ENB_APP/MESSAGES/V2/header.proto b/openair2/ENB_APP/MESSAGES/V2/header.proto
index 8900b934920eca605cce1746c2aa014ef8564bce..c91d2e2c09929f83545fb057e22d570ebdc22e0e 100644
--- a/openair2/ENB_APP/MESSAGES/V2/header.proto
+++ b/openair2/ENB_APP/MESSAGES/V2/header.proto
@@ -12,6 +12,7 @@ enum flex_type {
      FLPT_HELLO = 0;
      FLPT_ECHO_REQUEST = 1;
      FLPT_ECHO_REPLY = 2;
+     FLPT_DISCONNECT = 20;
 
      // Statistics and measurement messages
      FLPT_STATS_REQUEST = 3;
diff --git a/openair2/ENB_APP/enb_app.c b/openair2/ENB_APP/enb_app.c
index cba0211c51dc640273bb0dd0989793f0a122ceba..0580f0eb52cffe0fffd2cecab1234059b76cfdae 100644
--- a/openair2/ENB_APP/enb_app.c
+++ b/openair2/ENB_APP/enb_app.c
@@ -34,6 +34,7 @@
 #include "enb_config.h"
 #include "assertions.h"
 #include "common/ran_context.h"
+#include "targets/RT/USER/lte-softmodem.h"
 
 #include "common/utils/LOG/log.h"
 
@@ -41,6 +42,7 @@
 #   include "s1ap_eNB.h"
 #   include "sctp_eNB_task.h"
 #   include "gtpv1u_eNB_task.h"
+#   include "flexran_agent.h"
 
 #   include "x2ap_eNB.h"
 #   include "x2ap_messages_types.h"
@@ -49,74 +51,47 @@
 #include "openair1/PHY/INIT/phy_init.h"
 extern unsigned char NB_eNB_INST;
 
-
 extern RAN_CONTEXT_t RC;
 
-
-
-/*------------------------------------------------------------------------------*/
-
 #   define ENB_REGISTER_RETRY_DELAY 10
 
-
 #include "targets/RT/USER/lte-softmodem.h"
 
-/*------------------------------------------------------------------------------*/
 
-/*
-static void configure_phy(module_id_t enb_id, const Enb_properties_array_t* enb_properties)
-{
-  MessageDef *msg_p;
-  int CC_id;
-
-  msg_p = itti_alloc_new_message (TASK_ENB_APP, PHY_CONFIGURATION_REQ);
-
-  for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
-    PHY_CONFIGURATION_REQ (msg_p).frame_type[CC_id]              = enb_properties->properties[enb_id]->frame_type[CC_id];
-    PHY_CONFIGURATION_REQ (msg_p).prefix_type[CC_id]             = enb_properties->properties[enb_id]->prefix_type[CC_id];
-    PHY_CONFIGURATION_REQ (msg_p).downlink_frequency[CC_id]      = enb_properties->properties[enb_id]->downlink_frequency[CC_id];
-    PHY_CONFIGURATION_REQ (msg_p).uplink_frequency_offset[CC_id] = enb_properties->properties[enb_id]->uplink_frequency_offset[CC_id];
-    PHY_CONFIGURATION_REQ (msg_p).nb_antennas_tx[CC_id]          = enb_properties->properties[enb_id]->nb_antennas_tx[CC_id];
-    PHY_CONFIGURATION_REQ (msg_p).nb_antennas_rx[CC_id]          = enb_properties->properties[enb_id]->nb_antennas_rx[CC_id];
-    PHY_CONFIGURATION_REQ (msg_p).tx_gain[CC_id]                 = enb_properties->properties[enb_id]->tx_gain[CC_id];
-    PHY_CONFIGURATION_REQ (msg_p).rx_gain[CC_id]                 = enb_properties->properties[enb_id]->rx_gain[CC_id];
-  }
 
-  itti_send_msg_to_task (TASK_PHY_ENB, ENB_MODULE_ID_TO_INSTANCE(enb_id), msg_p);
-}
-*/
-
-/*------------------------------------------------------------------------------*/
-static void configure_rrc(uint32_t enb_id) {
-  MessageDef *msg_p = NULL;
-  //  int CC_id;
-  msg_p = itti_alloc_new_message (TASK_ENB_APP, RRC_CONFIGURATION_REQ);
-
-  if (RC.rrc[enb_id]) {
-    RCconfig_RRC(msg_p,enb_id, RC.rrc[enb_id]);
-    LOG_I(ENB_APP,"Sending configuration message to RRC task\n");
-    itti_send_msg_to_task (TASK_RRC_ENB, ENB_MODULE_ID_TO_INSTANCE(enb_id), msg_p);
-  } else AssertFatal(0,"RRC context for eNB %d not allocated\n",enb_id);
-}
 
 /*------------------------------------------------------------------------------*/
 
-static uint32_t eNB_app_register(uint32_t enb_id_start, uint32_t enb_id_end) { //, const Enb_properties_array_t *enb_properties)
+static uint32_t eNB_app_register(ngran_node_t node_type,uint32_t enb_id_start, uint32_t enb_id_end) {
   uint32_t         enb_id;
   MessageDef      *msg_p;
   uint32_t         register_enb_pending = 0;
 
   for (enb_id = enb_id_start; (enb_id < enb_id_end) ; enb_id++) {
     {
-      /* note:  there is an implicit relationship between the data structure and the message name */
-      msg_p = itti_alloc_new_message (TASK_ENB_APP, S1AP_REGISTER_ENB_REQ);
-      RCconfig_S1(msg_p, enb_id);
+      if (NODE_IS_DU(node_type)) { // F1AP registration
+        // configure F1AP here for F1C
+        LOG_I(ENB_APP,"ngran_eNB_DU: Allocating ITTI message for F1AP_SETUP_REQ\n");
+        msg_p = itti_alloc_new_message (TASK_ENB_APP, F1AP_SETUP_REQ);
+        RCconfig_DU_F1(msg_p, enb_id);
+
+        LOG_I(ENB_APP,"[eNB %d] eNB_app_register via F1AP for instance %d\n", enb_id, ENB_MODULE_ID_TO_INSTANCE(enb_id));
+        itti_send_msg_to_task (TASK_DU_F1, ENB_MODULE_ID_TO_INSTANCE(enb_id), msg_p);
+        // configure GTPu here for F1U
+      }
+      else { // S1AP registration
+        /* note:  there is an implicit relationship between the data structure and the message name */
+        msg_p = itti_alloc_new_message (TASK_ENB_APP, S1AP_REGISTER_ENB_REQ);
+        RCconfig_S1(msg_p, enb_id);
+
+        if (enb_id == 0) RCconfig_gtpu();
+
+        LOG_I(ENB_APP,"default drx %d\n",((S1AP_REGISTER_ENB_REQ(msg_p)).default_drx));
 
-      if (enb_id == 0) RCconfig_gtpu();
+        LOG_I(ENB_APP,"[eNB %d] eNB_app_register via S1AP for instance %d\n", enb_id, ENB_MODULE_ID_TO_INSTANCE(enb_id));
+        itti_send_msg_to_task (TASK_S1AP, ENB_MODULE_ID_TO_INSTANCE(enb_id), msg_p);
+      }
 
-      LOG_I(ENB_APP,"default drx %d\n",((S1AP_REGISTER_ENB_REQ(msg_p)).default_drx));
-      LOG_I(ENB_APP,"[eNB %d] eNB_app_register for instance %d\n", enb_id, ENB_MODULE_ID_TO_INSTANCE(enb_id));
-      itti_send_msg_to_task (TASK_S1AP, ENB_MODULE_ID_TO_INSTANCE(enb_id), msg_p);
       register_enb_pending++;
     }
   }
@@ -145,52 +120,30 @@ static uint32_t eNB_app_register_x2(uint32_t enb_id_start, uint32_t enb_id_end)
 
 /*------------------------------------------------------------------------------*/
 void *eNB_app_task(void *args_p) {
-  uint32_t                        enb_nb = RC.nb_inst;
+  uint32_t                        enb_nb = RC.nb_inst; 
   uint32_t                        enb_id_start = 0;
   uint32_t                        enb_id_end = enb_id_start + enb_nb;
   uint32_t                        register_enb_pending=0;
-  uint32_t                        registered_enb;
+  uint32_t                        registered_enb=0;
   long                            enb_register_retry_timer_id;
   uint32_t                        x2_register_enb_pending = 0;
   uint32_t                        x2_registered_enb = 0;
   long                            x2_enb_register_retry_timer_id;
-  uint32_t                        enb_id;
   MessageDef                     *msg_p           = NULL;
   instance_t                      instance;
   int                             result;
   /* for no gcc warnings */
   (void)instance;
   itti_mark_task_ready (TASK_ENB_APP);
-  LOG_I(PHY, "%s() Task ready initialise structures\n", __FUNCTION__);
-  RCconfig_L1();
-  RCconfig_macrlc();
-  LOG_I(PHY, "%s() RC.nb_L1_inst:%d\n", __FUNCTION__, RC.nb_L1_inst);
-
-  if (RC.nb_L1_inst>0) AssertFatal(l1_north_init_eNB()==0,"could not initialize L1 north interface\n");
-
-  AssertFatal (enb_nb <= RC.nb_inst,
-               "Number of eNB is greater than eNB defined in configuration file (%d/%d)!",
-               enb_nb, RC.nb_inst);
-  LOG_I(ENB_APP,"Allocating eNB_RRC_INST for %d instances\n",RC.nb_inst);
-  RC.rrc = (eNB_RRC_INST **)malloc(RC.nb_inst*sizeof(eNB_RRC_INST *));
-  LOG_I(PHY, "%s() RC.nb_inst:%d RC.rrc:%p\n", __FUNCTION__, RC.nb_inst, RC.rrc);
-
-  for (enb_id = enb_id_start; (enb_id < enb_id_end) ; enb_id++) {
-    RC.rrc[enb_id] = (eNB_RRC_INST *)malloc(sizeof(eNB_RRC_INST));
-    LOG_I(PHY, "%s() Creating RRC instance RC.rrc[%d]:%p (%d of %d)\n", __FUNCTION__, enb_id, RC.rrc[enb_id], enb_id+1, enb_id_end);
-    memset((void *)RC.rrc[enb_id],0,sizeof(eNB_RRC_INST));
-    configure_rrc(enb_id);
-  }
 
+  /* Try to register each eNB */
+  // This assumes that node_type of all RRC instances is the same
   if (EPC_MODE_ENABLED) {
-    /* Try to register each eNB */
-    registered_enb = 0;
-    register_enb_pending = eNB_app_register (enb_id_start, enb_id_end);//, enb_properties_p);
+    register_enb_pending = eNB_app_register(RC.rrc[0]->node_type, enb_id_start, enb_id_end);
   }
 
-  if (is_x2ap_enabled()) {
     /* Try to register each eNB with each other */
-    x2_registered_enb = 0;
+  if (is_x2ap_enabled() && !NODE_IS_DU(RC.rrc[0]->node_type)) {
     x2_register_enb_pending = eNB_app_register_x2 (enb_id_start, enb_id_end);
   }
 
@@ -200,20 +153,21 @@ void *eNB_app_task(void *args_p) {
     instance = ITTI_MSG_INSTANCE (msg_p);
 
     switch (ITTI_MSG_ID(msg_p)) {
-      case TERMINATE_MESSAGE:
-        LOG_W(ENB_APP, " *** Exiting ENB_APP thread\n");
-        itti_exit_task ();
-        break;
+    case TERMINATE_MESSAGE:
+      LOG_W(ENB_APP, " *** Exiting ENB_APP thread\n");
+      itti_exit_task ();
+      break;
 
-      case MESSAGE_TEST:
-        LOG_I(ENB_APP, "Received %s\n", ITTI_MSG_NAME(msg_p));
-        break;
+    case MESSAGE_TEST:
+      LOG_I(ENB_APP, "Received %s\n", ITTI_MSG_NAME(msg_p));
+      break;
 
-      case SOFT_RESTART_MESSAGE:
-        handle_reconfiguration(instance);
-        break;
+    case SOFT_RESTART_MESSAGE:
+      handle_reconfiguration(instance);
+      break;
 
-      case S1AP_REGISTER_ENB_CNF:
+    case S1AP_REGISTER_ENB_CNF:
+      AssertFatal(!NODE_IS_DU(RC.rrc[0]->node_type), "Should not have received S1AP_REGISTER_ENB_CNF\n");
         if (EPC_MODE_ENABLED) {
           LOG_I(ENB_APP, "[eNB %d] Received %s: associated MME %d\n", instance, ITTI_MSG_NAME (msg_p),
                 S1AP_REGISTER_ENB_CNF(msg_p).nb_mme);
@@ -243,87 +197,131 @@ void *eNB_app_task(void *args_p) {
                 sleep(ENB_REGISTER_RETRY_DELAY);
                 /* Restart the registration process */
                 registered_enb = 0;
-                register_enb_pending = eNB_app_register (enb_id_start, enb_id_end);//, enb_properties_p);
+                register_enb_pending = eNB_app_register (RC.rrc[0]->node_type,enb_id_start, enb_id_end);
               }
             }
           }
         } /* if (EPC_MODE_ENABLED) */
 
-        break;
+      break;
 
-      case S1AP_DEREGISTERED_ENB_IND:
-        if (EPC_MODE_ENABLED) {
-          LOG_W(ENB_APP, "[eNB %d] Received %s: associated MME %d\n", instance, ITTI_MSG_NAME (msg_p),
-                S1AP_DEREGISTERED_ENB_IND(msg_p).nb_mme);
-          /* TODO handle recovering of registration */
-        }
+    case F1AP_SETUP_RESP:
+      AssertFatal(NODE_IS_DU(RC.rrc[0]->node_type), "Should not have received F1AP_REGISTER_ENB_CNF in CU/eNB\n");
 
-        break;
+      LOG_I(ENB_APP, "Received %s: associated ngran_eNB_CU %s with %d cells to activate\n", ITTI_MSG_NAME (msg_p),
+	    F1AP_SETUP_RESP(msg_p).gNB_CU_name,F1AP_SETUP_RESP(msg_p).num_cells_to_activate);
+      
+      handle_f1ap_setup_resp(&F1AP_SETUP_RESP(msg_p));
 
-      case TIMER_HAS_EXPIRED:
-        if (EPC_MODE_ENABLED) {
-          LOG_I(ENB_APP, " Received %s: timer_id %ld\n", ITTI_MSG_NAME (msg_p), TIMER_HAS_EXPIRED(msg_p).timer_id);
+      DevAssert(register_enb_pending > 0);
+      register_enb_pending--;
 
-          if (TIMER_HAS_EXPIRED (msg_p).timer_id == enb_register_retry_timer_id) {
-            /* Restart the registration process */
-            registered_enb = 0;
-            register_enb_pending = eNB_app_register (enb_id_start, enb_id_end);//, enb_properties_p);
-          }
+      /* Check if at least eNB is registered with one MME */
+      if (F1AP_SETUP_RESP(msg_p).num_cells_to_activate > 0) {
+        registered_enb++;
+      }
 
-          if (TIMER_HAS_EXPIRED (msg_p).timer_id == x2_enb_register_retry_timer_id) {
+      /* Check if all register eNB requests have been processed */
+      if (register_enb_pending == 0) {
+        if (registered_enb == enb_nb) {
+          /* If all eNB cells are registered, start L2L1 task */
+          MessageDef *msg_init_p;
+
+          msg_init_p = itti_alloc_new_message (TASK_ENB_APP, INITIALIZE_MESSAGE);
+          itti_send_msg_to_task (TASK_L2L1, INSTANCE_DEFAULT, msg_init_p);
+
+        } else {
+          LOG_W(ENB_APP, " %d eNB not associated with a MME, retrying registration in %d seconds ...\n",
+                enb_nb - registered_enb,  ENB_REGISTER_RETRY_DELAY);
+
+          /* Restart the eNB registration process in ENB_REGISTER_RETRY_DELAY seconds */
+          if (timer_setup (ENB_REGISTER_RETRY_DELAY, 0, TASK_ENB_APP, INSTANCE_DEFAULT, TIMER_ONE_SHOT,
+                           NULL, &enb_register_retry_timer_id) < 0) {
+            LOG_E(ENB_APP, " Can not start eNB register retry timer, use \"sleep\" instead!\n");
+
+            sleep(ENB_REGISTER_RETRY_DELAY);
             /* Restart the registration process */
-            x2_registered_enb = 0;
-            x2_register_enb_pending = eNB_app_register_x2 (enb_id_start, enb_id_end);
+            registered_enb = 0;
+            register_enb_pending = eNB_app_register (RC.rrc[0]->node_type,enb_id_start, enb_id_end);//, enb_properties_p);
           }
-        } /* if (EPC_MODE_ENABLED) */
+        }
+      }
 
-        break;
+      break;
 
-      case X2AP_DEREGISTERED_ENB_IND:
-        LOG_W(ENB_APP, "[eNB %d] Received %s: associated eNB %d\n", instance, ITTI_MSG_NAME (msg_p),
-              X2AP_DEREGISTERED_ENB_IND(msg_p).nb_x2);
-        /* TODO handle recovering of registration */
-        break;
+    case S1AP_DEREGISTERED_ENB_IND:
+      if (EPC_MODE_ENABLED) {
+  	LOG_W(ENB_APP, "[eNB %d] Received %s: associated MME %d\n", instance, ITTI_MSG_NAME (msg_p),
+  	      S1AP_DEREGISTERED_ENB_IND(msg_p).nb_mme);
+  	/* TODO handle recovering of registration */
+      }
 
-      case X2AP_REGISTER_ENB_CNF:
-        LOG_I(ENB_APP, "[eNB %d] Received %s: associated eNB %d\n", instance, ITTI_MSG_NAME (msg_p),
-              X2AP_REGISTER_ENB_CNF(msg_p).nb_x2);
-        DevAssert(x2_register_enb_pending > 0);
-        x2_register_enb_pending--;
+      break;
 
-        /* Check if at least eNB is registered with one target eNB */
-        if (X2AP_REGISTER_ENB_CNF(msg_p).nb_x2 > 0) {
-          x2_registered_enb++;
-        }
+    case TIMER_HAS_EXPIRED:
+        if (EPC_MODE_ENABLED) {
+      LOG_I(ENB_APP, " Received %s: timer_id %ld\n", ITTI_MSG_NAME (msg_p), TIMER_HAS_EXPIRED(msg_p).timer_id);
+
+      if (TIMER_HAS_EXPIRED (msg_p).timer_id == enb_register_retry_timer_id) {
+        /* Restart the registration process */
+        registered_enb = 0;
+        register_enb_pending = eNB_app_register (RC.rrc[0]->node_type, enb_id_start, enb_id_end);
+      }
+
+      if (TIMER_HAS_EXPIRED (msg_p).timer_id == x2_enb_register_retry_timer_id) {
+        /* Restart the registration process */
+	x2_registered_enb = 0;
+        x2_register_enb_pending = eNB_app_register_x2 (enb_id_start, enb_id_end);
+      }
+        } /* if (EPC_MODE_ENABLED) */
 
-        /* Check if all register eNB requests have been processed */
-        if (x2_register_enb_pending == 0) {
-          if (x2_registered_enb == enb_nb) {
-            /* If all eNB are registered, start RRC HO task */
+      break;
+
+    case X2AP_DEREGISTERED_ENB_IND:
+      LOG_W(ENB_APP, "[eNB %d] Received %s: associated eNB %d\n", instance, ITTI_MSG_NAME (msg_p),
+            X2AP_DEREGISTERED_ENB_IND(msg_p).nb_x2);
+      /* TODO handle recovering of registration */
+      break;
+
+    case X2AP_REGISTER_ENB_CNF:
+      LOG_I(ENB_APP, "[eNB %d] Received %s: associated eNB %d\n", instance, ITTI_MSG_NAME (msg_p),
+            X2AP_REGISTER_ENB_CNF(msg_p).nb_x2);
+      DevAssert(x2_register_enb_pending > 0);
+      x2_register_enb_pending--;
+
+      /* Check if at least eNB is registered with one target eNB */
+      if (X2AP_REGISTER_ENB_CNF(msg_p).nb_x2 > 0) {
+        x2_registered_enb++;
+      }
+
+      /* Check if all register eNB requests have been processed */
+      if (x2_register_enb_pending == 0) {
+        if (x2_registered_enb == enb_nb) {
+          /* If all eNB are registered, start RRC HO task */
           } else {
-            uint32_t x2_not_associated = enb_nb - x2_registered_enb;
-            LOG_W(ENB_APP, " %d eNB %s not associated with the target\n",
-                  x2_not_associated, x2_not_associated > 1 ? "are" : "is");
-
-            // timer to retry
-            /* Restart the eNB registration process in ENB_REGISTER_RETRY_DELAY seconds */
-            if (timer_setup (X2AP_ENB_REGISTER_RETRY_DELAY, 0, TASK_ENB_APP,
-                             INSTANCE_DEFAULT, TIMER_ONE_SHOT, NULL,
-                             &x2_enb_register_retry_timer_id) < 0) {
-              LOG_E(ENB_APP, " Can not start eNB X2AP register: retry timer, use \"sleep\" instead!\n");
-              sleep(X2AP_ENB_REGISTER_RETRY_DELAY);
-              /* Restart the registration process */
-              x2_registered_enb = 0;
-              x2_register_enb_pending = eNB_app_register_x2 (enb_id_start, enb_id_end);
-            }
+          uint32_t x2_not_associated = enb_nb - x2_registered_enb;
+          LOG_W(ENB_APP, " %d eNB %s not associated with the target\n",
+                x2_not_associated, x2_not_associated > 1 ? "are" : "is");
+
+	  // timer to retry
+	  /* Restart the eNB registration process in ENB_REGISTER_RETRY_DELAY seconds */
+          if (timer_setup (X2AP_ENB_REGISTER_RETRY_DELAY, 0, TASK_ENB_APP,
+			   INSTANCE_DEFAULT, TIMER_ONE_SHOT, NULL,
+			   &x2_enb_register_retry_timer_id) < 0) {
+            LOG_E(ENB_APP, " Can not start eNB X2AP register: retry timer, use \"sleep\" instead!\n");
+            sleep(X2AP_ENB_REGISTER_RETRY_DELAY);
+            /* Restart the registration process */
+            x2_registered_enb = 0;
+            x2_register_enb_pending = eNB_app_register_x2 (enb_id_start, enb_id_end);
           }
         }
+      }
 
-        break;
+      break;
 
-      default:
-        LOG_E(ENB_APP, "Received unexpected message %s\n", ITTI_MSG_NAME (msg_p));
-        break;
+    default:
+      LOG_E(ENB_APP, "Received unexpected message %s\n", ITTI_MSG_NAME (msg_p));
+      break;
     }
 
     result = itti_free (ITTI_MSG_ORIGIN_ID(msg_p), msg_p);
diff --git a/openair2/ENB_APP/enb_config.c b/openair2/ENB_APP/enb_config.c
index e85fe5ac896d4adcfa692c912b90a0158ea51008..2e97f58e814cb17bd222d4980481d46a8c89ecb5 100644
--- a/openair2/ENB_APP/enb_config.c
+++ b/openair2/ENB_APP/enb_config.c
@@ -38,6 +38,7 @@
 #include "intertask_interface.h"
 #include "s1ap_eNB.h"
 #include "sctp_eNB_task.h"
+#include "common/ran_context.h"
 #include "sctp_default_values.h"
 #include "LTE_SystemInformationBlockType2.h"
 #include "LAYER2/MAC/mac_extern.h"
@@ -67,51 +68,10 @@ extern char *parallel_config;
 extern char *worker_config;
 
 void RCconfig_flexran() {
-  uint16_t i;
-  uint16_t num_enbs;
-  char aprefix[MAX_OPTNAME_SIZE*2 + 8];
-  /* this will possibly truncate the cell id (RRC assumes int32_t).
-     Both Nid_cell and enb_id are signed in RRC case, but we use unsigned for
-     the bitshifting to work properly */
-  int32_t Nid_cell = 0;
-  uint16_t Nid_cell_tr = 0;
-  uint32_t enb_id = 0;
   /* get number of eNBs */
   paramdef_t ENBSParams[] = ENBSPARAMS_DESC;
   config_get(ENBSParams, sizeof(ENBSParams)/sizeof(paramdef_t), NULL);
-  num_enbs = ENBSParams[ENB_ACTIVE_ENBS_IDX].numelt;
-  /* for eNB ID */
-  paramdef_t ENBParams[]  = ENBPARAMS_DESC;
-  paramlist_def_t ENBParamList = {ENB_CONFIG_STRING_ENB_LIST, NULL, 0};
-  /* for Nid_cell */
-  checkedparam_t config_check_CCparams[] = CCPARAMS_CHECK;
-  ccparams_lte_t ccparams_lte;
-  memset((void *)&ccparams_lte,0,sizeof(ccparams_lte_t));
-  paramdef_t CCsParams[] = CCPARAMS_DESC(ccparams_lte);
-  paramlist_def_t CCsParamList = {ENB_CONFIG_STRING_COMPONENT_CARRIERS, NULL, 0};
-
-  // Note: these should be turned on for EMTC support inside of FlexRAN
-  // ccparams_emtc_t ccparams_emtc;
-  //paramdef_t brParams[]              = BRPARAMS_DESC(ccparams_emtc);
-  //paramdef_t schedulingInfoBrParams[] = SI_INFO_BR_DESC(ccparams_emtc);
-  //paramlist_def_t schedulingInfoBrParamList = {ENB_CONFIG_STRING_SCHEDULING_INFO_BR, NULL, 0};
-  //paramdef_t rachcelevelParams[]     = RACH_CE_LEVELINFOLIST_R13_DESC(ccparams_emtc);
-  //paramlist_def_t rachcelevellist    = {ENB_CONFIG_STRING_RACH_CE_LEVELINFOLIST_R13, NULL, 0};
-  //paramdef_t rsrprangeParams[]       = RSRP_RANGE_LIST_DESC(ccparams_emtc);
-  //paramlist_def_t rsrprangelist      = {ENB_CONFIG_STRING_RSRP_RANGE_LIST, NULL, 0};
-  //paramdef_t prachParams[]           = PRACH_PARAMS_CE_R13_DESC(ccparams_emtc);
-  //paramlist_def_t prachParamslist    = {ENB_CONFIG_STRING_PRACH_PARAMETERS_CE_R13, NULL, 0};
-  //paramdef_t n1PUCCH_ANR13Params[]   = N1PUCCH_AN_INFOLIST_R13_DESC(ccparams_emtc);
-  //paramlist_def_t n1PUCCHInfoList    = {ENB_CONFIG_STRING_N1PUCCH_AN_INFOLIST_R13, NULL, 0};
-  //paramdef_t pcchv1310Params[]       = PCCH_CONFIG_V1310_DESC(ccparams_emtc);
-  //paramdef_t sib2freqhoppingParams[] = SIB2_FREQ_HOPPING_R13_DESC(ccparams_emtc);
-
-  //  paramdef_t SRB1Params[] = SRB1PARAMS_DESC;
-
-  /* map parameter checking array instances to parameter definition array instances */
-  for (int I = 0; I < (sizeof(CCsParams) / sizeof(paramdef_t)); I++) {
-    CCsParams[I].chkPptr = &(config_check_CCparams[I]);
-  }
+  uint16_t num_enbs = ENBSParams[ENB_ACTIVE_ENBS_IDX].numelt;
 
   paramdef_t flexranParams[] = FLEXRANPARAMS_DESC;
   config_get(flexranParams, sizeof(flexranParams)/sizeof(paramdef_t), CONFIG_STRING_NETWORK_CONTROLLER_CONFIG);
@@ -124,7 +84,7 @@ void RCconfig_flexran() {
                 num_enbs, sizeof(flexran_agent_info_t *));
   }
 
-  for (i = 0; i < num_enbs; i++) {
+  for (uint16_t i = 0; i < num_enbs; i++) {
     RC.flexran[i] = calloc(1, sizeof(flexran_agent_info_t));
     AssertFatal(RC.flexran[i],
                 "can't ALLOCATE %zu Bytes for flexran agent info (iteration %d/%d)\n",
@@ -142,37 +102,8 @@ void RCconfig_flexran() {
     RC.flexran[i]->remote_port      = *(flexranParams[FLEXRAN_PORT_IDX].uptr);
     RC.flexran[i]->cache_name       = strdup(*(flexranParams[FLEXRAN_CACHE_IDX].strptr));
     RC.flexran[i]->node_ctrl_state  = strcasecmp(*(flexranParams[FLEXRAN_AWAIT_RECONF_IDX].strptr), "yes") == 0 ? ENB_WAIT : ENB_NORMAL_OPERATION;
-    config_getlist(&ENBParamList, ENBParams, sizeof(ENBParams)/sizeof(paramdef_t),NULL);
-
-    /* eNB ID from configuration, as read in by RCconfig_RRC() */
-    if (!ENBParamList.paramarray[i][ENB_ENB_ID_IDX].uptr) {
-      // Calculate a default eNB ID
-      if (EPC_MODE_ENABLED)
-        enb_id = i + (s1ap_generate_eNB_id () & 0xFFFF8);
-      else
-        enb_id = i;
-    } else {
-      enb_id = *(ENBParamList.paramarray[i][ENB_ENB_ID_IDX].uptr);
-    }
 
-    /* cell ID */
-    sprintf(aprefix, "%s.[%i]", ENB_CONFIG_STRING_ENB_LIST, i);
-    config_getlist(&CCsParamList, NULL, 0, aprefix);
-
-    if (CCsParamList.numelt > 0) {
-      sprintf(aprefix, "%s.[%i].%s.[%i]", ENB_CONFIG_STRING_ENB_LIST, i, ENB_CONFIG_STRING_COMPONENT_CARRIERS, 0);
-      config_get(CCsParams, sizeof(CCsParams)/sizeof(paramdef_t), aprefix);
-      Nid_cell_tr = (uint16_t) Nid_cell;
-    }
-
-    RC.flexran[i]->mod_id   = i;
-    RC.flexran[i]->agent_id = (((uint64_t)i) << 48) | (((uint64_t)enb_id) << 16) | ((uint64_t)Nid_cell_tr);
-    /* assume for the moment the monolithic case, i.e. agent can provide
-       information for all layers */
-    RC.flexran[i]->capability_mask = FLEXRAN_CAP_LOPHY | FLEXRAN_CAP_HIPHY
-                                     | FLEXRAN_CAP_LOMAC | FLEXRAN_CAP_HIMAC
-                                     | FLEXRAN_CAP_RLC   | FLEXRAN_CAP_PDCP
-                                     | FLEXRAN_CAP_SDAP  | FLEXRAN_CAP_RRC;
+    RC.flexran[i]->mod_id  = i;
   }
 }
 
@@ -275,18 +206,21 @@ void RCconfig_L1(void) {
   }
 }
 
-void RCconfig_macrlc() {
+void RCconfig_macrlc(int macrlc_has_f1[MAX_MAC_INST]) {
   int               j;
   paramdef_t MacRLC_Params[] = MACRLCPARAMS_DESC;
   paramlist_def_t MacRLC_ParamList = {CONFIG_STRING_MACRLC_LIST,NULL,0};
   config_getlist( &MacRLC_ParamList,MacRLC_Params,sizeof(MacRLC_Params)/sizeof(paramdef_t), NULL);
 
+  config_getlist( &MacRLC_ParamList,MacRLC_Params,sizeof(MacRLC_Params)/sizeof(paramdef_t), NULL);    
+
   if ( MacRLC_ParamList.numelt > 0) {
-    RC.nb_macrlc_inst=MacRLC_ParamList.numelt;
-    mac_top_init_eNB();
+
+    RC.nb_macrlc_inst=MacRLC_ParamList.numelt; 
+    mac_top_init_eNB();   
     RC.nb_mac_CC = (int *)malloc(RC.nb_macrlc_inst*sizeof(int));
 
-    for (j=0; j<RC.nb_macrlc_inst; j++) {
+    for (j = 0; j < RC.nb_macrlc_inst; j++) {
       RC.mac[j]->puSch10xSnr = *(MacRLC_ParamList.paramarray[j][MACRLC_PUSCH10xSNR_IDX ].iptr);
       RC.mac[j]->puCch10xSnr = *(MacRLC_ParamList.paramarray[j][MACRLC_PUCCH10xSNR_IDX ].iptr);
       RC.nb_mac_CC[j] = *(MacRLC_ParamList.paramarray[j][MACRLC_CC_IDX].iptr);
@@ -294,16 +228,19 @@ void RCconfig_macrlc() {
       //printf("PHY_TEST = %d,%d\n", RC.mac[j]->phy_test, j);
 
       if (strcmp(*(MacRLC_ParamList.paramarray[j][MACRLC_TRANSPORT_N_PREFERENCE_IDX].strptr), "local_RRC") == 0) {
-        // check number of instances is same as RRC/PDCP
-      } else if (strcmp(*(MacRLC_ParamList.paramarray[j][MACRLC_TRANSPORT_N_PREFERENCE_IDX].strptr), "cudu") == 0) {
-        RC.mac[j]->eth_params_n.local_if_name            = strdup(*(MacRLC_ParamList.paramarray[j][MACRLC_LOCAL_N_IF_NAME_IDX].strptr));
-        RC.mac[j]->eth_params_n.my_addr                  = strdup(*(MacRLC_ParamList.paramarray[j][MACRLC_LOCAL_N_ADDRESS_IDX].strptr));
-        RC.mac[j]->eth_params_n.remote_addr              = strdup(*(MacRLC_ParamList.paramarray[j][MACRLC_REMOTE_N_ADDRESS_IDX].strptr));
-        RC.mac[j]->eth_params_n.my_portc                 = *(MacRLC_ParamList.paramarray[j][MACRLC_LOCAL_N_PORTC_IDX].iptr);
-        RC.mac[j]->eth_params_n.remote_portc             = *(MacRLC_ParamList.paramarray[j][MACRLC_REMOTE_N_PORTC_IDX].iptr);
-        RC.mac[j]->eth_params_n.my_portd                 = *(MacRLC_ParamList.paramarray[j][MACRLC_LOCAL_N_PORTD_IDX].iptr);
-        RC.mac[j]->eth_params_n.remote_portd             = *(MacRLC_ParamList.paramarray[j][MACRLC_REMOTE_N_PORTD_IDX].iptr);;
-        RC.mac[j]->eth_params_n.transp_preference        = ETH_UDP_MODE;
+	// check number of instances is same as RRC/PDCP
+	printf("Configuring local RRC for MACRLC\n");
+      } else if (strcmp(*(MacRLC_ParamList.paramarray[j][MACRLC_TRANSPORT_N_PREFERENCE_IDX].strptr), "f1") == 0) {
+	printf("Configuring F1 interfaces for MACRLC\n");
+	RC.mac[j]->eth_params_n.local_if_name            = strdup(*(MacRLC_ParamList.paramarray[j][MACRLC_LOCAL_N_IF_NAME_IDX].strptr));
+	RC.mac[j]->eth_params_n.my_addr                  = strdup(*(MacRLC_ParamList.paramarray[j][MACRLC_LOCAL_N_ADDRESS_IDX].strptr));
+	RC.mac[j]->eth_params_n.remote_addr              = strdup(*(MacRLC_ParamList.paramarray[j][MACRLC_REMOTE_N_ADDRESS_IDX].strptr));
+	RC.mac[j]->eth_params_n.my_portc                 = *(MacRLC_ParamList.paramarray[j][MACRLC_LOCAL_N_PORTC_IDX].iptr);
+	RC.mac[j]->eth_params_n.remote_portc             = *(MacRLC_ParamList.paramarray[j][MACRLC_REMOTE_N_PORTC_IDX].iptr);
+	RC.mac[j]->eth_params_n.my_portd                 = *(MacRLC_ParamList.paramarray[j][MACRLC_LOCAL_N_PORTD_IDX].iptr);
+	RC.mac[j]->eth_params_n.remote_portd             = *(MacRLC_ParamList.paramarray[j][MACRLC_REMOTE_N_PORTD_IDX].iptr);;
+	RC.mac[j]->eth_params_n.transp_preference        = ETH_UDP_MODE;
+        macrlc_has_f1[j]                                 = 1;
       } else { // other midhaul
         AssertFatal(1==0,"MACRLC %d: %s unknown northbound midhaul\n",j, *(MacRLC_ParamList.paramarray[j][MACRLC_TRANSPORT_N_PREFERENCE_IDX].strptr));
       }
@@ -337,17 +274,19 @@ void RCconfig_macrlc() {
         printf("sched mode = default %d [%s]\n",global_scheduler_mode,*(MacRLC_ParamList.paramarray[j][MACRLC_SCHED_MODE_IDX].strptr));
       }
     }// j=0..num_inst
-  } else {// MacRLC_ParamList.numelt > 0
+  } /*else {// MacRLC_ParamList.numelt > 0 // ignore it
     AssertFatal (0,
                  "No " CONFIG_STRING_MACRLC_LIST " configuration found");
-  }
+  }*/
 }
 
-int RCconfig_RRC(MessageDef *msg_p, uint32_t i, eNB_RRC_INST *rrc) {
+int RCconfig_RRC(uint32_t i, eNB_RRC_INST *rrc, int macrlc_has_f1) {
   int               num_enbs                      = 0;
   int               j,k                           = 0;
   int32_t           enb_id                        = 0;
   int               nb_cc                         = 0;
+  MessageDef *msg_p = itti_alloc_new_message(TASK_RRC_ENB, RRC_CONFIGURATION_REQ);
+
   ccparams_lte_t ccparams_lte;
   ccparams_sidelink_t SLconfig;
   ccparams_eMTC_t eMTCconfig;
@@ -399,20 +338,50 @@ int RCconfig_RRC(MessageDef *msg_p, uint32_t i, eNB_RRC_INST *rrc) {
       enb_id = *(ENBParamList.paramarray[i][ENB_ENB_ID_IDX].uptr);
     }
 
-    LOG_I(ENB_APP,"RRC %d: Southbound Transport %s\n",i,*(ENBParamList.paramarray[i][ENB_TRANSPORT_S_PREFERENCE_IDX].strptr));
-
-    if (strcmp(*(ENBParamList.paramarray[i][ENB_TRANSPORT_S_PREFERENCE_IDX].strptr), "local_mac") == 0) {
-    } else if (strcmp(*(ENBParamList.paramarray[i][ENB_TRANSPORT_S_PREFERENCE_IDX].strptr), "cudu") == 0) {
-      rrc->eth_params_s.local_if_name            = strdup(*(ENBParamList.paramarray[i][ENB_LOCAL_S_IF_NAME_IDX].strptr));
-      rrc->eth_params_s.my_addr                  = strdup(*(ENBParamList.paramarray[i][ENB_LOCAL_S_ADDRESS_IDX].strptr));
-      rrc->eth_params_s.remote_addr              = strdup(*(ENBParamList.paramarray[i][ENB_REMOTE_S_ADDRESS_IDX].strptr));
-      rrc->eth_params_s.my_portc                 = *(ENBParamList.paramarray[i][ENB_LOCAL_S_PORTC_IDX].uptr);
-      rrc->eth_params_s.remote_portc             = *(ENBParamList.paramarray[i][ENB_REMOTE_S_PORTC_IDX].uptr);
-      rrc->eth_params_s.my_portd                 = *(ENBParamList.paramarray[i][ENB_LOCAL_S_PORTD_IDX].uptr);
-      rrc->eth_params_s.remote_portd             = *(ENBParamList.paramarray[i][ENB_REMOTE_S_PORTD_IDX].uptr);
-      rrc->eth_params_s.transp_preference        = ETH_UDP_MODE;
-    } else { // other midhaul
-    }
+      LOG_I(RRC,"Instance %d: Southbound Transport %s\n",i,*(ENBParamList.paramarray[i][ENB_TRANSPORT_S_PREFERENCE_IDX].strptr));
+	    
+      if (strcmp(*(ENBParamList.paramarray[i][ENB_TRANSPORT_S_PREFERENCE_IDX].strptr), "f1") == 0) {
+
+	paramdef_t SCTPParams[]  = SCTPPARAMS_DESC;
+	char aprefix[MAX_OPTNAME_SIZE*2 + 8];
+
+	sprintf(aprefix,"%s.[%i].%s",ENB_CONFIG_STRING_ENB_LIST,i,ENB_CONFIG_STRING_SCTP_CONFIG);
+	config_get( SCTPParams,sizeof(SCTPParams)/sizeof(paramdef_t),aprefix); 
+
+        rrc->node_id        = *(ENBParamList.paramarray[0][ENB_ENB_ID_IDX].uptr);
+	LOG_I(ENB_APP,"F1AP: gNB_CU_id[%d] %d\n",k,rrc->node_id);
+
+	rrc->node_name = strdup(*(ENBParamList.paramarray[0][ENB_ENB_NAME_IDX].strptr));
+	LOG_I(ENB_APP,"F1AP: gNB_CU_name[%d] %s\n",k,rrc->node_name);
+
+	rrc->eth_params_s.local_if_name            = strdup(*(ENBParamList.paramarray[i][ENB_LOCAL_S_IF_NAME_IDX].strptr));
+	rrc->eth_params_s.my_addr                  = strdup(*(ENBParamList.paramarray[i][ENB_LOCAL_S_ADDRESS_IDX].strptr));
+	rrc->eth_params_s.remote_addr              = strdup(*(ENBParamList.paramarray[i][ENB_REMOTE_S_ADDRESS_IDX].strptr));
+	rrc->eth_params_s.my_portc                 = *(ENBParamList.paramarray[i][ENB_LOCAL_S_PORTC_IDX].uptr);
+	rrc->eth_params_s.remote_portc             = *(ENBParamList.paramarray[i][ENB_REMOTE_S_PORTC_IDX].uptr);
+	rrc->eth_params_s.my_portd                 = *(ENBParamList.paramarray[i][ENB_LOCAL_S_PORTD_IDX].uptr);
+	rrc->eth_params_s.remote_portd             = *(ENBParamList.paramarray[i][ENB_REMOTE_S_PORTD_IDX].uptr);
+	rrc->eth_params_s.transp_preference        = ETH_UDP_MODE;
+	rrc->node_type                             = ngran_eNB_CU;
+	rrc->sctp_in_streams                       = (uint16_t)*(SCTPParams[ENB_SCTP_INSTREAMS_IDX].uptr);
+	rrc->sctp_out_streams                      = (uint16_t)*(SCTPParams[ENB_SCTP_OUTSTREAMS_IDX].uptr);
+
+      }
+      
+      else {
+	// set to ngran_eNB for now, it will get set to ngran_eNB_DU if macrlc entity which uses F1 is present
+	// Note: we will have to handle the case of ngran_ng_eNB_DU
+	if (macrlc_has_f1 == 0) {
+            rrc->node_type = ngran_eNB;
+            LOG_I(RRC,"Setting node_type to ngran_eNB\n");
+        }
+	else {
+            rrc->node_type = ngran_eNB_DU;
+            LOG_I(RRC,"Setting node_type to ngran_eNB_DU\n");
+        }
+      }	      
+
+      rrc->nr_cellid        = (uint64_t)*(ENBParamList.paramarray[i][ENB_NRCELLID_IDX].u64ptr);
 
     // search if in active list
 
@@ -473,491 +442,497 @@ int RCconfig_RRC(MessageDef *msg_p, uint32_t i, eNB_RRC_INST *rrc) {
             config_get( CCsParams,sizeof(CCsParams)/sizeof(paramdef_t),ccspath);
             //printf("Component carrier %d\n",component_carrier);
             nb_cc++;
-            RRC_CONFIGURATION_REQ (msg_p).tdd_config[j] = ccparams_lte.tdd_config;
-            AssertFatal (ccparams_lte.tdd_config <= LTE_TDD_Config__subframeAssignment_sa6,
-                         "Failed to parse eNB configuration file %s, enb %d illegal tdd_config %d (should be 0-%d)!",
-                         RC.config_file_name, i, ccparams_lte.tdd_config, LTE_TDD_Config__subframeAssignment_sa6);
-            RRC_CONFIGURATION_REQ (msg_p).tdd_config_s[j] = ccparams_lte.tdd_config_s;
-            AssertFatal (ccparams_lte.tdd_config_s <= LTE_TDD_Config__specialSubframePatterns_ssp8,
-                         "Failed to parse eNB configuration file %s, enb %d illegal tdd_config_s %d (should be 0-%d)!",
-                         RC.config_file_name, i, ccparams_lte.tdd_config_s, LTE_TDD_Config__specialSubframePatterns_ssp8);
-
-            if (!ccparams_lte.prefix_type)
-              AssertFatal (0,
-                           "Failed to parse eNB configuration file %s, enb %d define %s: NORMAL,EXTENDED!\n",
-                           RC.config_file_name, i, ENB_CONFIG_STRING_PREFIX_TYPE);
-            else if (strcmp(ccparams_lte.prefix_type, "NORMAL") == 0) {
-              RRC_CONFIGURATION_REQ (msg_p).prefix_type[j] = NORMAL;
-            } else  if (strcmp(ccparams_lte.prefix_type, "EXTENDED") == 0) {
-              RRC_CONFIGURATION_REQ (msg_p).prefix_type[j] = EXTENDED;
-            } else {
-              AssertFatal (0,
-                           "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for prefix_type choice: NORMAL or EXTENDED !\n",
-                           RC.config_file_name, i, ccparams_lte.prefix_type);
-            }
+
+            if (!NODE_IS_CU(rrc->node_type)) {
+              // Cell params, MIB/SIB1 in DU
+              RRC_CONFIGURATION_REQ (msg_p).tdd_config[j] = ccparams_lte.tdd_config;
+              AssertFatal (ccparams_lte.tdd_config <= LTE_TDD_Config__subframeAssignment_sa6,
+                           "Failed to parse eNB configuration file %s, enb %d illegal tdd_config %d (should be 0-%d)!",
+                           RC.config_file_name, i, ccparams_lte.tdd_config, LTE_TDD_Config__subframeAssignment_sa6);
+              RRC_CONFIGURATION_REQ (msg_p).tdd_config_s[j] = ccparams_lte.tdd_config_s;
+              AssertFatal (ccparams_lte.tdd_config_s <= LTE_TDD_Config__specialSubframePatterns_ssp8,
+                           "Failed to parse eNB configuration file %s, enb %d illegal tdd_config_s %d (should be 0-%d)!",
+                           RC.config_file_name, i, ccparams_lte.tdd_config_s, LTE_TDD_Config__specialSubframePatterns_ssp8);
+
+              if (!ccparams_lte.prefix_type)
+                AssertFatal (0,
+                             "Failed to parse eNB configuration file %s, enb %d define %s: NORMAL,EXTENDED!\n",
+                             RC.config_file_name, i, ENB_CONFIG_STRING_PREFIX_TYPE);
+              else if (strcmp(ccparams_lte.prefix_type, "NORMAL") == 0) {
+                RRC_CONFIGURATION_REQ (msg_p).prefix_type[j] = NORMAL;
+              } else  if (strcmp(ccparams_lte.prefix_type, "EXTENDED") == 0) {
+                RRC_CONFIGURATION_REQ (msg_p).prefix_type[j] = EXTENDED;
+              } else {
+                AssertFatal (0,
+                             "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for prefix_type choice: NORMAL or EXTENDED !\n",
+                             RC.config_file_name, i, ccparams_lte.prefix_type);
+              }
 
 #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
 
-            if (!ccparams_lte.pbch_repetition)
-              AssertFatal (0,
-                           "Failed to parse eNB configuration file %s, enb %d define %s: TRUE,FALSE!\n",
-                           RC.config_file_name, i, ENB_CONFIG_STRING_PBCH_REPETITION);
-            else if (strcmp(ccparams_lte.pbch_repetition, "TRUE") == 0) {
-              RRC_CONFIGURATION_REQ (msg_p).pbch_repetition[j] = 1;
-            } else  if (strcmp(ccparams_lte.pbch_repetition, "FALSE") == 0) {
-              RRC_CONFIGURATION_REQ (msg_p).pbch_repetition[j] = 0;
-            } else {
-              AssertFatal (0,
-                           "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for pbch_repetition choice: TRUE or FALSE !\n",
-                           RC.config_file_name, i, ccparams_lte.pbch_repetition);
-            }
+              if (!ccparams_lte.pbch_repetition)
+                AssertFatal (0,
+                             "Failed to parse eNB configuration file %s, enb %d define %s: TRUE,FALSE!\n",
+                             RC.config_file_name, i, ENB_CONFIG_STRING_PBCH_REPETITION);
+              else if (strcmp(ccparams_lte.pbch_repetition, "TRUE") == 0) {
+                RRC_CONFIGURATION_REQ (msg_p).pbch_repetition[j] = 1;
+              } else  if (strcmp(ccparams_lte.pbch_repetition, "FALSE") == 0) {
+                RRC_CONFIGURATION_REQ (msg_p).pbch_repetition[j] = 0;
+              } else {
+                AssertFatal (0,
+                             "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for pbch_repetition choice: TRUE or FALSE !\n",
+                             RC.config_file_name, i, ccparams_lte.pbch_repetition);
+              }
 
 #endif
-            RRC_CONFIGURATION_REQ (msg_p).eutra_band[j] = ccparams_lte.eutra_band;
-            RRC_CONFIGURATION_REQ (msg_p).downlink_frequency[j] = (uint32_t) ccparams_lte.downlink_frequency;
-            RRC_CONFIGURATION_REQ (msg_p).uplink_frequency_offset[j] = (unsigned int) ccparams_lte.uplink_frequency_offset;
-            RRC_CONFIGURATION_REQ (msg_p).Nid_cell[j]= ccparams_lte.Nid_cell;
+              RRC_CONFIGURATION_REQ (msg_p).eutra_band[j] = ccparams_lte.eutra_band;
+              RRC_CONFIGURATION_REQ (msg_p).downlink_frequency[j] = (uint32_t) ccparams_lte.downlink_frequency;
+              RRC_CONFIGURATION_REQ (msg_p).uplink_frequency_offset[j] = (unsigned int) ccparams_lte.uplink_frequency_offset;
+              RRC_CONFIGURATION_REQ (msg_p).Nid_cell[j]= ccparams_lte.Nid_cell;
 
-            if (ccparams_lte.Nid_cell>503) {
-              AssertFatal (0,
-                           "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for Nid_cell choice: 0...503 !\n",
-                           RC.config_file_name, i, ccparams_lte.Nid_cell);
-            }
+              if (ccparams_lte.Nid_cell>503) {
+                AssertFatal (0,
+                             "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for Nid_cell choice: 0...503 !\n",
+                             RC.config_file_name, i, ccparams_lte.Nid_cell);
+              }
 
-            RRC_CONFIGURATION_REQ (msg_p).N_RB_DL[j]= ccparams_lte.N_RB_DL;
+              RRC_CONFIGURATION_REQ (msg_p).N_RB_DL[j]= ccparams_lte.N_RB_DL;
 
-            if ((ccparams_lte.N_RB_DL!=6) &&
-                (ccparams_lte.N_RB_DL!=15) &&
-                (ccparams_lte.N_RB_DL!=25) &&
-                (ccparams_lte.N_RB_DL!=50) &&
-                (ccparams_lte.N_RB_DL!=75) &&
-                (ccparams_lte.N_RB_DL!=100)) {
-              AssertFatal (0,
-                           "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for N_RB_DL choice: 6,15,25,50,75,100 !\n",
-                           RC.config_file_name, i, ccparams_lte.N_RB_DL);
-            }
+              if ((ccparams_lte.N_RB_DL!=6) &&
+                  (ccparams_lte.N_RB_DL!=15) &&
+                  (ccparams_lte.N_RB_DL!=25) &&
+                  (ccparams_lte.N_RB_DL!=50) &&
+                  (ccparams_lte.N_RB_DL!=75) &&
+                  (ccparams_lte.N_RB_DL!=100)) {
+                AssertFatal (0,
+                             "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for N_RB_DL choice: 6,15,25,50,75,100 !\n",
+                             RC.config_file_name, i, ccparams_lte.N_RB_DL);
+              }
 
-            if (strcmp(ccparams_lte.frame_type, "FDD") == 0) {
-              RRC_CONFIGURATION_REQ (msg_p).frame_type[j] = FDD;
-            } else  if (strcmp(ccparams_lte.frame_type, "TDD") == 0) {
-              RRC_CONFIGURATION_REQ (msg_p).frame_type[j] = TDD;
-            } else {
-              AssertFatal (0,
-                           "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for frame_type choice: FDD or TDD !\n",
-                           RC.config_file_name, i, ccparams_lte.frame_type);
-            }
+              if (strcmp(ccparams_lte.frame_type, "FDD") == 0) {
+                RRC_CONFIGURATION_REQ (msg_p).frame_type[j] = FDD;
+              } else  if (strcmp(ccparams_lte.frame_type, "TDD") == 0) {
+                RRC_CONFIGURATION_REQ (msg_p).frame_type[j] = TDD;
+              } else {
+                AssertFatal (0,
+                             "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for frame_type choice: FDD or TDD !\n",
+                             RC.config_file_name, i, ccparams_lte.frame_type);
+              }
 
-            if (config_check_band_frequencies(j,
-                                              RRC_CONFIGURATION_REQ (msg_p).eutra_band[j],
-                                              RRC_CONFIGURATION_REQ (msg_p).downlink_frequency[j],
-                                              RRC_CONFIGURATION_REQ (msg_p).uplink_frequency_offset[j],
-                                              RRC_CONFIGURATION_REQ (msg_p).frame_type[j])) {
-              AssertFatal(0, "error calling enb_check_band_frequencies\n");
-            }
+              if (config_check_band_frequencies(j,
+                                                RRC_CONFIGURATION_REQ (msg_p).eutra_band[j],
+                                                RRC_CONFIGURATION_REQ (msg_p).downlink_frequency[j],
+                                                RRC_CONFIGURATION_REQ (msg_p).uplink_frequency_offset[j],
+                                                RRC_CONFIGURATION_REQ (msg_p).frame_type[j])) {
+                AssertFatal(0, "error calling enb_check_band_frequencies\n");
+              }
 
-            if ((ccparams_lte.nb_antenna_ports <1) || (ccparams_lte.nb_antenna_ports > 2))
-              AssertFatal (0,
-                           "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for nb_antenna_ports choice: 1..2 !\n",
-                           RC.config_file_name, i, ccparams_lte.nb_antenna_ports);
+              if ((ccparams_lte.nb_antenna_ports <1) || (ccparams_lte.nb_antenna_ports > 2))
+                AssertFatal (0,
+                             "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for nb_antenna_ports choice: 1..2 !\n",
+                             RC.config_file_name, i, ccparams_lte.nb_antenna_ports);
 
-            RRC_CONFIGURATION_REQ (msg_p).nb_antenna_ports[j] = ccparams_lte.nb_antenna_ports;
-            // Radio Resource Configuration (SIB2)
-            RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].prach_root =  ccparams_lte.prach_root;
+              RRC_CONFIGURATION_REQ (msg_p).nb_antenna_ports[j] = ccparams_lte.nb_antenna_ports;
+            }
 
-            if ((ccparams_lte.prach_root <0) || (ccparams_lte.prach_root > 1023))
-              AssertFatal (0,
-                           "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for prach_root choice: 0..1023 !\n",
-                           RC.config_file_name, i, ccparams_lte.prach_root);
+            if (!NODE_IS_DU(rrc->node_type)) { //this is CU or eNB, SIB2-20 in CU
+              // Radio Resource Configuration (SIB2)
+              RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].prach_root =  ccparams_lte.prach_root;
 
-            RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].prach_config_index = ccparams_lte.prach_config_index;
+              if ((ccparams_lte.prach_root <0) || (ccparams_lte.prach_root > 1023))
+                AssertFatal (0,
+                             "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for prach_root choice: 0..1023 !\n",
+                             RC.config_file_name, i, ccparams_lte.prach_root);
 
-            if ((ccparams_lte.prach_config_index <0) || (ccparams_lte.prach_config_index > 63))
-              AssertFatal (0,
-                           "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for prach_config_index choice: 0..1023 !\n",
-                           RC.config_file_name, i, ccparams_lte.prach_config_index);
+              RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].prach_config_index = ccparams_lte.prach_config_index;
 
-            if (!ccparams_lte.prach_high_speed)
-              AssertFatal (0,
-                           "Failed to parse eNB configuration file %s, enb %d define %s: ENABLE,DISABLE!\n",
-                           RC.config_file_name, i, ENB_CONFIG_STRING_PRACH_HIGH_SPEED);
-            else if (strcmp(ccparams_lte.prach_high_speed, "ENABLE") == 0) {
-              RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].prach_high_speed = TRUE;
-            } else if (strcmp(ccparams_lte.prach_high_speed, "DISABLE") == 0) {
-              RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].prach_high_speed = FALSE;
-            } else
-              AssertFatal (0,
-                           "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for prach_config choice: ENABLE,DISABLE !\n",
-                           RC.config_file_name, i, ccparams_lte.prach_high_speed);
+              if ((ccparams_lte.prach_config_index <0) || (ccparams_lte.prach_config_index > 63))
+                AssertFatal (0,
+                             "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for prach_config_index choice: 0..1023 !\n",
+                             RC.config_file_name, i, ccparams_lte.prach_config_index);
 
-            RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].prach_zero_correlation = ccparams_lte.prach_zero_correlation;
+              if (!ccparams_lte.prach_high_speed)
+                AssertFatal (0,
+                             "Failed to parse eNB configuration file %s, enb %d define %s: ENABLE,DISABLE!\n",
+                             RC.config_file_name, i, ENB_CONFIG_STRING_PRACH_HIGH_SPEED);
+              else if (strcmp(ccparams_lte.prach_high_speed, "ENABLE") == 0) {
+                RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].prach_high_speed = TRUE;
+              } else if (strcmp(ccparams_lte.prach_high_speed, "DISABLE") == 0) {
+                RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].prach_high_speed = FALSE;
+              } else
+                AssertFatal (0,
+                             "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for prach_config choice: ENABLE,DISABLE !\n",
+                             RC.config_file_name, i, ccparams_lte.prach_high_speed);
 
-            if ((ccparams_lte.prach_zero_correlation <0) ||
-                (ccparams_lte.prach_zero_correlation > 15))
-              AssertFatal (0,
-                           "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for prach_zero_correlation choice: 0..15!\n",
-                           RC.config_file_name, i, ccparams_lte.prach_zero_correlation);
+              RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].prach_zero_correlation = ccparams_lte.prach_zero_correlation;
 
-            RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].prach_freq_offset = ccparams_lte.prach_freq_offset;
+              if ((ccparams_lte.prach_zero_correlation <0) ||
+                  (ccparams_lte.prach_zero_correlation > 15))
+                AssertFatal (0,
+                             "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for prach_zero_correlation choice: 0..15!\n",
+                             RC.config_file_name, i, ccparams_lte.prach_zero_correlation);
 
-            if ((ccparams_lte.prach_freq_offset <0) ||
-                (ccparams_lte.prach_freq_offset > 94))
-              AssertFatal (0,
-                           "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for prach_freq_offset choice: 0..94!\n",
-                           RC.config_file_name, i, ccparams_lte.prach_freq_offset);
+              RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].prach_freq_offset = ccparams_lte.prach_freq_offset;
 
-            RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pucch_delta_shift = ccparams_lte.pucch_delta_shift-1;
+              if ((ccparams_lte.prach_freq_offset <0) ||
+                  (ccparams_lte.prach_freq_offset > 94))
+                AssertFatal (0,
+                             "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for prach_freq_offset choice: 0..94!\n",
+                             RC.config_file_name, i, ccparams_lte.prach_freq_offset);
 
-            if ((ccparams_lte.pucch_delta_shift <1) ||
-                (ccparams_lte.pucch_delta_shift > 3))
-              AssertFatal (0,
-                           "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for pucch_delta_shift choice: 1..3!\n",
-                           RC.config_file_name, i, ccparams_lte.pucch_delta_shift);
+              RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pucch_delta_shift = ccparams_lte.pucch_delta_shift-1;
 
-            RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pucch_nRB_CQI = ccparams_lte.pucch_nRB_CQI;
+              if ((ccparams_lte.pucch_delta_shift <1) ||
+                  (ccparams_lte.pucch_delta_shift > 3))
+                AssertFatal (0,
+                             "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for pucch_delta_shift choice: 1..3!\n",
+                             RC.config_file_name, i, ccparams_lte.pucch_delta_shift);
 
-            if ((ccparams_lte.pucch_nRB_CQI <0) ||
-                (ccparams_lte.pucch_nRB_CQI > 98))
-              AssertFatal (0,
-                           "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for pucch_nRB_CQI choice: 0..98!\n",
-                           RC.config_file_name, i, ccparams_lte.pucch_nRB_CQI);
+              RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pucch_nRB_CQI = ccparams_lte.pucch_nRB_CQI;
 
-            RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pucch_nCS_AN = ccparams_lte.pucch_nCS_AN;
+              if ((ccparams_lte.pucch_nRB_CQI <0) ||
+                  (ccparams_lte.pucch_nRB_CQI > 98))
+                AssertFatal (0,
+                             "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for pucch_nRB_CQI choice: 0..98!\n",
+                             RC.config_file_name, i, ccparams_lte.pucch_nRB_CQI);
 
-            if ((ccparams_lte.pucch_nCS_AN <0) ||
-                (ccparams_lte.pucch_nCS_AN > 7))
-              AssertFatal (0,
-                           "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for pucch_nCS_AN choice: 0..7!\n",
-                           RC.config_file_name, i, ccparams_lte.pucch_nCS_AN);
+              RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pucch_nCS_AN = ccparams_lte.pucch_nCS_AN;
 
-            //#if (LTE_RRC_VERSION < MAKE_VERSION(10, 0, 0))
-            RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pucch_n1_AN = ccparams_lte.pucch_n1_AN;
+              if ((ccparams_lte.pucch_nCS_AN <0) ||
+                  (ccparams_lte.pucch_nCS_AN > 7))
+                AssertFatal (0,
+                             "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for pucch_nCS_AN choice: 0..7!\n",
+                             RC.config_file_name, i, ccparams_lte.pucch_nCS_AN);
 
-            if ((ccparams_lte.pucch_n1_AN <0) ||
-                (ccparams_lte.pucch_n1_AN > 2047))
-              AssertFatal (0,
-                           "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for pucch_n1_AN choice: 0..2047!\n",
-                           RC.config_file_name, i, ccparams_lte.pucch_n1_AN);
+              //#if (LTE_RRC_VERSION < MAKE_VERSION(10, 0, 0))
+              RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pucch_n1_AN = ccparams_lte.pucch_n1_AN;
 
-            //#endif
-            RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pdsch_referenceSignalPower = ccparams_lte.pdsch_referenceSignalPower;
+              if ((ccparams_lte.pucch_n1_AN <0) ||
+                  (ccparams_lte.pucch_n1_AN > 2047))
+                AssertFatal (0,
+                             "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for pucch_n1_AN choice: 0..2047!\n",
+                             RC.config_file_name, i, ccparams_lte.pucch_n1_AN);
 
-            if ((ccparams_lte.pdsch_referenceSignalPower <-60) ||
-                (ccparams_lte.pdsch_referenceSignalPower > 50))
-              AssertFatal (0,
-                           "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for pdsch_referenceSignalPower choice:-60..50!\n",
-                           RC.config_file_name, i, ccparams_lte.pdsch_referenceSignalPower);
+              //#endif
+              RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pdsch_referenceSignalPower = ccparams_lte.pdsch_referenceSignalPower;
 
-            RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pdsch_p_b = ccparams_lte.pdsch_p_b;
+              if ((ccparams_lte.pdsch_referenceSignalPower <-60) ||
+                  (ccparams_lte.pdsch_referenceSignalPower > 50))
+                AssertFatal (0,
+                             "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for pdsch_referenceSignalPower choice:-60..50!\n",
+                             RC.config_file_name, i, ccparams_lte.pdsch_referenceSignalPower);
 
-            if ((ccparams_lte.pdsch_p_b <0) ||
-                (ccparams_lte.pdsch_p_b > 3))
-              AssertFatal (0,
-                           "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for pdsch_p_b choice: 0..3!\n",
-                           RC.config_file_name, i, ccparams_lte.pdsch_p_b);
+              RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pdsch_p_b = ccparams_lte.pdsch_p_b;
 
-            RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_n_SB = ccparams_lte.pusch_n_SB;
+              if ((ccparams_lte.pdsch_p_b <0) ||
+                  (ccparams_lte.pdsch_p_b > 3))
+                AssertFatal (0,
+                             "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for pdsch_p_b choice: 0..3!\n",
+                             RC.config_file_name, i, ccparams_lte.pdsch_p_b);
 
-            if ((ccparams_lte.pusch_n_SB <1) ||
-                (ccparams_lte.pusch_n_SB > 4))
-              AssertFatal (0,
-                           "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for pusch_n_SB choice: 1..4!\n",
-                           RC.config_file_name, i, ccparams_lte.pusch_n_SB);
+              RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_n_SB = ccparams_lte.pusch_n_SB;
 
-            if (!ccparams_lte.pusch_hoppingMode)
-              AssertFatal (0,
-                           "Failed to parse eNB configuration file %s, enb %d define %s: interSubframe,intraAndInterSubframe!\n",
-                           RC.config_file_name, i, ENB_CONFIG_STRING_PUSCH_HOPPINGMODE);
-            else if (strcmp(ccparams_lte.pusch_hoppingMode,"interSubFrame")==0) {
-              RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_hoppingMode = LTE_PUSCH_ConfigCommon__pusch_ConfigBasic__hoppingMode_interSubFrame;
+              if ((ccparams_lte.pusch_n_SB <1) ||
+                  (ccparams_lte.pusch_n_SB > 4))
+                AssertFatal (0,
+                             "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for pusch_n_SB choice: 1..4!\n",
+                             RC.config_file_name, i, ccparams_lte.pusch_n_SB);
+
+              if (!ccparams_lte.pusch_hoppingMode)
+                AssertFatal (0,
+                             "Failed to parse eNB configuration file %s, enb %d define %s: interSubframe,intraAndInterSubframe!\n",
+                             RC.config_file_name, i, ENB_CONFIG_STRING_PUSCH_HOPPINGMODE);
+              else if (strcmp(ccparams_lte.pusch_hoppingMode,"interSubFrame")==0) {
+                RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_hoppingMode = LTE_PUSCH_ConfigCommon__pusch_ConfigBasic__hoppingMode_interSubFrame;
             } else if (strcmp(ccparams_lte.pusch_hoppingMode,"intraAndInterSubFrame")==0) {
-              RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_hoppingMode = LTE_PUSCH_ConfigCommon__pusch_ConfigBasic__hoppingMode_intraAndInterSubFrame;
-            } else
-              AssertFatal (0,
-                           "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for pusch_hoppingMode choice: interSubframe,intraAndInterSubframe!\n",
-                           RC.config_file_name, i, ccparams_lte.pusch_hoppingMode);
+                RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_hoppingMode = LTE_PUSCH_ConfigCommon__pusch_ConfigBasic__hoppingMode_intraAndInterSubFrame;
+              } else
+                AssertFatal (0,
+                             "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for pusch_hoppingMode choice: interSubframe,intraAndInterSubframe!\n",
+                             RC.config_file_name, i, ccparams_lte.pusch_hoppingMode);
 
-            RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_hoppingOffset = ccparams_lte.pusch_hoppingOffset;
+              RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_hoppingOffset = ccparams_lte.pusch_hoppingOffset;
 
-            if ((ccparams_lte.pusch_hoppingOffset<0) ||
-                (ccparams_lte.pusch_hoppingOffset>98))
-              AssertFatal (0,
-                           "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for pusch_hoppingOffset choice: 0..98!\n",
-                           RC.config_file_name, i, ccparams_lte.pusch_hoppingMode);
+              if ((ccparams_lte.pusch_hoppingOffset<0) ||
+                  (ccparams_lte.pusch_hoppingOffset>98))
+                AssertFatal (0,
+                             "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for pusch_hoppingOffset choice: 0..98!\n",
+                             RC.config_file_name, i, ccparams_lte.pusch_hoppingMode);
 
-            if (!ccparams_lte.pusch_enable64QAM)
-              AssertFatal (0,
-                           "Failed to parse eNB configuration file %s, enb %d define %s: ENABLE,DISABLE!\n",
-                           RC.config_file_name, i, ENB_CONFIG_STRING_PUSCH_ENABLE64QAM);
-            else if (strcmp(ccparams_lte.pusch_enable64QAM, "ENABLE") == 0) {
-              RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_enable64QAM = TRUE;
+              if (!ccparams_lte.pusch_enable64QAM)
+                AssertFatal (0,
+                             "Failed to parse eNB configuration file %s, enb %d define %s: ENABLE,DISABLE!\n",
+                             RC.config_file_name, i, ENB_CONFIG_STRING_PUSCH_ENABLE64QAM);
+              else if (strcmp(ccparams_lte.pusch_enable64QAM, "ENABLE") == 0) {
+                RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_enable64QAM = TRUE;
             } else if (strcmp(ccparams_lte.pusch_enable64QAM, "DISABLE") == 0) {
-              RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_enable64QAM = FALSE;
+                RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_enable64QAM = FALSE;
             } else
-              AssertFatal (0,
-                           "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for pusch_enable64QAM choice: ENABLE,DISABLE!\n",
-                           RC.config_file_name, i, ccparams_lte.pusch_enable64QAM);
+                AssertFatal (0,
+                             "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for pusch_enable64QAM choice: ENABLE,DISABLE!\n",
+                             RC.config_file_name, i, ccparams_lte.pusch_enable64QAM);
 
-            if (!ccparams_lte.pusch_groupHoppingEnabled)
-              AssertFatal (0,
-                           "Failed to parse eNB configuration file %s, enb %d define %s: ENABLE,DISABLE!\n",
-                           RC.config_file_name, i, ENB_CONFIG_STRING_PUSCH_GROUP_HOPPING_EN);
-            else if (strcmp(ccparams_lte.pusch_groupHoppingEnabled, "ENABLE") == 0) {
-              RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_groupHoppingEnabled = TRUE;
+              if (!ccparams_lte.pusch_groupHoppingEnabled)
+                AssertFatal (0,
+                             "Failed to parse eNB configuration file %s, enb %d define %s: ENABLE,DISABLE!\n",
+                             RC.config_file_name, i, ENB_CONFIG_STRING_PUSCH_GROUP_HOPPING_EN);
+              else if (strcmp(ccparams_lte.pusch_groupHoppingEnabled, "ENABLE") == 0) {
+                RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_groupHoppingEnabled = TRUE;
             } else if (strcmp(ccparams_lte.pusch_groupHoppingEnabled, "DISABLE") == 0) {
-              RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_groupHoppingEnabled= FALSE;
+                RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_groupHoppingEnabled= FALSE;
             } else
-              AssertFatal (0,
-                           "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for pusch_groupHoppingEnabled choice: ENABLE,DISABLE!\n",
-                           RC.config_file_name, i, ccparams_lte.pusch_groupHoppingEnabled);
+                AssertFatal (0,
+                             "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for pusch_groupHoppingEnabled choice: ENABLE,DISABLE!\n",
+                             RC.config_file_name, i, ccparams_lte.pusch_groupHoppingEnabled);
 
-            RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_groupAssignment = ccparams_lte.pusch_groupAssignment;
+              RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_groupAssignment = ccparams_lte.pusch_groupAssignment;
 
-            if ((ccparams_lte.pusch_groupAssignment<0)||
-                (ccparams_lte.pusch_groupAssignment>29))
-              AssertFatal (0,
-                           "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for pusch_groupAssignment choice: 0..29!\n",
-                           RC.config_file_name, i, ccparams_lte.pusch_groupAssignment);
+              if ((ccparams_lte.pusch_groupAssignment<0)||
+                  (ccparams_lte.pusch_groupAssignment>29))
+                AssertFatal (0,
+                             "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for pusch_groupAssignment choice: 0..29!\n",
+                             RC.config_file_name, i, ccparams_lte.pusch_groupAssignment);
 
-            if (!ccparams_lte.pusch_sequenceHoppingEnabled)
-              AssertFatal (0,
-                           "Failed to parse eNB configuration file %s, enb %d define %s: ENABLE,DISABLE!\n",
-                           RC.config_file_name, i, ENB_CONFIG_STRING_PUSCH_SEQUENCE_HOPPING_EN);
-            else if (strcmp(ccparams_lte.pusch_sequenceHoppingEnabled, "ENABLE") == 0) {
-              RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_sequenceHoppingEnabled = TRUE;
+              if (!ccparams_lte.pusch_sequenceHoppingEnabled)
+                AssertFatal (0,
+                             "Failed to parse eNB configuration file %s, enb %d define %s: ENABLE,DISABLE!\n",
+                             RC.config_file_name, i, ENB_CONFIG_STRING_PUSCH_SEQUENCE_HOPPING_EN);
+              else if (strcmp(ccparams_lte.pusch_sequenceHoppingEnabled, "ENABLE") == 0) {
+                RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_sequenceHoppingEnabled = TRUE;
             } else if (strcmp(ccparams_lte.pusch_sequenceHoppingEnabled, "DISABLE") == 0) {
-              RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_sequenceHoppingEnabled = FALSE;
-            } else
-              AssertFatal (0,
-                           "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for pusch_sequenceHoppingEnabled choice: ENABLE,DISABLE!\n",
-                           RC.config_file_name, i, ccparams_lte.pusch_sequenceHoppingEnabled);
+                RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_sequenceHoppingEnabled = FALSE;
+              } else
+                AssertFatal (0,
+                             "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for pusch_sequenceHoppingEnabled choice: ENABLE,DISABLE!\n",
+                             RC.config_file_name, i, ccparams_lte.pusch_sequenceHoppingEnabled);
 
-            RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_nDMRS1= ccparams_lte.pusch_nDMRS1;  //cyclic_shift in RRC!
+              RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_nDMRS1= ccparams_lte.pusch_nDMRS1;  //cyclic_shift in RRC!
 
-            if ((ccparams_lte.pusch_nDMRS1 <0) ||
-                (ccparams_lte.pusch_nDMRS1>7))
-              AssertFatal (0,
-                           "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for pusch_nDMRS1 choice: 0..7!\n",
-                           RC.config_file_name, i, ccparams_lte.pusch_nDMRS1);
+              if ((ccparams_lte.pusch_nDMRS1 <0) ||
+                  (ccparams_lte.pusch_nDMRS1>7))
+                AssertFatal (0,
+                             "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for pusch_nDMRS1 choice: 0..7!\n",
+                             RC.config_file_name, i, ccparams_lte.pusch_nDMRS1);
 
-            if (strcmp(ccparams_lte.phich_duration,"NORMAL")==0) {
-              RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].phich_duration= LTE_PHICH_Config__phich_Duration_normal;
-            } else if (strcmp(ccparams_lte.phich_duration,"EXTENDED")==0) {
-              RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].phich_duration= LTE_PHICH_Config__phich_Duration_extended;
-            } else
-              AssertFatal (0,
-                           "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for phich_duration choice: NORMAL,EXTENDED!\n",
-                           RC.config_file_name, i, ccparams_lte.phich_duration);
+              if (strcmp(ccparams_lte.phich_duration,"NORMAL")==0) {
+                RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].phich_duration= LTE_PHICH_Config__phich_Duration_normal;
+              } else if (strcmp(ccparams_lte.phich_duration,"EXTENDED")==0) {
+                RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].phich_duration= LTE_PHICH_Config__phich_Duration_extended;
+              } else
+                AssertFatal (0,
+                             "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for phich_duration choice: NORMAL,EXTENDED!\n",
+                             RC.config_file_name, i, ccparams_lte.phich_duration);
 
-            if (strcmp(ccparams_lte.phich_resource,"ONESIXTH")==0) {
-              RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].phich_resource= LTE_PHICH_Config__phich_Resource_oneSixth ;
+              if (strcmp(ccparams_lte.phich_resource,"ONESIXTH")==0) {
+                RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].phich_resource= LTE_PHICH_Config__phich_Resource_oneSixth ;
             } else if (strcmp(ccparams_lte.phich_resource,"HALF")==0) {
-              RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].phich_resource= LTE_PHICH_Config__phich_Resource_half;
+                RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].phich_resource= LTE_PHICH_Config__phich_Resource_half;
             } else if (strcmp(ccparams_lte.phich_resource,"ONE")==0) {
-              RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].phich_resource= LTE_PHICH_Config__phich_Resource_one;
+                RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].phich_resource= LTE_PHICH_Config__phich_Resource_one;
             } else if (strcmp(ccparams_lte.phich_resource,"TWO")==0) {
-              RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].phich_resource= LTE_PHICH_Config__phich_Resource_two;
+                RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].phich_resource= LTE_PHICH_Config__phich_Resource_two;
             } else
-              AssertFatal (0,
-                           "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for phich_resource choice: ONESIXTH,HALF,ONE,TWO!\n",
-                           RC.config_file_name, i, ccparams_lte.phich_resource);
+                AssertFatal (0,
+                             "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for phich_resource choice: ONESIXTH,HALF,ONE,TWO!\n",
+                             RC.config_file_name, i, ccparams_lte.phich_resource);
 
-            printf("phich.resource %ld (%s), phich.duration %ld (%s)\n",
-                   RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].phich_resource,ccparams_lte.phich_resource,
-                   RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].phich_duration,ccparams_lte.phich_duration);
+              printf("phich.resource %ld (%s), phich.duration %ld (%s)\n",
+                     RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].phich_resource,ccparams_lte.phich_resource,
+                     RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].phich_duration,ccparams_lte.phich_duration);
 
-            if (strcmp(ccparams_lte.srs_enable, "ENABLE") == 0) {
-              RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].srs_enable= TRUE;
+              if (strcmp(ccparams_lte.srs_enable, "ENABLE") == 0) {
+                RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].srs_enable= TRUE;
             } else if (strcmp(ccparams_lte.srs_enable, "DISABLE") == 0) {
-              RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].srs_enable= FALSE;
+                RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].srs_enable= FALSE;
             } else
-              AssertFatal (0,
-                           "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for srs_BandwidthConfig choice: ENABLE,DISABLE !\n",
-                           RC.config_file_name, i, ccparams_lte.srs_enable);
+                AssertFatal (0,
+                             "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for srs_BandwidthConfig choice: ENABLE,DISABLE !\n",
+                             RC.config_file_name, i, ccparams_lte.srs_enable);
 
-            if (RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].srs_enable== TRUE) {
-              RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].srs_BandwidthConfig= ccparams_lte.srs_BandwidthConfig;
+              if (RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].srs_enable== TRUE) {
+                RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].srs_BandwidthConfig= ccparams_lte.srs_BandwidthConfig;
 
-              if ((ccparams_lte.srs_BandwidthConfig < 0) ||
-                  (ccparams_lte.srs_BandwidthConfig >7))
-                AssertFatal (0, "Failed to parse eNB configuration file %s, enb %d unknown value %d for srs_BandwidthConfig choice: 0...7\n",
-                             RC.config_file_name, i, ccparams_lte.srs_BandwidthConfig);
+                if ((ccparams_lte.srs_BandwidthConfig < 0) ||
+                    (ccparams_lte.srs_BandwidthConfig >7))
+                  AssertFatal (0, "Failed to parse eNB configuration file %s, enb %d unknown value %d for srs_BandwidthConfig choice: 0...7\n",
+                               RC.config_file_name, i, ccparams_lte.srs_BandwidthConfig);
 
-              RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].srs_SubframeConfig= ccparams_lte.srs_SubframeConfig;
+                RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].srs_SubframeConfig= ccparams_lte.srs_SubframeConfig;
 
-              if ((ccparams_lte.srs_SubframeConfig<0) ||
-                  (ccparams_lte.srs_SubframeConfig>15))
-                AssertFatal (0,
-                             "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for srs_SubframeConfig choice: 0..15 !\n",
-                             RC.config_file_name, i, ccparams_lte.srs_SubframeConfig);
+                if ((ccparams_lte.srs_SubframeConfig<0) ||
+                    (ccparams_lte.srs_SubframeConfig>15))
+                  AssertFatal (0,
+                               "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for srs_SubframeConfig choice: 0..15 !\n",
+                               RC.config_file_name, i, ccparams_lte.srs_SubframeConfig);
 
-              if (strcmp(ccparams_lte.srs_ackNackST, "ENABLE") == 0) {
-                RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].srs_ackNackST= TRUE;
+                if (strcmp(ccparams_lte.srs_ackNackST, "ENABLE") == 0) {
+                  RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].srs_ackNackST= TRUE;
               } else if (strcmp(ccparams_lte.srs_ackNackST, "DISABLE") == 0) {
-                RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].srs_ackNackST= FALSE;
-              } else
-                AssertFatal (0,
-                             "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for srs_BandwidthConfig choice: ENABLE,DISABLE !\n",
-                             RC.config_file_name, i, ccparams_lte.srs_ackNackST);
+                  RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].srs_ackNackST= FALSE;
+                } else
+                  AssertFatal (0,
+                               "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for srs_BandwidthConfig choice: ENABLE,DISABLE !\n",
+                               RC.config_file_name, i, ccparams_lte.srs_ackNackST);
 
-              if (strcmp(ccparams_lte.srs_MaxUpPts, "ENABLE") == 0) {
-                RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].srs_MaxUpPts= TRUE;
+                if (strcmp(ccparams_lte.srs_MaxUpPts, "ENABLE") == 0) {
+                  RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].srs_MaxUpPts= TRUE;
               } else if (strcmp(ccparams_lte.srs_MaxUpPts, "DISABLE") == 0) {
-                RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].srs_MaxUpPts= FALSE;
+                  RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].srs_MaxUpPts= FALSE;
               } else
-                AssertFatal (0,
-                             "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for srs_MaxUpPts choice: ENABLE,DISABLE !\n",
-                             RC.config_file_name, i, ccparams_lte.srs_MaxUpPts);
-            }
+                  AssertFatal (0,
+                               "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for srs_MaxUpPts choice: ENABLE,DISABLE !\n",
+                               RC.config_file_name, i, ccparams_lte.srs_MaxUpPts);
+              }
 
-            RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_p0_Nominal= ccparams_lte.pusch_p0_Nominal;
+              RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_p0_Nominal= ccparams_lte.pusch_p0_Nominal;
 
-            if ((ccparams_lte.pusch_p0_Nominal<-126) ||
-                (ccparams_lte.pusch_p0_Nominal>24))
-              AssertFatal (0,
-                           "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for pusch_p0_Nominal choice: -126..24 !\n",
-                           RC.config_file_name, i, ccparams_lte.pusch_p0_Nominal);
+              if ((ccparams_lte.pusch_p0_Nominal<-126) ||
+                  (ccparams_lte.pusch_p0_Nominal>24))
+                AssertFatal (0,
+                             "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for pusch_p0_Nominal choice: -126..24 !\n",
+                             RC.config_file_name, i, ccparams_lte.pusch_p0_Nominal);
 
 #if (LTE_RRC_VERSION <= MAKE_VERSION(12, 0, 0))
 
-            if (strcmp(ccparams_lte.pusch_alpha,"AL0")==0) {
-              RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_alpha= LTE_UplinkPowerControlCommon__alpha_al0;
+              if (strcmp(ccparams_lte.pusch_alpha,"AL0")==0) {
+                RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_alpha= LTE_UplinkPowerControlCommon__alpha_al0;
             } else if (strcmp(ccparams_lte.pusch_alpha,"AL04")==0) {
-              RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_alpha= LTE_UplinkPowerControlCommon__alpha_al04;
+                RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_alpha= LTE_UplinkPowerControlCommon__alpha_al04;
             } else if (strcmp(ccparams_lte.pusch_alpha,"AL05")==0) {
-              RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_alpha= LTE_UplinkPowerControlCommon__alpha_al05;
+                RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_alpha= LTE_UplinkPowerControlCommon__alpha_al05;
             } else if (strcmp(ccparams_lte.pusch_alpha,"AL06")==0) {
-              RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_alpha= LTE_UplinkPowerControlCommon__alpha_al06;
+                RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_alpha= LTE_UplinkPowerControlCommon__alpha_al06;
             } else if (strcmp(ccparams_lte.pusch_alpha,"AL07")==0) {
-              RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_alpha= LTE_UplinkPowerControlCommon__alpha_al07;
+                RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_alpha= LTE_UplinkPowerControlCommon__alpha_al07;
             } else if (strcmp(ccparams_lte.pusch_alpha,"AL08")==0) {
-              RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_alpha= LTE_UplinkPowerControlCommon__alpha_al08;
+                RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_alpha= LTE_UplinkPowerControlCommon__alpha_al08;
             } else if (strcmp(ccparams_lte.pusch_alpha,"AL09")==0) {
-              RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_alpha= LTE_UplinkPowerControlCommon__alpha_al09;
+                RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_alpha= LTE_UplinkPowerControlCommon__alpha_al09;
             } else if (strcmp(ccparams_lte.pusch_alpha,"AL1")==0) {
-              RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_alpha= LTE_UplinkPowerControlCommon__alpha_al1;
-            }
+                RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_alpha= LTE_UplinkPowerControlCommon__alpha_al1;
+              }
 
 #endif
 #if (LTE_RRC_VERSION >= MAKE_VERSION(12, 0, 0))
 
-            if (strcmp(ccparams_lte.pusch_alpha,"AL0")==0) {
-              RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_alpha= LTE_Alpha_r12_al0;
+              if (strcmp(ccparams_lte.pusch_alpha,"AL0")==0) {
+                RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_alpha= LTE_Alpha_r12_al0;
             } else if (strcmp(ccparams_lte.pusch_alpha,"AL04")==0) {
-              RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_alpha= LTE_Alpha_r12_al04;
+                RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_alpha= LTE_Alpha_r12_al04;
             } else if (strcmp(ccparams_lte.pusch_alpha,"AL05")==0) {
-              RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_alpha= LTE_Alpha_r12_al05;
+                RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_alpha= LTE_Alpha_r12_al05;
             } else if (strcmp(ccparams_lte.pusch_alpha,"AL06")==0) {
-              RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_alpha= LTE_Alpha_r12_al06;
+                RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_alpha= LTE_Alpha_r12_al06;
             } else if (strcmp(ccparams_lte.pusch_alpha,"AL07")==0) {
-              RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_alpha= LTE_Alpha_r12_al07;
+                RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_alpha= LTE_Alpha_r12_al07;
             } else if (strcmp(ccparams_lte.pusch_alpha,"AL08")==0) {
-              RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_alpha= LTE_Alpha_r12_al08;
+                RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_alpha= LTE_Alpha_r12_al08;
             } else if (strcmp(ccparams_lte.pusch_alpha,"AL09")==0) {
-              RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_alpha= LTE_Alpha_r12_al09;
+                RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_alpha= LTE_Alpha_r12_al09;
             } else if (strcmp(ccparams_lte.pusch_alpha,"AL1")==0) {
-              RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_alpha= LTE_Alpha_r12_al1;
-            }
+                RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_alpha= LTE_Alpha_r12_al1;
+              }
 
 #endif
-            else
-              AssertFatal (0,
-                           "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for pucch_Alpha choice: AL0,AL04,AL05,AL06,AL07,AL08,AL09,AL1!\n",
-                           RC.config_file_name, i, ccparams_lte.pusch_alpha);
+              else
+                AssertFatal (0,
+                             "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for pucch_Alpha choice: AL0,AL04,AL05,AL06,AL07,AL08,AL09,AL1!\n",
+                             RC.config_file_name, i, ccparams_lte.pusch_alpha);
 
-            RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pucch_p0_Nominal= ccparams_lte.pucch_p0_Nominal;
+              RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pucch_p0_Nominal= ccparams_lte.pucch_p0_Nominal;
 
-            if ((ccparams_lte.pucch_p0_Nominal<-127) ||
-                (ccparams_lte.pucch_p0_Nominal>-96))
-              AssertFatal (0,
-                           "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for pucch_p0_Nominal choice: -127..-96 !\n",
-                           RC.config_file_name, i, ccparams_lte.pucch_p0_Nominal);
+              if ((ccparams_lte.pucch_p0_Nominal<-127) ||
+                  (ccparams_lte.pucch_p0_Nominal>-96))
+                AssertFatal (0,
+                             "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for pucch_p0_Nominal choice: -127..-96 !\n",
+                             RC.config_file_name, i, ccparams_lte.pucch_p0_Nominal);
 
-            RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].msg3_delta_Preamble= ccparams_lte.msg3_delta_Preamble;
+              RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].msg3_delta_Preamble= ccparams_lte.msg3_delta_Preamble;
 
-            if ((ccparams_lte.msg3_delta_Preamble<-1) ||
-                (ccparams_lte.msg3_delta_Preamble>6))
-              AssertFatal (0,
-                           "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for msg3_delta_Preamble choice: -1..6 !\n",
-                           RC.config_file_name, i, ccparams_lte.msg3_delta_Preamble);
+              if ((ccparams_lte.msg3_delta_Preamble<-1) ||
+                  (ccparams_lte.msg3_delta_Preamble>6))
+                AssertFatal (0,
+                             "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for msg3_delta_Preamble choice: -1..6 !\n",
+                             RC.config_file_name, i, ccparams_lte.msg3_delta_Preamble);
 
-            if (strcmp(ccparams_lte.pucch_deltaF_Format1,"deltaF_2")==0) {
-              RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pucch_deltaF_Format1= LTE_DeltaFList_PUCCH__deltaF_PUCCH_Format1_deltaF_2;
+              if (strcmp(ccparams_lte.pucch_deltaF_Format1,"deltaF_2")==0) {
+                RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pucch_deltaF_Format1= LTE_DeltaFList_PUCCH__deltaF_PUCCH_Format1_deltaF_2;
             } else if (strcmp(ccparams_lte.pucch_deltaF_Format1,"deltaF0")==0) {
-              RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pucch_deltaF_Format1= LTE_DeltaFList_PUCCH__deltaF_PUCCH_Format1_deltaF0;
+                RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pucch_deltaF_Format1= LTE_DeltaFList_PUCCH__deltaF_PUCCH_Format1_deltaF0;
             } else if (strcmp(ccparams_lte.pucch_deltaF_Format1,"deltaF2")==0) {
-              RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pucch_deltaF_Format1= LTE_DeltaFList_PUCCH__deltaF_PUCCH_Format1_deltaF2;
+                RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pucch_deltaF_Format1= LTE_DeltaFList_PUCCH__deltaF_PUCCH_Format1_deltaF2;
             } else
-              AssertFatal (0,
-                           "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for pucch_deltaF_Format1 choice: deltaF_2,dltaF0,deltaF2!\n",
-                           RC.config_file_name, i, ccparams_lte.pucch_deltaF_Format1);
+                AssertFatal (0,
+                             "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for pucch_deltaF_Format1 choice: deltaF_2,dltaF0,deltaF2!\n",
+                             RC.config_file_name, i, ccparams_lte.pucch_deltaF_Format1);
 
-            if (strcmp(ccparams_lte.pucch_deltaF_Format1b,"deltaF1")==0) {
-              RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pucch_deltaF_Format1b= LTE_DeltaFList_PUCCH__deltaF_PUCCH_Format1b_deltaF1;
+              if (strcmp(ccparams_lte.pucch_deltaF_Format1b,"deltaF1")==0) {
+                RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pucch_deltaF_Format1b= LTE_DeltaFList_PUCCH__deltaF_PUCCH_Format1b_deltaF1;
             } else if (strcmp(ccparams_lte.pucch_deltaF_Format1b,"deltaF3")==0) {
-              RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pucch_deltaF_Format1b= LTE_DeltaFList_PUCCH__deltaF_PUCCH_Format1b_deltaF3;
+                RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pucch_deltaF_Format1b= LTE_DeltaFList_PUCCH__deltaF_PUCCH_Format1b_deltaF3;
             } else if (strcmp(ccparams_lte.pucch_deltaF_Format1b,"deltaF5")==0) {
-              RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pucch_deltaF_Format1b= LTE_DeltaFList_PUCCH__deltaF_PUCCH_Format1b_deltaF5;
+                RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pucch_deltaF_Format1b= LTE_DeltaFList_PUCCH__deltaF_PUCCH_Format1b_deltaF5;
             } else
-              AssertFatal (0,
-                           "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for pucch_deltaF_Format1b choice: deltaF1,dltaF3,deltaF5!\n",
-                           RC.config_file_name, i, ccparams_lte.pucch_deltaF_Format1b);
+                AssertFatal (0,
+                             "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for pucch_deltaF_Format1b choice: deltaF1,dltaF3,deltaF5!\n",
+                             RC.config_file_name, i, ccparams_lte.pucch_deltaF_Format1b);
 
-            if (strcmp(ccparams_lte.pucch_deltaF_Format2,"deltaF_2")==0) {
-              RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pucch_deltaF_Format2= LTE_DeltaFList_PUCCH__deltaF_PUCCH_Format2_deltaF_2;
+              if (strcmp(ccparams_lte.pucch_deltaF_Format2,"deltaF_2")==0) {
+                RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pucch_deltaF_Format2= LTE_DeltaFList_PUCCH__deltaF_PUCCH_Format2_deltaF_2;
             } else if (strcmp(ccparams_lte.pucch_deltaF_Format2,"deltaF0")==0) {
-              RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pucch_deltaF_Format2= LTE_DeltaFList_PUCCH__deltaF_PUCCH_Format2_deltaF0;
+                RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pucch_deltaF_Format2= LTE_DeltaFList_PUCCH__deltaF_PUCCH_Format2_deltaF0;
             } else if (strcmp(ccparams_lte.pucch_deltaF_Format2,"deltaF1")==0) {
-              RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pucch_deltaF_Format2= LTE_DeltaFList_PUCCH__deltaF_PUCCH_Format2_deltaF1;
+                RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pucch_deltaF_Format2= LTE_DeltaFList_PUCCH__deltaF_PUCCH_Format2_deltaF1;
             } else if (strcmp(ccparams_lte.pucch_deltaF_Format2,"deltaF2")==0) {
-              RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pucch_deltaF_Format2= LTE_DeltaFList_PUCCH__deltaF_PUCCH_Format2_deltaF2;
-            } else
-              AssertFatal (0,
-                           "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for pucch_deltaF_Format2 choice: deltaF_2,dltaF0,deltaF1,deltaF2!\n",
-                           RC.config_file_name, i, ccparams_lte.pucch_deltaF_Format2);
+                RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pucch_deltaF_Format2= LTE_DeltaFList_PUCCH__deltaF_PUCCH_Format2_deltaF2;
+              } else
+                AssertFatal (0,
+                             "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for pucch_deltaF_Format2 choice: deltaF_2,dltaF0,deltaF1,deltaF2!\n",
+                             RC.config_file_name, i, ccparams_lte.pucch_deltaF_Format2);
 
-            if (strcmp(ccparams_lte.pucch_deltaF_Format2a,"deltaF_2")==0) {
-              RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pucch_deltaF_Format2a= LTE_DeltaFList_PUCCH__deltaF_PUCCH_Format2a_deltaF_2;
+              if (strcmp(ccparams_lte.pucch_deltaF_Format2a,"deltaF_2")==0) {
+                RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pucch_deltaF_Format2a= LTE_DeltaFList_PUCCH__deltaF_PUCCH_Format2a_deltaF_2;
             } else if (strcmp(ccparams_lte.pucch_deltaF_Format2a,"deltaF0")==0) {
-              RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pucch_deltaF_Format2a= LTE_DeltaFList_PUCCH__deltaF_PUCCH_Format2a_deltaF0;
+                RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pucch_deltaF_Format2a= LTE_DeltaFList_PUCCH__deltaF_PUCCH_Format2a_deltaF0;
             } else if (strcmp(ccparams_lte.pucch_deltaF_Format2a,"deltaF2")==0) {
-              RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pucch_deltaF_Format2a= LTE_DeltaFList_PUCCH__deltaF_PUCCH_Format2a_deltaF2;
+                RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pucch_deltaF_Format2a= LTE_DeltaFList_PUCCH__deltaF_PUCCH_Format2a_deltaF2;
             } else
-              AssertFatal (0,
-                           "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for pucch_deltaF_Format2a choice: deltaF_2,dltaF0,deltaF2!\n",
-                           RC.config_file_name, i, ccparams_lte.pucch_deltaF_Format2a);
+                AssertFatal (0,
+                             "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for pucch_deltaF_Format2a choice: deltaF_2,dltaF0,deltaF2!\n",
+                             RC.config_file_name, i, ccparams_lte.pucch_deltaF_Format2a);
 
-            if (strcmp(ccparams_lte.pucch_deltaF_Format2b,"deltaF_2")==0) {
-              RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pucch_deltaF_Format2b= LTE_DeltaFList_PUCCH__deltaF_PUCCH_Format2b_deltaF_2;
+              if (strcmp(ccparams_lte.pucch_deltaF_Format2b,"deltaF_2")==0) {
+                RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pucch_deltaF_Format2b= LTE_DeltaFList_PUCCH__deltaF_PUCCH_Format2b_deltaF_2;
             } else if (strcmp(ccparams_lte.pucch_deltaF_Format2b,"deltaF0")==0) {
-              RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pucch_deltaF_Format2b= LTE_DeltaFList_PUCCH__deltaF_PUCCH_Format2b_deltaF0;
+                RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pucch_deltaF_Format2b= LTE_DeltaFList_PUCCH__deltaF_PUCCH_Format2b_deltaF0;
             } else if (strcmp(ccparams_lte.pucch_deltaF_Format2b,"deltaF2")==0) {
-              RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pucch_deltaF_Format2b= LTE_DeltaFList_PUCCH__deltaF_PUCCH_Format2b_deltaF2;
+                RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pucch_deltaF_Format2b= LTE_DeltaFList_PUCCH__deltaF_PUCCH_Format2b_deltaF2;
             } else
-              AssertFatal (0,
-                           "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for pucch_deltaF_Format2b choice: deltaF_2,dltaF0,deltaF2!\n",
-                           RC.config_file_name, i, ccparams_lte.pucch_deltaF_Format2b);
-
-            RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].rach_numberOfRA_Preambles= (ccparams_lte.rach_numberOfRA_Preambles/4)-1;
-
-            if ((ccparams_lte.rach_numberOfRA_Preambles <4) ||
-                (ccparams_lte.rach_numberOfRA_Preambles>64) ||
-                ((ccparams_lte.rach_numberOfRA_Preambles&3)!=0))
-              AssertFatal (0,
-                           "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for rach_numberOfRA_Preambles choice: 4,8,12,...,64!\n",
-                           RC.config_file_name, i, ccparams_lte.rach_numberOfRA_Preambles);
+                AssertFatal (0,
+                             "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for pucch_deltaF_Format2b choice: deltaF_2,dltaF0,deltaF2!\n",
+                             RC.config_file_name, i, ccparams_lte.pucch_deltaF_Format2b);
 
-            if (strcmp(ccparams_lte.rach_preamblesGroupAConfig, "ENABLE") == 0) {
-              RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].rach_preamblesGroupAConfig= TRUE;
-              RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].rach_sizeOfRA_PreamblesGroupA= (ccparams_lte.rach_sizeOfRA_PreamblesGroupA/4)-1;
+              RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].rach_numberOfRA_Preambles= (ccparams_lte.rach_numberOfRA_Preambles/4)-1;
 
               if ((ccparams_lte.rach_numberOfRA_Preambles <4) ||
-                  (ccparams_lte.rach_numberOfRA_Preambles>60) ||
+                  (ccparams_lte.rach_numberOfRA_Preambles>64) ||
                   ((ccparams_lte.rach_numberOfRA_Preambles&3)!=0))
                 AssertFatal (0,
-                             "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for rach_sizeOfRA_PreamblesGroupA choice: 4,8,12,...,60!\n",
-                             RC.config_file_name, i, ccparams_lte.rach_sizeOfRA_PreamblesGroupA);
+                             "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for rach_numberOfRA_Preambles choice: 4,8,12,...,64!\n",
+                             RC.config_file_name, i, ccparams_lte.rach_numberOfRA_Preambles);
+
+              if (strcmp(ccparams_lte.rach_preamblesGroupAConfig, "ENABLE") == 0) {
+                RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].rach_preamblesGroupAConfig= TRUE;
+                RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].rach_sizeOfRA_PreamblesGroupA= (ccparams_lte.rach_sizeOfRA_PreamblesGroupA/4)-1;
+
+                if ((ccparams_lte.rach_numberOfRA_Preambles <4) ||
+                    (ccparams_lte.rach_numberOfRA_Preambles>60) ||
+                    ((ccparams_lte.rach_numberOfRA_Preambles&3)!=0))
+                  AssertFatal (0,
+                               "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for rach_sizeOfRA_PreamblesGroupA choice: 4,8,12,...,60!\n",
+                               RC.config_file_name, i, ccparams_lte.rach_sizeOfRA_PreamblesGroupA);
 
-              switch (ccparams_lte.rach_messageSizeGroupA) {
+                switch (ccparams_lte.rach_messageSizeGroupA) {
                 case 56:
                   RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].rach_messageSizeGroupA= LTE_RACH_ConfigCommon__preambleInfo__preamblesGroupAConfig__messageSizeGroupA_b56;
                   break;
@@ -979,54 +954,54 @@ int RCconfig_RRC(MessageDef *msg_p, uint32_t i, eNB_RRC_INST *rrc) {
                                "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for rach_messageSizeGroupA choice: 56,144,208,256!\n",
                                RC.config_file_name, i, ccparams_lte.rach_messageSizeGroupA);
                   break;
-              }
+                }
 
-              if (strcmp(ccparams_lte.rach_messagePowerOffsetGroupB,"minusinfinity")==0) {
-                RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].rach_messagePowerOffsetGroupB= LTE_RACH_ConfigCommon__preambleInfo__preamblesGroupAConfig__messagePowerOffsetGroupB_minusinfinity;
+                if (strcmp(ccparams_lte.rach_messagePowerOffsetGroupB,"minusinfinity")==0) {
+                  RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].rach_messagePowerOffsetGroupB= LTE_RACH_ConfigCommon__preambleInfo__preamblesGroupAConfig__messagePowerOffsetGroupB_minusinfinity;
               } else if (strcmp(ccparams_lte.rach_messagePowerOffsetGroupB,"dB0")==0) {
-                RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].rach_messagePowerOffsetGroupB= LTE_RACH_ConfigCommon__preambleInfo__preamblesGroupAConfig__messagePowerOffsetGroupB_dB0;
+                  RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].rach_messagePowerOffsetGroupB= LTE_RACH_ConfigCommon__preambleInfo__preamblesGroupAConfig__messagePowerOffsetGroupB_dB0;
               } else if (strcmp(ccparams_lte.rach_messagePowerOffsetGroupB,"dB5")==0) {
-                RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].rach_messagePowerOffsetGroupB= LTE_RACH_ConfigCommon__preambleInfo__preamblesGroupAConfig__messagePowerOffsetGroupB_dB5;
+                  RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].rach_messagePowerOffsetGroupB= LTE_RACH_ConfigCommon__preambleInfo__preamblesGroupAConfig__messagePowerOffsetGroupB_dB5;
               } else if (strcmp(ccparams_lte.rach_messagePowerOffsetGroupB,"dB8")==0) {
-                RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].rach_messagePowerOffsetGroupB= LTE_RACH_ConfigCommon__preambleInfo__preamblesGroupAConfig__messagePowerOffsetGroupB_dB8;
+                  RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].rach_messagePowerOffsetGroupB= LTE_RACH_ConfigCommon__preambleInfo__preamblesGroupAConfig__messagePowerOffsetGroupB_dB8;
               } else if (strcmp(ccparams_lte.rach_messagePowerOffsetGroupB,"dB10")==0) {
-                RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].rach_messagePowerOffsetGroupB= LTE_RACH_ConfigCommon__preambleInfo__preamblesGroupAConfig__messagePowerOffsetGroupB_dB10;
+                  RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].rach_messagePowerOffsetGroupB= LTE_RACH_ConfigCommon__preambleInfo__preamblesGroupAConfig__messagePowerOffsetGroupB_dB10;
               } else if (strcmp(ccparams_lte.rach_messagePowerOffsetGroupB,"dB12")==0) {
-                RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].rach_messagePowerOffsetGroupB= LTE_RACH_ConfigCommon__preambleInfo__preamblesGroupAConfig__messagePowerOffsetGroupB_dB12;
+                  RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].rach_messagePowerOffsetGroupB= LTE_RACH_ConfigCommon__preambleInfo__preamblesGroupAConfig__messagePowerOffsetGroupB_dB12;
               } else if (strcmp(ccparams_lte.rach_messagePowerOffsetGroupB,"dB15")==0) {
-                RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].rach_messagePowerOffsetGroupB= LTE_RACH_ConfigCommon__preambleInfo__preamblesGroupAConfig__messagePowerOffsetGroupB_dB15;
+                  RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].rach_messagePowerOffsetGroupB= LTE_RACH_ConfigCommon__preambleInfo__preamblesGroupAConfig__messagePowerOffsetGroupB_dB15;
               } else if (strcmp(ccparams_lte.rach_messagePowerOffsetGroupB,"dB18")==0) {
-                RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].rach_messagePowerOffsetGroupB= LTE_RACH_ConfigCommon__preambleInfo__preamblesGroupAConfig__messagePowerOffsetGroupB_dB18;
+                  RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].rach_messagePowerOffsetGroupB= LTE_RACH_ConfigCommon__preambleInfo__preamblesGroupAConfig__messagePowerOffsetGroupB_dB18;
+              } else
+                  AssertFatal (0,
+                               "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for rach_messagePowerOffsetGroupB choice: minusinfinity,dB0,dB5,dB8,dB10,dB12,dB15,dB18!\n",
+                               RC.config_file_name, i, ccparams_lte.rach_messagePowerOffsetGroupB);
+              } else if (strcmp(ccparams_lte.rach_preamblesGroupAConfig, "DISABLE") == 0) {
+                RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].rach_preamblesGroupAConfig= FALSE;
               } else
                 AssertFatal (0,
-                             "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for rach_messagePowerOffsetGroupB choice: minusinfinity,dB0,dB5,dB8,dB10,dB12,dB15,dB18!\n",
-                             RC.config_file_name, i, ccparams_lte.rach_messagePowerOffsetGroupB);
-            } else if (strcmp(ccparams_lte.rach_preamblesGroupAConfig, "DISABLE") == 0) {
-              RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].rach_preamblesGroupAConfig= FALSE;
-            } else
-              AssertFatal (0,
-                           "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for rach_preamblesGroupAConfig choice: ENABLE,DISABLE !\n",
-                           RC.config_file_name, i, ccparams_lte.rach_preamblesGroupAConfig);
+                             "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for rach_preamblesGroupAConfig choice: ENABLE,DISABLE !\n",
+                             RC.config_file_name, i, ccparams_lte.rach_preamblesGroupAConfig);
 
-            RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].rach_preambleInitialReceivedTargetPower= (ccparams_lte.rach_preambleInitialReceivedTargetPower+120)/2;
+              RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].rach_preambleInitialReceivedTargetPower= (ccparams_lte.rach_preambleInitialReceivedTargetPower+120)/2;
 
-            if ((ccparams_lte.rach_preambleInitialReceivedTargetPower<-120) ||
-                (ccparams_lte.rach_preambleInitialReceivedTargetPower>-90) ||
-                ((ccparams_lte.rach_preambleInitialReceivedTargetPower&1)!=0))
-              AssertFatal (0,
-                           "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for rach_preambleInitialReceivedTargetPower choice: -120,-118,...,-90 !\n",
-                           RC.config_file_name, i, ccparams_lte.rach_preambleInitialReceivedTargetPower);
+              if ((ccparams_lte.rach_preambleInitialReceivedTargetPower<-120) ||
+                  (ccparams_lte.rach_preambleInitialReceivedTargetPower>-90) ||
+                  ((ccparams_lte.rach_preambleInitialReceivedTargetPower&1)!=0))
+                AssertFatal (0,
+                             "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for rach_preambleInitialReceivedTargetPower choice: -120,-118,...,-90 !\n",
+                             RC.config_file_name, i, ccparams_lte.rach_preambleInitialReceivedTargetPower);
 
-            RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].rach_powerRampingStep= ccparams_lte.rach_powerRampingStep/2;
+              RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].rach_powerRampingStep= ccparams_lte.rach_powerRampingStep/2;
 
-            if ((ccparams_lte.rach_powerRampingStep<0) ||
-                (ccparams_lte.rach_powerRampingStep>6) ||
-                ((ccparams_lte.rach_powerRampingStep&1)!=0))
-              AssertFatal (0,
-                           "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for rach_powerRampingStep choice: 0,2,4,6 !\n",
-                           RC.config_file_name, i, ccparams_lte.rach_powerRampingStep);
+              if ((ccparams_lte.rach_powerRampingStep<0) ||
+                  (ccparams_lte.rach_powerRampingStep>6) ||
+                  ((ccparams_lte.rach_powerRampingStep&1)!=0))
+                AssertFatal (0,
+                             "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for rach_powerRampingStep choice: 0,2,4,6 !\n",
+                             RC.config_file_name, i, ccparams_lte.rach_powerRampingStep);
 
-            switch (ccparams_lte.rach_preambleTransMax) {
+              switch (ccparams_lte.rach_preambleTransMax) {
 #if (LTE_RRC_VERSION < MAKE_VERSION(14, 0, 0))
 
               case 3:
@@ -1124,35 +1099,35 @@ int RCconfig_RRC(MessageDef *msg_p, uint32_t i, eNB_RRC_INST *rrc) {
                              "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for rach_preambleTransMax choice: 3,4,5,6,7,8,10,20,50,100,200!\n",
                              RC.config_file_name, i, ccparams_lte.rach_preambleTransMax);
                 break;
-            }
+              }
 
-            RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].rach_raResponseWindowSize=  (ccparams_lte.rach_raResponseWindowSize==10)?7:ccparams_lte.rach_raResponseWindowSize-2;
+              RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].rach_raResponseWindowSize=  (ccparams_lte.rach_raResponseWindowSize==10)?7:ccparams_lte.rach_raResponseWindowSize-2;
 
-            if ((ccparams_lte.rach_raResponseWindowSize<0)||
-                (ccparams_lte.rach_raResponseWindowSize==9)||
-                (ccparams_lte.rach_raResponseWindowSize>10))
-              AssertFatal (0,
-                           "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for rach_raResponseWindowSize choice: 2,3,4,5,6,7,8,10!\n",
-                           RC.config_file_name, i, ccparams_lte.rach_preambleTransMax);
+              if ((ccparams_lte.rach_raResponseWindowSize<0)||
+                  (ccparams_lte.rach_raResponseWindowSize==9)||
+                  (ccparams_lte.rach_raResponseWindowSize>10))
+                AssertFatal (0,
+                             "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for rach_raResponseWindowSize choice: 2,3,4,5,6,7,8,10!\n",
+                             RC.config_file_name, i, ccparams_lte.rach_preambleTransMax);
 
-            RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].rach_macContentionResolutionTimer= (ccparams_lte.rach_macContentionResolutionTimer/8)-1;
+              RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].rach_macContentionResolutionTimer= (ccparams_lte.rach_macContentionResolutionTimer/8)-1;
 
-            if ((ccparams_lte.rach_macContentionResolutionTimer<8) ||
-                (ccparams_lte.rach_macContentionResolutionTimer>64) ||
-                ((ccparams_lte.rach_macContentionResolutionTimer&7)!=0))
-              AssertFatal (0,
-                           "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for rach_macContentionResolutionTimer choice: 8,16,...,56,64!\n",
-                           RC.config_file_name, i, ccparams_lte.rach_preambleTransMax);
+              if ((ccparams_lte.rach_macContentionResolutionTimer<8) ||
+                  (ccparams_lte.rach_macContentionResolutionTimer>64) ||
+                  ((ccparams_lte.rach_macContentionResolutionTimer&7)!=0))
+                AssertFatal (0,
+                             "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for rach_macContentionResolutionTimer choice: 8,16,...,56,64!\n",
+                             RC.config_file_name, i, ccparams_lte.rach_preambleTransMax);
 
-            RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].rach_maxHARQ_Msg3Tx= ccparams_lte.rach_maxHARQ_Msg3Tx;
+              RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].rach_maxHARQ_Msg3Tx= ccparams_lte.rach_maxHARQ_Msg3Tx;
 
-            if ((ccparams_lte.rach_maxHARQ_Msg3Tx<0) ||
-                (ccparams_lte.rach_maxHARQ_Msg3Tx>8))
-              AssertFatal (0,
-                           "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for rach_maxHARQ_Msg3Tx choice: 1..8!\n",
-                           RC.config_file_name, i, ccparams_lte.rach_preambleTransMax);
+              if ((ccparams_lte.rach_maxHARQ_Msg3Tx<0) ||
+                  (ccparams_lte.rach_maxHARQ_Msg3Tx>8))
+                AssertFatal (0,
+                             "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for rach_maxHARQ_Msg3Tx choice: 1..8!\n",
+                             RC.config_file_name, i, ccparams_lte.rach_preambleTransMax);
 
-            switch (ccparams_lte.pcch_defaultPagingCycle) {
+              switch (ccparams_lte.pcch_defaultPagingCycle) {
               case 32:
                 RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pcch_defaultPagingCycle= LTE_PCCH_Config__defaultPagingCycle_rf32;
                 break;
@@ -1174,30 +1149,30 @@ int RCconfig_RRC(MessageDef *msg_p, uint32_t i, eNB_RRC_INST *rrc) {
                              "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for pcch_defaultPagingCycle choice: 32,64,128,256!\n",
                              RC.config_file_name, i, ccparams_lte.pcch_defaultPagingCycle);
                 break;
-            }
+              }
 
-            if (strcmp(ccparams_lte.pcch_nB, "fourT") == 0) {
-              RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pcch_nB= LTE_PCCH_Config__nB_fourT;
+              if (strcmp(ccparams_lte.pcch_nB, "fourT") == 0) {
+                RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pcch_nB= LTE_PCCH_Config__nB_fourT;
             } else if (strcmp(ccparams_lte.pcch_nB, "twoT") == 0) {
-              RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pcch_nB= LTE_PCCH_Config__nB_twoT;
+                RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pcch_nB= LTE_PCCH_Config__nB_twoT;
             } else if (strcmp(ccparams_lte.pcch_nB, "oneT") == 0) {
-              RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pcch_nB= LTE_PCCH_Config__nB_oneT;
+                RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pcch_nB= LTE_PCCH_Config__nB_oneT;
             } else if (strcmp(ccparams_lte.pcch_nB, "halfT") == 0) {
-              RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pcch_nB= LTE_PCCH_Config__nB_halfT;
+                RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pcch_nB= LTE_PCCH_Config__nB_halfT;
             } else if (strcmp(ccparams_lte.pcch_nB, "quarterT") == 0) {
-              RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pcch_nB= LTE_PCCH_Config__nB_quarterT;
+                RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pcch_nB= LTE_PCCH_Config__nB_quarterT;
             } else if (strcmp(ccparams_lte.pcch_nB, "oneEighthT") == 0) {
-              RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pcch_nB= LTE_PCCH_Config__nB_oneEighthT;
+                RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pcch_nB= LTE_PCCH_Config__nB_oneEighthT;
             } else if (strcmp(ccparams_lte.pcch_nB, "oneSixteenthT") == 0) {
-              RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pcch_nB= LTE_PCCH_Config__nB_oneSixteenthT;
+                RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pcch_nB= LTE_PCCH_Config__nB_oneSixteenthT;
             } else if (strcmp(ccparams_lte.pcch_nB, "oneThirtySecondT") == 0) {
-              RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pcch_nB= LTE_PCCH_Config__nB_oneThirtySecondT;
+                RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pcch_nB= LTE_PCCH_Config__nB_oneThirtySecondT;
             } else
-              AssertFatal (0,
-                           "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for pcch_nB choice: fourT,twoT,oneT,halfT,quarterT,oneighthT,oneSixteenthT,oneThirtySecondT !\n",
-                           RC.config_file_name, i, ccparams_lte.pcch_nB);
+                AssertFatal (0,
+                             "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for pcch_nB choice: fourT,twoT,oneT,halfT,quarterT,oneighthT,oneSixteenthT,oneThirtySecondT !\n",
+                             RC.config_file_name, i, ccparams_lte.pcch_nB);
 
-            switch (ccparams_lte.bcch_modificationPeriodCoeff) {
+              switch (ccparams_lte.bcch_modificationPeriodCoeff) {
               case 2:
                 RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].bcch_modificationPeriodCoeff= LTE_BCCH_Config__modificationPeriodCoeff_n2;
                 break;
@@ -1219,16 +1194,16 @@ int RCconfig_RRC(MessageDef *msg_p, uint32_t i, eNB_RRC_INST *rrc) {
                              "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for bcch_modificationPeriodCoeff choice: 2,4,8,16",
                              RC.config_file_name, i, ccparams_lte.bcch_modificationPeriodCoeff);
                 break;
-            }
+              }
 
-            RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].ue_TimersAndConstants_t300= ccparams_lte.ue_TimersAndConstants_t300;
-            RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].ue_TimersAndConstants_t301= ccparams_lte.ue_TimersAndConstants_t301;
-            RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].ue_TimersAndConstants_t310= ccparams_lte.ue_TimersAndConstants_t310;
-            RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].ue_TimersAndConstants_t311= ccparams_lte.ue_TimersAndConstants_t311;
-            RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].ue_TimersAndConstants_n310= ccparams_lte.ue_TimersAndConstants_n310;
-            RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].ue_TimersAndConstants_n311= ccparams_lte.ue_TimersAndConstants_n311;
+              RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].ue_TimersAndConstants_t300= ccparams_lte.ue_TimersAndConstants_t300;
+              RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].ue_TimersAndConstants_t301= ccparams_lte.ue_TimersAndConstants_t301;
+              RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].ue_TimersAndConstants_t310= ccparams_lte.ue_TimersAndConstants_t310;
+              RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].ue_TimersAndConstants_t311= ccparams_lte.ue_TimersAndConstants_t311;
+              RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].ue_TimersAndConstants_n310= ccparams_lte.ue_TimersAndConstants_n310;
+              RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].ue_TimersAndConstants_n311= ccparams_lte.ue_TimersAndConstants_n311;
 
-            switch (ccparams_lte.ue_TransmissionMode) {
+              switch (ccparams_lte.ue_TransmissionMode) {
               case 1:
                 RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].ue_TransmissionMode= LTE_AntennaInfoDedicated__transmissionMode_tm1;
                 break;
@@ -1262,11 +1237,11 @@ int RCconfig_RRC(MessageDef *msg_p, uint32_t i, eNB_RRC_INST *rrc) {
                              "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for ue_TransmissionMode choice: 1,2,3,4,5,6,7",
                              RC.config_file_name, i, ccparams_lte.ue_TransmissionMode);
                 break;
-            }
+              }
 
-            RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].ue_multiple_max= ccparams_lte.ue_multiple_max;
+              RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].ue_multiple_max= ccparams_lte.ue_multiple_max;
 
-            switch (ccparams_lte.N_RB_DL) {
+              switch (ccparams_lte.N_RB_DL) {
               case 25:
                 if ((ccparams_lte.ue_multiple_max < 1) ||
                     (ccparams_lte.ue_multiple_max > 4))
@@ -1299,338 +1274,509 @@ int RCconfig_RRC(MessageDef *msg_p, uint32_t i, eNB_RRC_INST *rrc) {
                              "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for N_RB_DL choice: 25,50,100 !\n",
                              RC.config_file_name, i, ccparams_lte.N_RB_DL);
                 break;
-            }
+              }
 
-            // eMBMS configuration
-            RRC_CONFIGURATION_REQ(msg_p).eMBMS_configured = 0;
-            printf("No eMBMS configuration, skipping it\n");
-            // eMTC configuration
-            char brparamspath[MAX_OPTNAME_SIZE*2 + 16];
-            sprintf(brparamspath,"%s.%s", ccspath, ENB_CONFIG_STRING_EMTC_PARAMETERS);
-            config_get(eMTCParams, sizeof(eMTCParams)/sizeof(paramdef_t), brparamspath);
-            RRC_CONFIGURATION_REQ(msg_p).eMTC_configured = eMTCconfig.eMTC_configured&1;
-
-            if (eMTCconfig.eMTC_configured > 0) fill_eMTC_configuration(msg_p,&eMTCconfig, i,j,RC.config_file_name,brparamspath);
-            else                            printf("No eMTC configuration, skipping it\n");
-
-            // Sidelink configuration
-            char SLparamspath[MAX_OPTNAME_SIZE*2 + 16];
-            sprintf(SLparamspath,"%s.%s", ccspath, ENB_CONFIG_STRING_SL_PARAMETERS);
-            config_get( SLParams, sizeof(SLParams)/sizeof(paramdef_t), SLparamspath);
-            // Sidelink Resource pool information
-            RRC_CONFIGURATION_REQ (msg_p).SL_configured=SLconfig.sidelink_configured&1;
-
-            if (SLconfig.sidelink_configured==1) fill_SL_configuration(msg_p,&SLconfig,i,j,RC.config_file_name);
-            else                                 printf("No SL configuration skipping it\n");
+              // eMBMS configuration
+              RRC_CONFIGURATION_REQ(msg_p).eMBMS_configured = 0;
+              printf("No eMBMS configuration, skipping it\n");
+              // eMTC configuration
+              char brparamspath[MAX_OPTNAME_SIZE*2 + 16];
+              sprintf(brparamspath,"%s.%s", ccspath, ENB_CONFIG_STRING_EMTC_PARAMETERS);
+              config_get(eMTCParams, sizeof(eMTCParams)/sizeof(paramdef_t), brparamspath);
+              RRC_CONFIGURATION_REQ(msg_p).eMTC_configured = eMTCconfig.eMTC_configured&1;
+
+              if (eMTCconfig.eMTC_configured > 0) fill_eMTC_configuration(msg_p,&eMTCconfig, i,j,RC.config_file_name,brparamspath);
+              else   	                        printf("No eMTC configuration, skipping it\n");
+
+              // Sidelink configuration
+              char SLparamspath[MAX_OPTNAME_SIZE*2 + 16];
+              sprintf(SLparamspath,"%s.%s", ccspath, ENB_CONFIG_STRING_SL_PARAMETERS);
+              config_get( SLParams, sizeof(SLParams)/sizeof(paramdef_t), SLparamspath);
+              // Sidelink Resource pool information
+              RRC_CONFIGURATION_REQ (msg_p).SL_configured=SLconfig.sidelink_configured&1;
+
+              if (SLconfig.sidelink_configured==1) fill_SL_configuration(msg_p,&SLconfig,i,j,RC.config_file_name);
+              else                                 printf("No SL configuration skipping it\n");
+            } // !NODE_IS_DU(node_type)
           }
-        }
 
-        char srb1path[MAX_OPTNAME_SIZE*2 + 8];
-        sprintf(srb1path,"%s.%s",enbpath,ENB_CONFIG_STRING_SRB1);
-        config_get( SRB1Params,sizeof(SRB1Params)/sizeof(paramdef_t), srb1path);
+          if (!NODE_IS_DU(rrc->node_type)) {
+            char srb1path[MAX_OPTNAME_SIZE*2 + 8];
+            sprintf(srb1path,"%s.%s",enbpath,ENB_CONFIG_STRING_SRB1);
+            config_get( SRB1Params,sizeof(SRB1Params)/sizeof(paramdef_t), srb1path);
 
-        switch (srb1_params.srb1_max_retx_threshold) {
-          case 1:
-            rrc->srb1_max_retx_threshold = LTE_UL_AM_RLC__maxRetxThreshold_t1;
-            break;
+            switch (srb1_params.srb1_max_retx_threshold) {
+            case 1:
+              rrc->srb1_max_retx_threshold = LTE_UL_AM_RLC__maxRetxThreshold_t1;
+              break;
 
-          case 2:
-            rrc->srb1_max_retx_threshold = LTE_UL_AM_RLC__maxRetxThreshold_t2;
-            break;
+            case 2:
+              rrc->srb1_max_retx_threshold = LTE_UL_AM_RLC__maxRetxThreshold_t2;
+              break;
 
-          case 3:
-            rrc->srb1_max_retx_threshold = LTE_UL_AM_RLC__maxRetxThreshold_t3;
-            break;
+            case 3:
+              rrc->srb1_max_retx_threshold = LTE_UL_AM_RLC__maxRetxThreshold_t3;
+              break;
 
-          case 4:
-            rrc->srb1_max_retx_threshold = LTE_UL_AM_RLC__maxRetxThreshold_t4;
-            break;
+            case 4:
+              rrc->srb1_max_retx_threshold = LTE_UL_AM_RLC__maxRetxThreshold_t4;
+              break;
 
-          case 6:
-            rrc->srb1_max_retx_threshold = LTE_UL_AM_RLC__maxRetxThreshold_t6;
-            break;
+            case 6:
+              rrc->srb1_max_retx_threshold = LTE_UL_AM_RLC__maxRetxThreshold_t6;
+              break;
 
-          case 8:
-            rrc->srb1_max_retx_threshold = LTE_UL_AM_RLC__maxRetxThreshold_t8;
-            break;
+            case 8:
+              rrc->srb1_max_retx_threshold = LTE_UL_AM_RLC__maxRetxThreshold_t8;
+              break;
 
-          case 16:
-            rrc->srb1_max_retx_threshold = LTE_UL_AM_RLC__maxRetxThreshold_t16;
-            break;
+            case 16:
+              rrc->srb1_max_retx_threshold = LTE_UL_AM_RLC__maxRetxThreshold_t16;
+              break;
 
-          case 32:
-            rrc->srb1_max_retx_threshold = LTE_UL_AM_RLC__maxRetxThreshold_t32;
-            break;
+            case 32:
+              rrc->srb1_max_retx_threshold = LTE_UL_AM_RLC__maxRetxThreshold_t32;
+              break;
 
-          default:
-            AssertFatal (0,
-                         "Bad config value when parsing eNB configuration file %s, enb %d  srb1_max_retx_threshold %u!\n",
-                         RC.config_file_name, i, srb1_params.srb1_max_retx_threshold);
-        }
+            default:
+              AssertFatal (0,
+                           "Bad config value when parsing eNB configuration file %s, enb %d  srb1_max_retx_threshold %u!\n",
+                           RC.config_file_name, i, srb1_params.srb1_max_retx_threshold);
+            }
 
-        switch (srb1_params.srb1_poll_pdu) {
-          case 4:
-            rrc->srb1_poll_pdu = LTE_PollPDU_p4;
-            break;
+            switch (srb1_params.srb1_poll_pdu) {
+            case 4:
+              rrc->srb1_poll_pdu = LTE_PollPDU_p4;
+              break;
 
-          case 8:
-            rrc->srb1_poll_pdu = LTE_PollPDU_p8;
-            break;
+            case 8:
+              rrc->srb1_poll_pdu = LTE_PollPDU_p8;
+              break;
 
-          case 16:
-            rrc->srb1_poll_pdu = LTE_PollPDU_p16;
-            break;
+            case 16:
+              rrc->srb1_poll_pdu = LTE_PollPDU_p16;
+              break;
 
-          case 32:
-            rrc->srb1_poll_pdu = LTE_PollPDU_p32;
-            break;
+            case 32:
+              rrc->srb1_poll_pdu = LTE_PollPDU_p32;
+              break;
 
-          case 64:
-            rrc->srb1_poll_pdu = LTE_PollPDU_p64;
-            break;
+            case 64:
+              rrc->srb1_poll_pdu = LTE_PollPDU_p64;
+              break;
 
-          case 128:
-            rrc->srb1_poll_pdu = LTE_PollPDU_p128;
-            break;
+            case 128:
+              rrc->srb1_poll_pdu = LTE_PollPDU_p128;
+              break;
 
-          case 256:
-            rrc->srb1_poll_pdu = LTE_PollPDU_p256;
-            break;
+            case 256:
+              rrc->srb1_poll_pdu = LTE_PollPDU_p256;
+              break;
 
-          default:
-            if (srb1_params.srb1_poll_pdu >= 10000)
-              rrc->srb1_poll_pdu = LTE_PollPDU_pInfinity;
-            else
-              AssertFatal (0,
-                           "Bad config value when parsing eNB configuration file %s, enb %d  srb1_poll_pdu %u!\n",
-                           RC.config_file_name, i, srb1_params.srb1_poll_pdu);
-        }
+            default:
+              if (srb1_params.srb1_poll_pdu >= 10000)
+                rrc->srb1_poll_pdu = LTE_PollPDU_pInfinity;
+              else
+                AssertFatal (0,
+                             "Bad config value when parsing eNB configuration file %s, enb %d  srb1_poll_pdu %u!\n",
+                             RC.config_file_name, i, srb1_params.srb1_poll_pdu);
+            }
 
-        rrc->srb1_poll_byte             = srb1_params.srb1_poll_byte;
+            rrc->srb1_poll_byte             = srb1_params.srb1_poll_byte;
 
-        switch (srb1_params.srb1_poll_byte) {
-          case 25:
-            rrc->srb1_poll_byte = LTE_PollByte_kB25;
-            break;
+            switch (srb1_params.srb1_poll_byte) {
+            case 25:
+              rrc->srb1_poll_byte = LTE_PollByte_kB25;
+              break;
 
-          case 50:
-            rrc->srb1_poll_byte = LTE_PollByte_kB50;
-            break;
+            case 50:
+              rrc->srb1_poll_byte = LTE_PollByte_kB50;
+              break;
 
-          case 75:
-            rrc->srb1_poll_byte = LTE_PollByte_kB75;
-            break;
+            case 75:
+              rrc->srb1_poll_byte = LTE_PollByte_kB75;
+              break;
 
-          case 100:
-            rrc->srb1_poll_byte = LTE_PollByte_kB100;
-            break;
+            case 100:
+              rrc->srb1_poll_byte = LTE_PollByte_kB100;
+              break;
 
-          case 125:
-            rrc->srb1_poll_byte = LTE_PollByte_kB125;
-            break;
+            case 125:
+              rrc->srb1_poll_byte = LTE_PollByte_kB125;
+              break;
 
-          case 250:
-            rrc->srb1_poll_byte = LTE_PollByte_kB250;
-            break;
+            case 250:
+              rrc->srb1_poll_byte = LTE_PollByte_kB250;
+              break;
 
-          case 375:
-            rrc->srb1_poll_byte = LTE_PollByte_kB375;
-            break;
+            case 375:
+              rrc->srb1_poll_byte = LTE_PollByte_kB375;
+              break;
 
-          case 500:
-            rrc->srb1_poll_byte = LTE_PollByte_kB500;
-            break;
+            case 500:
+              rrc->srb1_poll_byte = LTE_PollByte_kB500;
+              break;
 
-          case 750:
-            rrc->srb1_poll_byte = LTE_PollByte_kB750;
-            break;
+            case 750:
+              rrc->srb1_poll_byte = LTE_PollByte_kB750;
+              break;
 
-          case 1000:
-            rrc->srb1_poll_byte = LTE_PollByte_kB1000;
-            break;
+            case 1000:
+              rrc->srb1_poll_byte = LTE_PollByte_kB1000;
+              break;
 
-          case 1250:
-            rrc->srb1_poll_byte = LTE_PollByte_kB1250;
-            break;
+            case 1250:
+              rrc->srb1_poll_byte = LTE_PollByte_kB1250;
+              break;
 
-          case 1500:
-            rrc->srb1_poll_byte = LTE_PollByte_kB1500;
-            break;
+            case 1500:
+              rrc->srb1_poll_byte = LTE_PollByte_kB1500;
+              break;
 
-          case 2000:
-            rrc->srb1_poll_byte = LTE_PollByte_kB2000;
-            break;
+            case 2000:
+              rrc->srb1_poll_byte = LTE_PollByte_kB2000;
+              break;
 
-          case 3000:
-            rrc->srb1_poll_byte = LTE_PollByte_kB3000;
-            break;
+            case 3000:
+              rrc->srb1_poll_byte = LTE_PollByte_kB3000;
+              break;
 
-          default:
-            if (srb1_params.srb1_poll_byte >= 10000)
-              rrc->srb1_poll_byte = LTE_PollByte_kBinfinity;
-            else
-              AssertFatal (0,
-                           "Bad config value when parsing eNB configuration file %s, enb %d  srb1_poll_byte %u!\n",
-                           RC.config_file_name, i, srb1_params.srb1_poll_byte);
-        }
+            default:
+              if (srb1_params.srb1_poll_byte >= 10000)
+                rrc->srb1_poll_byte = LTE_PollByte_kBinfinity;
+              else
+                AssertFatal (0,
+                             "Bad config value when parsing eNB configuration file %s, enb %d  srb1_poll_byte %u!\n",
+                             RC.config_file_name, i, srb1_params.srb1_poll_byte);
+            }
 
-        if (srb1_params.srb1_timer_poll_retransmit <= 250) {
-          rrc->srb1_timer_poll_retransmit = (srb1_params.srb1_timer_poll_retransmit - 5)/5;
-        } else if (srb1_params.srb1_timer_poll_retransmit <= 500) {
-          rrc->srb1_timer_poll_retransmit = (srb1_params.srb1_timer_poll_retransmit - 300)/50 + 50;
-        } else {
-          AssertFatal (0,
-                       "Bad config value when parsing eNB configuration file %s, enb %d  srb1_timer_poll_retransmit %u!\n",
-                       RC.config_file_name, i, srb1_params.srb1_timer_poll_retransmit);
-        }
+            if (srb1_params.srb1_timer_poll_retransmit <= 250) {
+              rrc->srb1_timer_poll_retransmit = (srb1_params.srb1_timer_poll_retransmit - 5)/5;
+            } else if (srb1_params.srb1_timer_poll_retransmit <= 500) {
+              rrc->srb1_timer_poll_retransmit = (srb1_params.srb1_timer_poll_retransmit - 300)/50 + 50;
+            } else {
+              AssertFatal (0,
+                           "Bad config value when parsing eNB configuration file %s, enb %d  srb1_timer_poll_retransmit %u!\n",
+                           RC.config_file_name, i, srb1_params.srb1_timer_poll_retransmit);
+            }
 
-        if (srb1_params.srb1_timer_status_prohibit <= 250) {
-          rrc->srb1_timer_status_prohibit = srb1_params.srb1_timer_status_prohibit/5;
-        } else if ((srb1_params.srb1_timer_poll_retransmit >= 300) && (srb1_params.srb1_timer_poll_retransmit <= 500)) {
-          rrc->srb1_timer_status_prohibit = (srb1_params.srb1_timer_status_prohibit - 300)/50 + 51;
-        } else {
-          AssertFatal (0,
-                       "Bad config value when parsing eNB configuration file %s, enb %d  srb1_timer_status_prohibit %u!\n",
-                       RC.config_file_name, i, srb1_params.srb1_timer_status_prohibit);
-        }
+            if (srb1_params.srb1_timer_status_prohibit <= 250) {
+              rrc->srb1_timer_status_prohibit = srb1_params.srb1_timer_status_prohibit/5;
+            } else if ((srb1_params.srb1_timer_poll_retransmit >= 300) && (srb1_params.srb1_timer_poll_retransmit <= 500)) {
+              rrc->srb1_timer_status_prohibit = (srb1_params.srb1_timer_status_prohibit - 300)/50 + 51;
+            } else {
+              AssertFatal (0,
+                           "Bad config value when parsing eNB configuration file %s, enb %d  srb1_timer_status_prohibit %u!\n",
+                           RC.config_file_name, i, srb1_params.srb1_timer_status_prohibit);
+            }
 
-        switch (srb1_params.srb1_timer_reordering) {
-          case 0:
-            rrc->srb1_timer_reordering = LTE_T_Reordering_ms0;
-            break;
+            switch (srb1_params.srb1_timer_reordering) {
+            case 0:
+              rrc->srb1_timer_reordering = LTE_T_Reordering_ms0;
+              break;
 
-          case 5:
-            rrc->srb1_timer_reordering = LTE_T_Reordering_ms5;
-            break;
+            case 5:
+              rrc->srb1_timer_reordering = LTE_T_Reordering_ms5;
+              break;
 
-          case 10:
-            rrc->srb1_timer_reordering = LTE_T_Reordering_ms10;
-            break;
+            case 10:
+              rrc->srb1_timer_reordering = LTE_T_Reordering_ms10;
+              break;
 
-          case 15:
-            rrc->srb1_timer_reordering = LTE_T_Reordering_ms15;
-            break;
+            case 15:
+              rrc->srb1_timer_reordering = LTE_T_Reordering_ms15;
+              break;
 
-          case 20:
-            rrc->srb1_timer_reordering = LTE_T_Reordering_ms20;
-            break;
+            case 20:
+              rrc->srb1_timer_reordering = LTE_T_Reordering_ms20;
+              break;
 
-          case 25:
-            rrc->srb1_timer_reordering = LTE_T_Reordering_ms25;
-            break;
+            case 25:
+              rrc->srb1_timer_reordering = LTE_T_Reordering_ms25;
+              break;
 
-          case 30:
-            rrc->srb1_timer_reordering = LTE_T_Reordering_ms30;
-            break;
+            case 30:
+              rrc->srb1_timer_reordering = LTE_T_Reordering_ms30;
+              break;
 
-          case 35:
-            rrc->srb1_timer_reordering = LTE_T_Reordering_ms35;
-            break;
+            case 35:
+              rrc->srb1_timer_reordering = LTE_T_Reordering_ms35;
+              break;
 
-          case 40:
-            rrc->srb1_timer_reordering = LTE_T_Reordering_ms40;
-            break;
+            case 40:
+              rrc->srb1_timer_reordering = LTE_T_Reordering_ms40;
+              break;
 
-          case 45:
-            rrc->srb1_timer_reordering = LTE_T_Reordering_ms45;
-            break;
+            case 45:
+              rrc->srb1_timer_reordering = LTE_T_Reordering_ms45;
+              break;
 
-          case 50:
-            rrc->srb1_timer_reordering = LTE_T_Reordering_ms50;
-            break;
+            case 50:
+              rrc->srb1_timer_reordering = LTE_T_Reordering_ms50;
+              break;
 
-          case 55:
-            rrc->srb1_timer_reordering = LTE_T_Reordering_ms55;
-            break;
+            case 55:
+              rrc->srb1_timer_reordering = LTE_T_Reordering_ms55;
+              break;
 
-          case 60:
-            rrc->srb1_timer_reordering = LTE_T_Reordering_ms60;
-            break;
+            case 60:
+              rrc->srb1_timer_reordering = LTE_T_Reordering_ms60;
+              break;
 
-          case 65:
-            rrc->srb1_timer_reordering = LTE_T_Reordering_ms65;
-            break;
+            case 65:
+              rrc->srb1_timer_reordering = LTE_T_Reordering_ms65;
+              break;
 
-          case 70:
-            rrc->srb1_timer_reordering = LTE_T_Reordering_ms70;
-            break;
+            case 70:
+              rrc->srb1_timer_reordering = LTE_T_Reordering_ms70;
+              break;
 
-          case 75:
-            rrc->srb1_timer_reordering = LTE_T_Reordering_ms75;
-            break;
+            case 75:
+              rrc->srb1_timer_reordering = LTE_T_Reordering_ms75;
+              break;
 
-          case 80:
-            rrc->srb1_timer_reordering = LTE_T_Reordering_ms80;
-            break;
+            case 80:
+              rrc->srb1_timer_reordering = LTE_T_Reordering_ms80;
+              break;
 
-          case 85:
-            rrc->srb1_timer_reordering = LTE_T_Reordering_ms85;
-            break;
+            case 85:
+              rrc->srb1_timer_reordering = LTE_T_Reordering_ms85;
+              break;
 
-          case 90:
-            rrc->srb1_timer_reordering = LTE_T_Reordering_ms90;
-            break;
+            case 90:
+              rrc->srb1_timer_reordering = LTE_T_Reordering_ms90;
+              break;
 
-          case 95:
-            rrc->srb1_timer_reordering = LTE_T_Reordering_ms95;
-            break;
+            case 95:
+              rrc->srb1_timer_reordering = LTE_T_Reordering_ms95;
+              break;
 
-          case 100:
-            rrc->srb1_timer_reordering = LTE_T_Reordering_ms100;
-            break;
+            case 100:
+              rrc->srb1_timer_reordering = LTE_T_Reordering_ms100;
+              break;
 
-          case 110:
-            rrc->srb1_timer_reordering = LTE_T_Reordering_ms110;
-            break;
+            case 110:
+              rrc->srb1_timer_reordering = LTE_T_Reordering_ms110;
+              break;
 
-          case 120:
-            rrc->srb1_timer_reordering = LTE_T_Reordering_ms120;
-            break;
+            case 120:
+              rrc->srb1_timer_reordering = LTE_T_Reordering_ms120;
+              break;
 
-          case 130:
-            rrc->srb1_timer_reordering = LTE_T_Reordering_ms130;
-            break;
+            case 130:
+              rrc->srb1_timer_reordering = LTE_T_Reordering_ms130;
+              break;
 
-          case 140:
-            rrc->srb1_timer_reordering = LTE_T_Reordering_ms140;
-            break;
+            case 140:
+              rrc->srb1_timer_reordering = LTE_T_Reordering_ms140;
+              break;
 
-          case 150:
-            rrc->srb1_timer_reordering = LTE_T_Reordering_ms150;
-            break;
+            case 150:
+              rrc->srb1_timer_reordering = LTE_T_Reordering_ms150;
+              break;
 
-          case 160:
-            rrc->srb1_timer_reordering = LTE_T_Reordering_ms160;
-            break;
+            case 160:
+              rrc->srb1_timer_reordering = LTE_T_Reordering_ms160;
+              break;
 
-          case 170:
-            rrc->srb1_timer_reordering = LTE_T_Reordering_ms170;
-            break;
+            case 170:
+              rrc->srb1_timer_reordering = LTE_T_Reordering_ms170;
+              break;
 
-          case 180:
-            rrc->srb1_timer_reordering = LTE_T_Reordering_ms180;
-            break;
+            case 180:
+              rrc->srb1_timer_reordering = LTE_T_Reordering_ms180;
+              break;
 
-          case 190:
-            rrc->srb1_timer_reordering = LTE_T_Reordering_ms190;
-            break;
+            case 190:
+              rrc->srb1_timer_reordering = LTE_T_Reordering_ms190;
+              break;
 
-          case 200:
-            rrc->srb1_timer_reordering = LTE_T_Reordering_ms200;
-            break;
+            case 200:
+              rrc->srb1_timer_reordering = LTE_T_Reordering_ms200;
+              break;
 
-          default:
-            AssertFatal (0,
-                         "Bad config value when parsing eNB configuration file %s, enb %d  srb1_timer_reordering %u!\n",
-                         RC.config_file_name, i, srb1_params.srb1_timer_reordering);
+            default:
+              AssertFatal (0,
+                           "Bad config value when parsing eNB configuration file %s, enb %d  srb1_timer_reordering %u!\n",
+                           RC.config_file_name, i, srb1_params.srb1_timer_reordering);
+            }
+          }
         }
       }
     }
+    memcpy(&rrc->configuration, &RRC_CONFIGURATION_REQ(msg_p), sizeof(RRC_CONFIGURATION_REQ(msg_p)));
   }
+  LOG_I(RRC,"Node type %d \n ", rrc->node_type);
 
   return 0;
 }
 
+int RCconfig_DU_F1(MessageDef *msg_p, uint32_t i) {
+
+  int k;
+
+  paramdef_t ENBSParams[] = ENBSPARAMS_DESC;
+  
+  paramdef_t ENBParams[]  = ENBPARAMS_DESC;
+  paramlist_def_t ENBParamList = {ENB_CONFIG_STRING_ENB_LIST,NULL,0};  
+  
+  config_get( ENBSParams,sizeof(ENBSParams)/sizeof(paramdef_t),NULL); 
+  int num_enbs = ENBSParams[ENB_ACTIVE_ENBS_IDX].numelt;
+  AssertFatal (i<num_enbs,
+   	       "Failed to parse config file no %ith element in %s \n",i, ENB_CONFIG_STRING_ACTIVE_ENBS);
+
+  if (num_enbs>0) {
+    // Output a list of all eNBs.
+    config_getlist( &ENBParamList,ENBParams,sizeof(ENBParams)/sizeof(paramdef_t),NULL); 
+    AssertFatal(ENBParamList.paramarray[i][ENB_ENB_ID_IDX].uptr != NULL,
+		"eNB id %d is not defined in configuration file\n",i);
+
+    F1AP_SETUP_REQ (msg_p).num_cells_available = 0;
+
+    for (k=0; k <num_enbs ; k++) {
+      if (strcmp(ENBSParams[ENB_ACTIVE_ENBS_IDX].strlistptr[k], *(ENBParamList.paramarray[i][ENB_ENB_NAME_IDX].strptr) )== 0) {
+
+        char aprefix[MAX_OPTNAME_SIZE*2 + 8];
+        sprintf(aprefix,"%s.[%i]",ENB_CONFIG_STRING_ENB_LIST,k);
+        paramdef_t PLMNParams[] = PLMNPARAMS_DESC;
+        paramlist_def_t PLMNParamList = {ENB_CONFIG_STRING_PLMN_LIST, NULL, 0};
+        /* map parameter checking array instances to parameter definition array instances */
+        checkedparam_t config_check_PLMNParams [] = PLMNPARAMS_CHECK;
+
+        for (int I = 0; I < sizeof(PLMNParams) / sizeof(paramdef_t); ++I)
+          PLMNParams[I].chkPptr = &(config_check_PLMNParams[I]);
+        config_getlist(&PLMNParamList, PLMNParams, sizeof(PLMNParams)/sizeof(paramdef_t), aprefix);
+
+        paramdef_t SCTPParams[]  = SCTPPARAMS_DESC;
+	
+	      F1AP_SETUP_REQ (msg_p).num_cells_available++;
+
+        F1AP_SETUP_REQ (msg_p).gNB_DU_id        = *(ENBParamList.paramarray[0][ENB_ENB_ID_IDX].uptr);
+        LOG_I(ENB_APP,"F1AP: gNB_DU_id[%d] %ld\n",k,F1AP_SETUP_REQ (msg_p).gNB_DU_id);
+
+        F1AP_SETUP_REQ (msg_p).gNB_DU_name      = strdup(*(ENBParamList.paramarray[0][ENB_ENB_NAME_IDX].strptr));
+        LOG_I(ENB_APP,"F1AP: gNB_DU_name[%d] %s\n",k,F1AP_SETUP_REQ (msg_p).gNB_DU_name);
+
+        F1AP_SETUP_REQ (msg_p).tac[k]              = *ENBParamList.paramarray[i][ENB_TRACKING_AREA_CODE_IDX].uptr;
+        LOG_I(ENB_APP,"F1AP: tac[%d] %d\n",k,F1AP_SETUP_REQ (msg_p).tac[k]);
+
+        F1AP_SETUP_REQ (msg_p).mcc[k]              = *PLMNParamList.paramarray[0][ENB_MOBILE_COUNTRY_CODE_IDX].uptr;
+        LOG_I(ENB_APP,"F1AP: mcc[%d] %d\n",k,F1AP_SETUP_REQ (msg_p).mcc[k]);
+
+        F1AP_SETUP_REQ (msg_p).mnc[k]              = *PLMNParamList.paramarray[0][ENB_MOBILE_NETWORK_CODE_IDX].uptr;
+        LOG_I(ENB_APP,"F1AP: mnc[%d] %d\n",k,F1AP_SETUP_REQ (msg_p).mnc[k]);
+
+        F1AP_SETUP_REQ (msg_p).mnc_digit_length[k] = *PLMNParamList.paramarray[0][ENB_MNC_DIGIT_LENGTH].u8ptr;
+        LOG_I(ENB_APP,"F1AP: mnc_digit_length[%d] %d\n",k,F1AP_SETUP_REQ (msg_p).mnc_digit_length[k]);
+	
+        AssertFatal((F1AP_SETUP_REQ (msg_p).mnc_digit_length[k] == 2) ||
+                    (F1AP_SETUP_REQ (msg_p).mnc_digit_length[k] == 3),
+                    "BAD MNC DIGIT LENGTH %d",
+                    F1AP_SETUP_REQ (msg_p).mnc_digit_length[k]);
+
+	F1AP_SETUP_REQ (msg_p).nr_cellid[k] = (uint64_t)*(ENBParamList.paramarray[i][ENB_NRCELLID_IDX].u64ptr);
+        LOG_I(ENB_APP,"F1AP: nr_cellid[%d] %ld\n",k,F1AP_SETUP_REQ (msg_p).nr_cellid[k]);
+
+        LOG_I(ENB_APP,"F1AP: CU_ip4_address in DU %s\n",RC.mac[k]->eth_params_n.remote_addr);
+        LOG_I(ENB_APP,"FIAP: CU_ip4_address in DU %p, strlen %d\n",F1AP_SETUP_REQ (msg_p).CU_f1_ip_address.ipv4_address,(int)strlen(RC.mac[k]->eth_params_n.remote_addr));
+ 	
+        F1AP_SETUP_REQ (msg_p).CU_f1_ip_address.ipv6 = 0;
+        F1AP_SETUP_REQ (msg_p).CU_f1_ip_address.ipv4 = 1;
+        //strcpy(F1AP_SETUP_REQ (msg_p).CU_f1_ip_address.ipv6_address, "");
+        strcpy(F1AP_SETUP_REQ (msg_p).CU_f1_ip_address.ipv4_address, RC.mac[k]->eth_params_n.remote_addr);
+
+        LOG_I(ENB_APP,"F1AP: DU_ip4_address in DU %s\n",RC.mac[k]->eth_params_n.my_addr);
+        LOG_I(ENB_APP,"FIAP: DU_ip4_address in DU %p, strlen %d\n",F1AP_SETUP_REQ (msg_p).DU_f1_ip_address.ipv4_address,(int)strlen(RC.mac[k]->eth_params_n.my_addr));
+  
+        F1AP_SETUP_REQ (msg_p).DU_f1_ip_address.ipv6 = 0;
+        F1AP_SETUP_REQ (msg_p).DU_f1_ip_address.ipv4 = 1;
+        //strcpy(F1AP_SETUP_REQ (msg_p).DU_f1_ip_address.ipv6_address, "");
+        strcpy(F1AP_SETUP_REQ (msg_p).DU_f1_ip_address.ipv4_address, RC.mac[k]->eth_params_n.my_addr);
+
+        //strcpy(F1AP_SETUP_REQ (msg_p).CU_ip_address[l].ipv6_address,*(F1ParamList.paramarray[l][ENB_CU_IPV6_ADDRESS_IDX].strptr));
+        //F1AP_SETUP_REQ (msg_p).CU_port = RC.mac[k]->eth_params_n.remote_portc; // maybe we dont need it
+      
+        sprintf(aprefix,"%s.[%i].%s",ENB_CONFIG_STRING_ENB_LIST,k,ENB_CONFIG_STRING_SCTP_CONFIG);
+        config_get( SCTPParams,sizeof(SCTPParams)/sizeof(paramdef_t),aprefix); 
+        F1AP_SETUP_REQ (msg_p).sctp_in_streams = (uint16_t)*(SCTPParams[ENB_SCTP_INSTREAMS_IDX].uptr);
+        F1AP_SETUP_REQ (msg_p).sctp_out_streams = (uint16_t)*(SCTPParams[ENB_SCTP_OUTSTREAMS_IDX].uptr);
+
+        eNB_RRC_INST *rrc = RC.rrc[k];
+        // wait until RRC cell information is configured
+        int cell_info_configured=0;
+        do {
+          LOG_I(ENB_APP,"ngran_eNB_DU: Waiting for basic cell configuration\n");
+          usleep(100000);
+          pthread_mutex_lock(&rrc->cell_info_mutex);
+          cell_info_configured = rrc->cell_info_configured;
+          pthread_mutex_unlock(&rrc->cell_info_mutex);
+        } while (cell_info_configured ==0);
+
+
+        rrc->configuration.mcc[0] = F1AP_SETUP_REQ (msg_p).mcc[k];
+        rrc->configuration.mnc[0] = F1AP_SETUP_REQ (msg_p).mnc[k];
+        rrc->configuration.tac    = F1AP_SETUP_REQ (msg_p).tac[k];
+        rrc->nr_cellid = F1AP_SETUP_REQ (msg_p).nr_cellid[k];
+
+        F1AP_SETUP_REQ (msg_p).nr_pci[k]    = rrc->carrier[0].physCellId;
+        F1AP_SETUP_REQ (msg_p).num_ssi[k] = 0;
+
+
+        if (rrc->carrier[0].sib1->tdd_Config) {
+
+          LOG_I(ENB_APP,"ngran_DU: Configuring Cell %d for TDD\n",k);
+          F1AP_SETUP_REQ (msg_p).fdd_flag = 0;
+          F1AP_SETUP_REQ (msg_p).nr_mode_info[k].tdd.nr_arfcn            = freq_to_arfcn10(rrc->carrier[0].sib1->freqBandIndicator,
+        										   rrc->carrier[0].dl_CarrierFreq);
+          // For LTE use scs field to carry prefix type and number of antennas
+          F1AP_SETUP_REQ (msg_p).nr_mode_info[k].tdd.scs                 = (rrc->carrier[0].Ncp<<2)+rrc->carrier[0].p_eNB;;
+          // use nrb field to hold LTE N_RB_DL (0...5)
+          F1AP_SETUP_REQ (msg_p).nr_mode_info[k].tdd.nrb                 = rrc->carrier[0].mib.message.dl_Bandwidth;
+          F1AP_SETUP_REQ (msg_p).nr_mode_info[k].tdd.nrb                 = rrc->carrier[0].mib.message.dl_Bandwidth;
+          F1AP_SETUP_REQ (msg_p).nr_mode_info[k].tdd.num_frequency_bands = 1;
+          F1AP_SETUP_REQ (msg_p).nr_mode_info[k].tdd.nr_band[0]          = rrc->carrier[0].sib1->freqBandIndicator;
+          F1AP_SETUP_REQ (msg_p).nr_mode_info[k].fdd.sul_active          = 0;
+        }
+        else {
+          LOG_I(ENB_APP,"ngran_DU: Configuring Cell %d for FDD\n",k);
+          F1AP_SETUP_REQ (msg_p).fdd_flag = 1;
+          F1AP_SETUP_REQ (msg_p).nr_mode_info[k].fdd.dl_nr_arfcn             = freq_to_arfcn10(rrc->carrier[0].sib1->freqBandIndicator,
+        										       rrc->carrier[0].dl_CarrierFreq);
+          F1AP_SETUP_REQ (msg_p).nr_mode_info[k].fdd.ul_nr_arfcn             = F1AP_SETUP_REQ (msg_p).nr_mode_info[k].fdd.dl_nr_arfcn;
+          // For LTE use scs field to carry prefix type and number of antennas
+          F1AP_SETUP_REQ (msg_p).nr_mode_info[k].fdd.dl_scs                  = (rrc->carrier[0].Ncp<<2)+rrc->carrier[0].p_eNB;;
+          F1AP_SETUP_REQ (msg_p).nr_mode_info[k].fdd.ul_scs                  = rrc->carrier[0].Ncp;
+          // use nrb field to hold LTE N_RB_DL (0...5)
+          F1AP_SETUP_REQ (msg_p).nr_mode_info[k].fdd.ul_nrb                  = rrc->carrier[0].mib.message.dl_Bandwidth;
+          F1AP_SETUP_REQ (msg_p).nr_mode_info[k].fdd.ul_nrb                  = rrc->carrier[0].mib.message.dl_Bandwidth;
+
+          // RK: we need to check there value for FDD's frequency_bands DL/UL
+          F1AP_SETUP_REQ (msg_p).nr_mode_info[k].fdd.ul_num_frequency_bands  = 1;
+          F1AP_SETUP_REQ (msg_p).nr_mode_info[k].fdd.ul_nr_band[0]           = rrc->carrier[0].sib1->freqBandIndicator;
+          F1AP_SETUP_REQ (msg_p).nr_mode_info[k].fdd.dl_num_frequency_bands  = 1;
+          F1AP_SETUP_REQ (msg_p).nr_mode_info[k].fdd.dl_nr_band[0]           = rrc->carrier[0].sib1->freqBandIndicator;
+
+          F1AP_SETUP_REQ (msg_p).nr_mode_info[k].fdd.ul_num_sul_frequency_bands  = 0;
+          F1AP_SETUP_REQ (msg_p).nr_mode_info[k].fdd.ul_nr_sul_band[0]           = rrc->carrier[0].sib1->freqBandIndicator;
+          F1AP_SETUP_REQ (msg_p).nr_mode_info[k].fdd.dl_num_sul_frequency_bands  = 0;
+          F1AP_SETUP_REQ (msg_p).nr_mode_info[k].fdd.dl_nr_sul_band[0]           = rrc->carrier[0].sib1->freqBandIndicator;
+
+          F1AP_SETUP_REQ (msg_p).nr_mode_info[k].fdd.sul_active              = 0;
+        }
+        F1AP_SETUP_REQ (msg_p).measurement_timing_information[k]             = "0";
+        F1AP_SETUP_REQ (msg_p).ranac[k]                                      = 0;
+        F1AP_SETUP_REQ (msg_p).mib[k]                                        = rrc->carrier[0].MIB;
+        F1AP_SETUP_REQ (msg_p).sib1[k]                                       = rrc->carrier[0].SIB1;
+        F1AP_SETUP_REQ (msg_p).mib_length[k]                                 = rrc->carrier[0].sizeof_MIB;
+        F1AP_SETUP_REQ (msg_p).sib1_length[k]                                = rrc->carrier[0].sizeof_SIB1;
+
+        break;
+      } // if
+    } // for
+  } // if
+  return 0;
+}
+
 int RCconfig_gtpu(void ) {
   int               num_enbs                      = 0;
   char             *enb_interface_name_for_S1U    = NULL;
@@ -1816,7 +1962,7 @@ int RCconfig_S1(
 
               default: {
                 LOG_E(S1AP, "Default I-DRX value in conf file is invalid (%i). Should be 32, 64, 128 or 256. \
-                           Default DRX set to 32 in MME configuration\n",
+                             Default DRX set to 32 in MME configuration\n",
                       ccparams_lte.pcch_defaultPagingCycle);
                 S1AP_REGISTER_ENB_REQ(msg_p).default_drx = 0;
               }
@@ -1926,8 +2072,8 @@ int RCconfig_X2(MessageDef *msg_p, uint32_t i) {
   }
 
   AssertFatal(i < ENBSParams[ENB_ACTIVE_ENBS_IDX].numelt,
-              "Failed to parse config file %s, %uth attribute %s \n",
-              RC.config_file_name, i, ENB_CONFIG_STRING_ACTIVE_ENBS);
+    "Failed to parse config file %s, %uth attribute %s \n",
+    RC.config_file_name, i, ENB_CONFIG_STRING_ACTIVE_ENBS);
 
   if (ENBSParams[ENB_ACTIVE_ENBS_IDX].numelt > 0) {
     // Output a list of all eNBs.
@@ -1938,16 +2084,16 @@ int RCconfig_X2(MessageDef *msg_p, uint32_t i) {
 	if (ENBParamList.paramarray[k][ENB_ENB_ID_IDX].uptr == NULL) {
 	  // Calculate a default eNB ID
           if (EPC_MODE_ENABLED) {
-	    uint32_t hash;
-	    hash = s1ap_generate_eNB_id ();
-	    enb_id = k + (hash & 0xFFFF8);
+	  uint32_t hash;
+	  hash = s1ap_generate_eNB_id ();
+	  enb_id = k + (hash & 0xFFFF8);
           } else {
-	    enb_id = k;
+	  enb_id = k;
           }
 	} else {
 	  enb_id = *(ENBParamList.paramarray[k][ENB_ENB_ID_IDX].uptr);
 	}
-	
+
 	// search if in active list
 	for (j = 0; j < ENBSParams[ENB_ACTIVE_ENBS_IDX].numelt; j++) {
 	  if (strcmp(ENBSParams[ENB_ACTIVE_ENBS_IDX].strlistptr[j], *(ENBParamList.paramarray[k][ENB_ENB_NAME_IDX].strptr)) == 0) {
@@ -1955,10 +2101,10 @@ int RCconfig_X2(MessageDef *msg_p, uint32_t i) {
 	    paramlist_def_t PLMNParamList = {ENB_CONFIG_STRING_PLMN_LIST, NULL, 0};
 	    /* map parameter checking array instances to parameter definition array instances */
 	    checkedparam_t config_check_PLMNParams [] = PLMNPARAMS_CHECK;
-	    
+
 	    for (int I = 0; I < sizeof(PLMNParams) / sizeof(paramdef_t); ++I)
 	      PLMNParams[I].chkPptr = &(config_check_PLMNParams[I]);
-	    
+
 	    paramdef_t X2Params[]  = X2PARAMS_DESC;
 	    paramlist_def_t X2ParamList = {ENB_CONFIG_STRING_TARGET_ENB_X2_IP_ADDRESS,NULL,0};
 	    paramdef_t SCTPParams[]  = SCTPPARAMS_DESC;
@@ -1969,7 +2115,7 @@ int RCconfig_X2(MessageDef *msg_p, uint32_t i) {
 	    sprintf(aprefix,"%s.[%i]",ENB_CONFIG_STRING_ENB_LIST,k);
 	    /* Some default/random parameters */
 	    X2AP_REGISTER_ENB_REQ (msg_p).eNB_id = enb_id;
-	    
+
 	    if (strcmp(*(ENBParamList.paramarray[k][ENB_CELL_TYPE_IDX].strptr), "CELL_MACRO_ENB") == 0) {
 	      X2AP_REGISTER_ENB_REQ (msg_p).cell_type = CELL_MACRO_ENB;
 	    } else  if (strcmp(*(ENBParamList.paramarray[k][ENB_CELL_TYPE_IDX].strptr), "CELL_HOME_ENB") == 0) {
@@ -1979,18 +2125,18 @@ int RCconfig_X2(MessageDef *msg_p, uint32_t i) {
 			   "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for cell_type choice: CELL_MACRO_ENB or CELL_HOME_ENB !\n",
 			   RC.config_file_name, i, *(ENBParamList.paramarray[k][ENB_CELL_TYPE_IDX].strptr));
 	    }
-	    
+
 	    X2AP_REGISTER_ENB_REQ (msg_p).eNB_name         = strdup(*(ENBParamList.paramarray[k][ENB_ENB_NAME_IDX].strptr));
 	    X2AP_REGISTER_ENB_REQ (msg_p).tac              = *ENBParamList.paramarray[k][ENB_TRACKING_AREA_CODE_IDX].uptr;
 	    config_getlist(&PLMNParamList, PLMNParams, sizeof(PLMNParams)/sizeof(paramdef_t), aprefix);
-	    
+
 	    if (PLMNParamList.numelt < 1 || PLMNParamList.numelt > 6)
 	      AssertFatal(0, "The number of PLMN IDs must be in [1,6], but is %d\n",
 			  PLMNParamList.numelt);
-	    
+
 	    if (PLMNParamList.numelt > 1)
 	      LOG_W(X2AP, "X2AP currently handles only one PLMN, ignoring the others!\n");
-	    
+
 	    X2AP_REGISTER_ENB_REQ (msg_p).mcc = *PLMNParamList.paramarray[0][ENB_MOBILE_COUNTRY_CODE_IDX].uptr;
 	    X2AP_REGISTER_ENB_REQ (msg_p).mnc = *PLMNParamList.paramarray[0][ENB_MOBILE_NETWORK_CODE_IDX].uptr;
 	    X2AP_REGISTER_ENB_REQ (msg_p).mnc_digit_length = *PLMNParamList.paramarray[0][ENB_MNC_DIGIT_LENGTH].u8ptr;
@@ -2001,7 +2147,7 @@ int RCconfig_X2(MessageDef *msg_p, uint32_t i) {
 	    /* CC params */
 	    config_getlist(&CCsParamList, NULL, 0, aprefix);
 	    X2AP_REGISTER_ENB_REQ (msg_p).num_cc = CCsParamList.numelt;
-	    
+
 	    if (CCsParamList.numelt > 0) {
 	      //char ccspath[MAX_OPTNAME_SIZE*2 + 16];
 	      for (J = 0; J < CCsParamList.numelt ; J++) {
@@ -2011,21 +2157,21 @@ int RCconfig_X2(MessageDef *msg_p, uint32_t i) {
 		X2AP_REGISTER_ENB_REQ (msg_p).downlink_frequency[J] = (uint32_t) ccparams_lte.downlink_frequency;
 		X2AP_REGISTER_ENB_REQ (msg_p).uplink_frequency_offset[J] = (unsigned int) ccparams_lte.uplink_frequency_offset;
 		X2AP_REGISTER_ENB_REQ (msg_p).Nid_cell[J]= ccparams_lte.Nid_cell;
-		
+
 		if (ccparams_lte.Nid_cell>503) {
 		  AssertFatal (0,
 			       "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for Nid_cell choice: 0...503 !\n",
 			       RC.config_file_name, k, ccparams_lte.Nid_cell);
 		}
-		
+
 		X2AP_REGISTER_ENB_REQ (msg_p).N_RB_DL[J]= ccparams_lte.N_RB_DL;
-		
+
 		if ((ccparams_lte.N_RB_DL!=6) && (ccparams_lte.N_RB_DL!=15) && (ccparams_lte.N_RB_DL!=25) && (ccparams_lte.N_RB_DL!=50) && (ccparams_lte.N_RB_DL!=75) && (ccparams_lte.N_RB_DL!=100)) {
 		  AssertFatal (0,
 			       "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for N_RB_DL choice: 6,15,25,50,75,100 !\n",
 			       RC.config_file_name, k, ccparams_lte.N_RB_DL);
 		}
-		
+
 		if (strcmp(ccparams_lte.frame_type, "FDD") == 0) {
 		  X2AP_REGISTER_ENB_REQ (msg_p).frame_type[J] = FDD;
 		} else  if (strcmp(ccparams_lte.frame_type, "TDD") == 0) {
@@ -2035,24 +2181,24 @@ int RCconfig_X2(MessageDef *msg_p, uint32_t i) {
 			       "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for frame_type choice: FDD or TDD !\n",
 			       RC.config_file_name, k, ccparams_lte.frame_type);
 		}
-		
+
 		X2AP_REGISTER_ENB_REQ (msg_p).fdd_earfcn_DL[J] = to_earfcn_DL(ccparams_lte.eutra_band, ccparams_lte.downlink_frequency, ccparams_lte.N_RB_DL);
 		X2AP_REGISTER_ENB_REQ (msg_p).fdd_earfcn_UL[J] = to_earfcn_UL(ccparams_lte.eutra_band, ccparams_lte.downlink_frequency + ccparams_lte.uplink_frequency_offset, ccparams_lte.N_RB_DL);
 	      }
 	    }
-	    
+
 	    sprintf(aprefix,"%s.[%i]",ENB_CONFIG_STRING_ENB_LIST,k);
 	    config_getlist( &X2ParamList,X2Params,sizeof(X2Params)/sizeof(paramdef_t),aprefix);
 	    AssertFatal(X2ParamList.numelt <= X2AP_MAX_NB_ENB_IP_ADDRESS,
 			"value of X2ParamList.numelt %d must be lower than X2AP_MAX_NB_ENB_IP_ADDRESS %d value: reconsider to increase X2AP_MAX_NB_ENB_IP_ADDRESS\n",
 			X2ParamList.numelt,X2AP_MAX_NB_ENB_IP_ADDRESS);
 	    X2AP_REGISTER_ENB_REQ (msg_p).nb_x2 = 0;
-	    
+
 	    for (l = 0; l < X2ParamList.numelt; l++) {
 	      X2AP_REGISTER_ENB_REQ (msg_p).nb_x2 += 1;
 	      strcpy(X2AP_REGISTER_ENB_REQ (msg_p).target_enb_x2_ip_address[l].ipv4_address,*(X2ParamList.paramarray[l][ENB_X2_IPV4_ADDRESS_IDX].strptr));
 	      strcpy(X2AP_REGISTER_ENB_REQ (msg_p).target_enb_x2_ip_address[l].ipv6_address,*(X2ParamList.paramarray[l][ENB_X2_IPV6_ADDRESS_IDX].strptr));
-	      
+
 	      if (strcmp(*(X2ParamList.paramarray[l][ENB_X2_IP_ADDRESS_PREFERENCE_IDX].strptr), "ipv4") == 0) {
 		X2AP_REGISTER_ENB_REQ (msg_p).target_enb_x2_ip_address[l].ipv4 = 1;
 		X2AP_REGISTER_ENB_REQ (msg_p).target_enb_x2_ip_address[l].ipv6 = 0;
@@ -2064,7 +2210,7 @@ int RCconfig_X2(MessageDef *msg_p, uint32_t i) {
 		X2AP_REGISTER_ENB_REQ (msg_p).target_enb_x2_ip_address[l].ipv6 = 1;
 	      }
 	    }
-	    
+
             // timers
             {
               int t_reloc_prep = 0;
@@ -2092,22 +2238,22 @@ int RCconfig_X2(MessageDef *msg_p, uint32_t i) {
 	    X2AP_REGISTER_ENB_REQ (msg_p).sctp_in_streams  = SCTP_IN_STREAMS;
 
             if (EPC_MODE_ENABLED) {
-	      sprintf(aprefix,"%s.[%i].%s",ENB_CONFIG_STRING_ENB_LIST,k,ENB_CONFIG_STRING_SCTP_CONFIG);
-	      config_get( SCTPParams,sizeof(SCTPParams)/sizeof(paramdef_t),aprefix);
-	      X2AP_REGISTER_ENB_REQ (msg_p).sctp_in_streams = (uint16_t)*(SCTPParams[ENB_SCTP_INSTREAMS_IDX].uptr);
-	      X2AP_REGISTER_ENB_REQ (msg_p).sctp_out_streams = (uint16_t)*(SCTPParams[ENB_SCTP_OUTSTREAMS_IDX].uptr);
+	    sprintf(aprefix,"%s.[%i].%s",ENB_CONFIG_STRING_ENB_LIST,k,ENB_CONFIG_STRING_SCTP_CONFIG);
+	    config_get( SCTPParams,sizeof(SCTPParams)/sizeof(paramdef_t),aprefix);
+	    X2AP_REGISTER_ENB_REQ (msg_p).sctp_in_streams = (uint16_t)*(SCTPParams[ENB_SCTP_INSTREAMS_IDX].uptr);
+	    X2AP_REGISTER_ENB_REQ (msg_p).sctp_out_streams = (uint16_t)*(SCTPParams[ENB_SCTP_OUTSTREAMS_IDX].uptr);
             }
 
 	    sprintf(aprefix,"%s.[%i].%s",ENB_CONFIG_STRING_ENB_LIST,k,ENB_CONFIG_STRING_NETWORK_INTERFACES_CONFIG);
 	    // NETWORK_INTERFACES
 	    config_get( NETParams,sizeof(NETParams)/sizeof(paramdef_t),aprefix);
 	    X2AP_REGISTER_ENB_REQ (msg_p).enb_port_for_X2C = (uint32_t)*(NETParams[ENB_PORT_FOR_X2C_IDX].uptr);
-	    
+
 	    if ((NETParams[ENB_IPV4_ADDR_FOR_X2C_IDX].strptr == NULL) || (X2AP_REGISTER_ENB_REQ (msg_p).enb_port_for_X2C == 0)) {
 	      LOG_E(RRC,"Add eNB IPv4 address and/or port for X2C in the CONF file!\n");
 	      exit(1);
 	    }
-	    
+
 	    cidr = *(NETParams[ENB_IPV4_ADDR_FOR_X2C_IDX].strptr);
 	    address = strtok(cidr, "/");
 	    X2AP_REGISTER_ENB_REQ (msg_p).enb_x2_ip_address.ipv6 = 0;
@@ -2158,9 +2304,12 @@ void RCConfig(void) {
   paramlist_def_t MACRLCParamList = {CONFIG_STRING_MACRLC_LIST,NULL,0};
   paramlist_def_t L1ParamList = {CONFIG_STRING_L1_LIST,NULL,0};
   paramlist_def_t RUParamList = {CONFIG_STRING_RU_LIST,NULL,0};
+  
   paramdef_t ENBSParams[] = ENBSPARAMS_DESC;
   paramlist_def_t CCsParamList = {ENB_CONFIG_STRING_COMPONENT_CARRIERS,NULL,0};
-  char aprefix[MAX_OPTNAME_SIZE*2 + 8];
+  
+  char aprefix[MAX_OPTNAME_SIZE*2 + 8];  
+  
   /* get global parameters, defined outside any section in the config file */
   printf("Getting ENBSParams\n");
   config_get( ENBSParams,sizeof(ENBSParams)/sizeof(paramdef_t),NULL);
@@ -2176,15 +2325,301 @@ void RCConfig(void) {
       RC.nb_CC[i]    = CCsParamList.numelt;
     }
   }
-
-  // Get num MACRLC instances
+ 
   config_getlist( &MACRLCParamList,NULL,0, NULL);
   RC.nb_macrlc_inst  = MACRLCParamList.numelt;
+  AssertFatal(RC.nb_macrlc_inst <= MAX_MAC_INST,
+              "Too many macrlc instances %d\n",RC.nb_macrlc_inst);
+
   // Get num L1 instances
   config_getlist( &L1ParamList,NULL,0, NULL);
   RC.nb_L1_inst = L1ParamList.numelt;
+
   // Get num RU instances
   config_getlist( &RUParamList,NULL,0, NULL);
   RC.nb_RU     = RUParamList.numelt;
+ 
   RCconfig_parallel();
 }
+
+int check_plmn_identity(rrc_eNB_carrier_data_t *carrier,uint16_t mcc,uint16_t mnc,uint8_t mnc_digit_length) {
+
+  AssertFatal(carrier->sib1->cellAccessRelatedInfo.plmn_IdentityList.list.count > 0,
+	      "plmn info isn't there\n");
+  AssertFatal(mnc_digit_length ==2 || mnc_digit_length == 3,
+	      "impossible mnc_digit_length %d\n",mnc_digit_length);
+
+  LTE_PLMN_IdentityInfo_t *plmn_Identity_info = carrier->sib1->cellAccessRelatedInfo.plmn_IdentityList.list.array[0];
+
+  // check if mcc is different and return failure if so
+  if (mcc != 
+      (*plmn_Identity_info->plmn_Identity.mcc->list.array[0]*100)+
+      (*plmn_Identity_info->plmn_Identity.mcc->list.array[1]*10) +
+      (*plmn_Identity_info->plmn_Identity.mcc->list.array[2])) return(0);
+
+  // check that mnc digit length is different and return failure if so
+  if (mnc_digit_length != plmn_Identity_info->plmn_Identity.mnc.list.count) return 0;
+
+  // check that 2 digit mnc is different and return failure if so
+  if (mnc_digit_length == 2 &&
+      (mnc !=       
+       (*plmn_Identity_info->plmn_Identity.mnc.list.array[0]*10) +
+       (*plmn_Identity_info->plmn_Identity.mnc.list.array[1]))) return(0);
+  else if (mnc_digit_length == 3 &&
+	   (mnc !=       
+	    (*plmn_Identity_info->plmn_Identity.mnc.list.array[0]*100) +
+	    (*plmn_Identity_info->plmn_Identity.mnc.list.array[1]*10) +
+	    (*plmn_Identity_info->plmn_Identity.mnc.list.array[2]))) return(0);
+
+  // if we're here, the mcc/mnc match so return success
+  return(1);
+
+}
+
+void extract_and_decode_SI(int inst,int si_ind,uint8_t *si_container,int si_container_length) {
+
+  eNB_RRC_INST *rrc = RC.rrc[inst];
+  rrc_eNB_carrier_data_t *carrier = &rrc->carrier[0];
+  LTE_BCCH_DL_SCH_Message_t *bcch_message ;
+
+  AssertFatal(si_ind==0,"Can only handle a single SI block for now\n");
+
+  LOG_I(ENB_APP, "rrc inst %d: Trying to decode SI block %d @ %p, length %d\n",inst,si_ind,si_container,si_container_length);
+  // point to first SI block
+  bcch_message = &carrier->systemInformation;
+  asn_dec_rval_t dec_rval = uper_decode_complete( NULL,
+						  &asn_DEF_LTE_BCCH_DL_SCH_Message,
+						  (void **)&bcch_message,
+						  (const void *)si_container,
+						  si_container_length);
+  
+  if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) {
+    AssertFatal(1==0, "[ENB_APP][RRC inst %"PRIu8"] Failed to decode BCCH_DLSCH_MESSAGE (%zu bits)\n",
+		inst,
+		dec_rval.consumed );
+  }
+  if (bcch_message->message.present == LTE_BCCH_DL_SCH_MessageType_PR_c1) {
+    switch (bcch_message->message.choice.c1.present) {
+    case LTE_BCCH_DL_SCH_MessageType__c1_PR_systemInformationBlockType1:
+      AssertFatal(1==0,"Should have received SIB1 from CU\n");
+      break;
+    case LTE_BCCH_DL_SCH_MessageType__c1_PR_systemInformation:
+      {
+	LTE_SystemInformation_t *si = &bcch_message->message.choice.c1.choice.systemInformation;
+
+
+	for (int i=0; i<si->criticalExtensions.choice.systemInformation_r8.sib_TypeAndInfo.list.count; i++) {
+	  LOG_I(ENB_APP,"Extracting SI %d/%d\n",i,si->criticalExtensions.choice.systemInformation_r8.sib_TypeAndInfo.list.count);
+	  struct LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member *typeandinfo;
+	  typeandinfo = si->criticalExtensions.choice.systemInformation_r8.sib_TypeAndInfo.list.array[i];
+	  
+	  switch(typeandinfo->present) {
+	  case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib2:
+	    carrier->sib2 = &typeandinfo->choice.sib2;
+	    carrier->SIB23 = (uint8_t*)malloc(64);
+	    memcpy((void*)carrier->SIB23,(void*)si_container,si_container_length);
+	    carrier->sizeof_SIB23 = si_container_length;
+	    LOG_I( ENB_APP, "[RRC %"PRIu8"] Found SIB2 in CU F1AP_SETUP_RESP message\n", inst);
+	    break;
+	  case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib3:
+	    carrier->sib3 = &typeandinfo->choice.sib3;
+	    LOG_I( ENB_APP, "[RRC %"PRIu8"] Found SIB3 in CU F1AP_SETUP_RESP message\n", inst);
+	    break;
+	  case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib4:
+	    //carrier->sib4 = &typeandinfo->choice.sib4;
+	    LOG_I( ENB_APP, "[RRC %"PRIu8"] Found SIB4 in CU F1AP_SETUP_RESP message\n", inst);
+	    break;
+	  case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib5:
+	    //carrier->sib5 = &typeandinfo->choice.sib5;
+	    LOG_I( ENB_APP, "[RRC %"PRIu8"] Found SIB5 in CU F1AP_SETUP_RESP message\n", inst);
+	    break;
+	  case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib6:
+	    //carrier->sib6 = &typeandinfo->choice.sib6;
+	    LOG_I( ENB_APP, "[RRC %"PRIu8"] Found SIB6 in CU F1AP_SETUP_RESP message\n", inst);
+	    break;
+	  case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib7:
+	    //carrier->sib7 = &typeandinfo->choice.sib7;
+	    LOG_I( ENB_APP, "[RRC %"PRIu8"] Found SIB7 in CU F1AP_SETUP_RESP message\n", inst);
+	    break;
+	  case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib8:
+	    //carrier->sib8 = &typeandinfo->choice.sib8;
+	    LOG_I( ENB_APP, "[RRC %"PRIu8"] Found SIB8 in CU F1AP_SETUP_RESP message\n", inst);
+	    break;
+	  case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib9:
+	    //carrier->sib9 = &typeandinfo->choice.sib9;
+	    LOG_I( ENB_APP, "[RRC %"PRIu8"] Found SIB9 in CU F1AP_SETUP_RESP message\n", inst);
+	    break;
+	  case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib10:
+	    //carrier->sib10 = &typeandinfo->choice.sib10;
+	    LOG_I( ENB_APP, "[RRC %"PRIu8"] Found SIB10 in CU F1AP_SETUP_RESP message\n", inst);
+	    break;
+	  case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib11:
+	    //carrier->sib11 = &typeandinfo->choice.sib11;
+	    LOG_I( ENB_APP, "[RRC %"PRIu8"] Found SIB11 in CU F1AP_SETUP_RESP message\n", inst);
+	    break;
+	    
+#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 2, 0))
+	    
+	  case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib12_v920:
+	    //carrier->sib12 = &typeandinfo->choice.sib12;
+	    LOG_I( ENB_APP, "[RRC %"PRIu8"] Found SIB12 in CU F1AP_SETUP_RESP message\n", inst);
+	    break;
+	    
+	  case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib13_v920:
+	    carrier->sib13 = &typeandinfo->choice.sib13_v920;
+	    LOG_I( ENB_APP, "[RRC %"PRIu8"] Found SIB13 in CU F1AP_SETUP_RESP message\n", inst);
+	    break;
+#endif
+#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0))
+	    //SIB18
+	  case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib18_v1250:
+	    carrier->sib18 = &typeandinfo->choice.sib18_v1250;
+	    LOG_I( ENB_APP, "[RRC %"PRIu8"] Found SIB18 in CU F1AP_SETUP_RESP message\n", inst);
+	    break;
+	    //SIB19
+	  case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib19_v1250:
+	    carrier->sib19 = &typeandinfo->choice.sib19_v1250;
+	    LOG_I( ENB_APP, "[RRC %"PRIu8"] Found SIB19 in CU F1AP_SETUP_RESP message\n", inst);
+	    break;
+	    //SIB21
+	  case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib21_v1430:
+	    carrier->sib21 = &typeandinfo->choice.sib21_v1430;
+	    LOG_I( ENB_APP, "[RRC %"PRIu8"] Found SIB21 in CU F1AP_SETUP_RESP message\n", inst);
+	    break;
+#endif
+	  default:
+	    AssertFatal(1==0,"Shouldn't have received this SI %d\n",typeandinfo->present);
+	    break;
+	  }
+	}
+	break;
+      }
+      case LTE_BCCH_DL_SCH_MessageType__c1_PR_NOTHING:
+        AssertFatal(0, "Should have received SIB1 from CU\n");
+        break;
+    }
+  }
+    
+  else AssertFatal(1==0,"No SI messages\n");
+
+
+}
+
+void configure_du_mac(int inst) {
+
+  eNB_RRC_INST *rrc = RC.rrc[inst];
+  rrc_eNB_carrier_data_t *carrier = &rrc->carrier[0];
+
+  LOG_I(ENB_APP,"Configuring MAC/L1 %d, carrier->sib2 %p\n",inst,&carrier->sib2->radioResourceConfigCommon);
+
+  rrc_mac_config_req_eNB(inst, 0,
+			 carrier->physCellId,
+			 carrier->p_eNB,
+			 carrier->Ncp,
+			 carrier->sib1->freqBandIndicator,
+			 carrier->dl_CarrierFreq,
+#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
+			 carrier->pbch_repetition,
+#endif
+			 0, // rnti
+			 (LTE_BCCH_BCH_Message_t *) &carrier->mib,
+			 (LTE_RadioResourceConfigCommonSIB_t *) &carrier->sib2->radioResourceConfigCommon,
+#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
+			 (LTE_RadioResourceConfigCommonSIB_t *) &carrier->sib2_BR->radioResourceConfigCommon,
+#endif
+			 (struct LTE_PhysicalConfigDedicated *)NULL,
+#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0))
+			 (LTE_SCellToAddMod_r10_t *)NULL,
+			 //(struct PhysicalConfigDedicatedSCell_r10 *)NULL,
+#endif
+			 (LTE_MeasObjectToAddMod_t **) NULL,
+			 (LTE_MAC_MainConfig_t *) NULL, 0,
+			 (struct LTE_LogicalChannelConfig *)NULL,
+			 (LTE_MeasGapConfig_t *) NULL,
+                         carrier->sib1->tdd_Config,
+			 NULL,
+			 &carrier->sib1->schedulingInfoList,
+			 carrier->ul_CarrierFreq,
+			 carrier->sib2->freqInfo.ul_Bandwidth,
+			 &carrier->sib2->freqInfo.additionalSpectrumEmission,
+			 (LTE_MBSFN_SubframeConfigList_t*) carrier->sib2->mbsfn_SubframeConfigList
+#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0))
+			 ,
+			 carrier->MBMS_flag,
+			 (LTE_MBSFN_AreaInfoList_r9_t*) & carrier->sib13->mbsfn_AreaInfoList_r9,
+			 (LTE_PMCH_InfoList_r9_t *) NULL
+#endif
+#if (LTE_RRC_VERSION >= MAKE_VERSION(13, 0, 0))
+			 , 
+			 NULL
+#endif
+			 );
+  
+}
+
+void handle_f1ap_setup_resp(f1ap_setup_resp_t *resp) {
+
+
+  int i,j,si_ind;
+  LOG_I(ENB_APP, "cells_to_activated %d, RRC instances %d\n",
+	 resp->num_cells_to_activate,RC.nb_inst);
+  for (j=0;j<resp->num_cells_to_activate;j++) {
+    for (i=0;i<RC.nb_inst;i++) {
+      rrc_eNB_carrier_data_t *carrier =  &RC.rrc[i]->carrier[0];
+      // identify local index of cell j by nr_cellid, plmn identity and physical cell ID
+      LOG_I(ENB_APP, "Checking cell %d, rrc inst %d : rrc->nr_cellid %lx, resp->nr_cellid %lx\n",
+	     j,i,RC.rrc[i]->nr_cellid,resp->nr_cellid[j]);
+      if (RC.rrc[i]->nr_cellid == resp->nr_cellid[j] && 
+	  (check_plmn_identity(carrier, resp->mcc[j], resp->mnc[j], resp->mnc_digit_length[j])>0 &&
+	   resp->nrpci[j] == carrier->physCellId)) {
+	// copy system information and decode it 
+	for (si_ind=0;si_ind<resp->num_SI[j];si_ind++)  {
+          //printf("SI %d size %d: ", si_ind, resp->SI_container_length[j][si_ind]);
+          //for (int n=0;n<resp->SI_container_length[j][si_ind];n++)
+          //  printf("%02x ",resp->SI_container[j][si_ind][n]);
+          //printf("\n");
+	  extract_and_decode_SI(i,
+				si_ind,
+				resp->SI_container[j][si_ind],
+				resp->SI_container_length[j][si_ind]);
+	}
+	// perform MAC/L1 common configuration
+	configure_du_mac(i);
+      } else {
+        LOG_E(ENB_APP, "F1 Setup Response not matching\n");
+      }
+    }
+  }
+}
+
+void read_config_and_init(void)
+{
+  int macrlc_has_f1[MAX_MAC_INST];
+  memset(macrlc_has_f1, 0 , MAX_MAC_INST*sizeof(int));
+
+  if (RC.nb_macrlc_inst > 0)
+    AssertFatal(RC.nb_macrlc_inst == RC.nb_inst,
+                "Number of MACRLC instances %d != number of RRC instances %d\n",
+                RC.nb_macrlc_inst, RC.nb_inst);
+
+  RCconfig_L1();
+  LOG_I(PHY, "%s() RC.nb_L1_inst: %d\n", __FUNCTION__, RC.nb_L1_inst);
+
+  RCconfig_macrlc(macrlc_has_f1);
+  LOG_I(MAC, "%s() RC.nb_macrlc_inst: %d\n", __FUNCTION__, RC.nb_macrlc_inst);
+
+  if (RC.nb_L1_inst > 0)
+    AssertFatal(l1_north_init_eNB() == 0, "could not initialize L1 north interface\n");
+
+  RC.rrc = malloc(RC.nb_inst * sizeof(eNB_RRC_INST *));
+  AssertFatal(RC.rrc, "could not allocate memory for RC.rrc\n");
+  for (uint32_t enb_id = 0; enb_id < RC.nb_inst; enb_id++) {
+    RC.rrc[enb_id] = malloc(sizeof(eNB_RRC_INST));
+    AssertFatal(RC.rrc[enb_id], "RRC context for eNB %d not allocated\n", enb_id);
+    memset((void *)RC.rrc[enb_id], 0, sizeof(eNB_RRC_INST));
+    RCconfig_RRC(enb_id, RC.rrc[enb_id],macrlc_has_f1[enb_id]);
+  }
+
+  if (!NODE_IS_DU(RC.rrc[0]->node_type))
+    pdcp_layer_init();
+}
diff --git a/openair2/ENB_APP/enb_config.h b/openair2/ENB_APP/enb_config.h
index 0edb84039ba9b5ea3f5c3b0ba08aedbe0da63995..a204a47652f6292858e9080b5a61fe3c93652fe9 100644
--- a/openair2/ENB_APP/enb_config.h
+++ b/openair2/ENB_APP/enb_config.h
@@ -40,6 +40,7 @@
 #include "PHY/impl_defs_lte.h"
 #include "PHY/defs_eNB.h"
 #include "s1ap_messages_types.h"
+#include "f1ap_messages_types.h"
 #include "LTE_SystemInformationBlockType2.h"
 #include "rrc_messages_types.h"
 #include "RRC/LTE/rrc_defs.h"
@@ -63,6 +64,9 @@
 // Hard to find a defined value for max enb...
 #define MAX_ENB 16
 
+#define MAX_DU	4
+#define CU_BALANCING_ALL		127
+#define CU_BALANCING_ROUND_ROBIN	126
 
 typedef struct mme_ip_address_s {
   unsigned  ipv4:1;
@@ -72,6 +76,13 @@ typedef struct mme_ip_address_s {
   char     *ipv6_address;
 } mme_ip_address_t;
 
+typedef struct cu_params {
+  const char    *local_ipv4_address;
+  const uint16_t local_port;
+  const char    *remote_ipv4_address;
+  const int16_t  remote_port;
+} cudu_params_t;
+
 typedef struct ru_config_s {
   // indicates if local or remote rf is used (1 == LOCAL)
   unsigned  local_rf:1;
@@ -93,7 +104,7 @@ typedef struct ru_config_s {
 extern void RCconfig_RU(void);
 extern void RCconfig_flexran(void);
 extern void RCconfig_L1(void);
-extern void RCconfig_macrlc(void);
+extern void RCconfig_macrlc(int macrlc_has_f1[MAX_MAC_INST]);
 extern void UE_config_stub_pnf(void);
 extern int  RCconfig_gtpu(void );
 extern void RCConfig(void);
@@ -101,12 +112,17 @@ extern void RCConfig(void);
 void                          enb_config_display(void);
 void                          ru_config_display(void);
 
-int RCconfig_RRC(MessageDef *msg_p, uint32_t i, eNB_RRC_INST *rrc);
+int RCconfig_RRC(uint32_t i, eNB_RRC_INST *rrc, int macrlc_has_f1);
 int RCconfig_S1(MessageDef *msg_p, uint32_t i);
+
+void read_config_and_init(void);
 int RCconfig_X2(MessageDef *msg_p, uint32_t i);
 
 void fill_SL_configuration(MessageDef *msg_p,  ccparams_sidelink_t *SLconfig,int cell_idx,int cc_idx,char *config_fname);
 void fill_eMTC_configuration(MessageDef *msg_p,  ccparams_eMTC_t *eMTCconfig, int cell_idx,int cc_idx,char *config_fname,char *brparamspath);
 
+int RCconfig_DU_F1(MessageDef *msg_p, uint32_t i);
+void handle_f1ap_setup_resp(f1ap_setup_resp_t *resp);
+
 #endif /* ENB_CONFIG_H_ */
 /** @} */
diff --git a/openair2/ENB_APP/enb_config_SL.c b/openair2/ENB_APP/enb_config_SL.c
index e9f2515f81603abebc44a0aeb5e5f955057c7589..aecede2db8da25fe465e53f5129a4aec16c2e615 100644
--- a/openair2/ENB_APP/enb_config_SL.c
+++ b/openair2/ENB_APP/enb_config_SL.c
@@ -39,7 +39,7 @@
 #include "RRC_config_tools.h"
 #include "enb_paramdef.h"
 #include "enb_paramdef_sidelink.h"
- 
+
 void fill_SL_configuration(MessageDef *msg_p,  ccparams_sidelink_t *SLconfig,int cell_idx,int cc_idx,char *config_fname) {
 
   printf("Configuring SL\n");
@@ -52,7 +52,7 @@ void fill_SL_configuration(MessageDef *msg_p,  ccparams_sidelink_t *SLconfig,int
     AssertFatal (0,
 		 "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for rxPool_sc_CP_Len choice: normal,extended!\n",
 		 config_fname, cell_idx, SLconfig->rxPool_sc_CP_Len);
-	      
+
   if (strcmp(SLconfig->rxPool_sc_Period,"sf40")==0) {
     RRC_CONFIGURATION_REQ (msg_p).rxPool_sc_Period[cc_idx] = LTE_SL_PeriodComm_r12_sf40;
   } else if (strcmp(SLconfig->rxPool_sc_Period,"sf60")==0) {
@@ -89,7 +89,7 @@ void fill_SL_configuration(MessageDef *msg_p,  ccparams_sidelink_t *SLconfig,int
     AssertFatal (0,
 		 "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for rxPool_sc_Period choice: sf40,sf60,sf70,sf80,sf120,sf140,sf160,sf240,sf280,sf320,spare6,spare5,spare4,spare3,spare2,spare!\n",
 		 config_fname, cell_idx, SLconfig->rxPool_sc_Period);
-	      
+
   if (strcmp(SLconfig->rxPool_data_CP_Len,"normal")==0) {
     RRC_CONFIGURATION_REQ (msg_p).rxPool_data_CP_Len[cc_idx] = LTE_SL_CP_Len_r12_normal;
   } else if (strcmp(SLconfig->rxPool_data_CP_Len,"extended")==0) {
@@ -98,11 +98,11 @@ void fill_SL_configuration(MessageDef *msg_p,  ccparams_sidelink_t *SLconfig,int
     AssertFatal (0,
 		 "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for rxPool_data_CP_Len choice: normal,extended!\n",
 		 config_fname, cell_idx, SLconfig->rxPool_data_CP_Len);
-	      
+
   RRC_CONFIGURATION_REQ (msg_p).rxPool_ResourceConfig_prb_Num[cc_idx] = SLconfig->rxPool_ResourceConfig_prb_Num;
   RRC_CONFIGURATION_REQ (msg_p).rxPool_ResourceConfig_prb_Start[cc_idx] = SLconfig->rxPool_ResourceConfig_prb_Start;
   RRC_CONFIGURATION_REQ (msg_p).rxPool_ResourceConfig_prb_End[cc_idx] = SLconfig->rxPool_ResourceConfig_prb_End;
-	      
+
   if (strcmp(SLconfig->rxPool_ResourceConfig_offsetIndicator_present,"prNothing")==0) {
     RRC_CONFIGURATION_REQ (msg_p).rxPool_ResourceConfig_offsetIndicator_present[cc_idx] = LTE_SL_OffsetIndicator_r12_PR_NOTHING;
   } else if (strcmp(SLconfig->rxPool_ResourceConfig_offsetIndicator_present,"prSmall")==0) {
@@ -113,9 +113,9 @@ void fill_SL_configuration(MessageDef *msg_p,  ccparams_sidelink_t *SLconfig,int
     AssertFatal (0,
 		 "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for rxPool_ResourceConfig_offsetIndicator_present choice: prNothing,prSmal,prLarge!\n",
 		 config_fname, cell_idx, SLconfig->rxPool_ResourceConfig_offsetIndicator_present);
-	      
+
   RRC_CONFIGURATION_REQ (msg_p).rxPool_ResourceConfig_offsetIndicator_choice[cc_idx] = SLconfig->rxPool_ResourceConfig_offsetIndicator_choice;
-	      
+
   if (strcmp(SLconfig->rxPool_ResourceConfig_subframeBitmap_present,"prNothing")==0) {
     RRC_CONFIGURATION_REQ (msg_p).rxPool_ResourceConfig_subframeBitmap_present[cc_idx] = LTE_SubframeBitmapSL_r12_PR_NOTHING;
   } else if (strcmp(SLconfig->rxPool_ResourceConfig_subframeBitmap_present,"prBs4")==0) {
@@ -136,11 +136,11 @@ void fill_SL_configuration(MessageDef *msg_p,  ccparams_sidelink_t *SLconfig,int
     AssertFatal (0,
 		 "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for rxPool_ResourceConfig_subframeBitmap_present choice: prNothing,prBs4,prBs8,prBs12,prBs16,prBs30,prBs40,prBs42!\n",
 		 config_fname, cell_idx, SLconfig->rxPool_ResourceConfig_subframeBitmap_present);
-	      
+
   RRC_CONFIGURATION_REQ (msg_p).rxPool_ResourceConfig_subframeBitmap_choice_bs_buf[cc_idx] = SLconfig->rxPool_ResourceConfig_subframeBitmap_choice_bs_buf;
   RRC_CONFIGURATION_REQ (msg_p).rxPool_ResourceConfig_subframeBitmap_choice_bs_size[cc_idx] = SLconfig->rxPool_ResourceConfig_subframeBitmap_choice_bs_size;
   RRC_CONFIGURATION_REQ (msg_p).rxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused[cc_idx] = SLconfig->rxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused;
-	      
+
   //SIB19 - for discRxPool
   if (strcmp(SLconfig->discRxPool_cp_Len,"normal")==0) {
     RRC_CONFIGURATION_REQ (msg_p).discRxPool_cp_Len[cc_idx] = LTE_SL_CP_Len_r12_normal;
@@ -150,7 +150,7 @@ void fill_SL_configuration(MessageDef *msg_p,  ccparams_sidelink_t *SLconfig,int
     AssertFatal (0,
 		 "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for discRxPool_cp_Len choice: normal,extended!\n",
 		 config_fname, cell_idx, SLconfig->discRxPool_cp_Len);
-	      
+
   if (strcmp(SLconfig->discRxPool_discPeriod,"rf32")==0) {
     RRC_CONFIGURATION_REQ (msg_p).discRxPool_discPeriod[cc_idx] = LTE_SL_DiscResourcePool_r12__discPeriod_r12_rf32;
   } else if (strcmp(SLconfig->discRxPool_discPeriod,"rf64")==0) {
@@ -171,13 +171,13 @@ void fill_SL_configuration(MessageDef *msg_p,  ccparams_sidelink_t *SLconfig,int
     AssertFatal (0,
 		 "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for discRxPool_discPeriod choice: rf32,rf64,rf128,rf512,rf1024,rf16,spare!\n",
 		 config_fname, cell_idx, SLconfig->discRxPool_discPeriod);
-	      
+
   RRC_CONFIGURATION_REQ (msg_p).discRxPool_numRetx[cc_idx] = SLconfig->discRxPool_numRetx;
   RRC_CONFIGURATION_REQ (msg_p).discRxPool_numRepetition[cc_idx] = SLconfig->discRxPool_numRepetition;
   RRC_CONFIGURATION_REQ (msg_p).discRxPool_ResourceConfig_prb_Num[cc_idx] = SLconfig->discRxPool_ResourceConfig_prb_Num;
   RRC_CONFIGURATION_REQ (msg_p).discRxPool_ResourceConfig_prb_Start[cc_idx] = SLconfig->discRxPool_ResourceConfig_prb_Start;
   RRC_CONFIGURATION_REQ (msg_p).discRxPool_ResourceConfig_prb_End[cc_idx] = SLconfig->discRxPool_ResourceConfig_prb_End;
-	      
+
   if (strcmp(SLconfig->discRxPool_ResourceConfig_offsetIndicator_present,"prNothing")==0) {
     RRC_CONFIGURATION_REQ (msg_p).discRxPool_ResourceConfig_offsetIndicator_present[cc_idx] = LTE_SL_OffsetIndicator_r12_PR_NOTHING;
   } else if (strcmp(SLconfig->discRxPool_ResourceConfig_offsetIndicator_present,"prSmall")==0) {
@@ -188,9 +188,9 @@ void fill_SL_configuration(MessageDef *msg_p,  ccparams_sidelink_t *SLconfig,int
     AssertFatal (0,
 		 "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for discRxPool_ResourceConfig_offsetIndicator_present choice: prNothing,prSmal,prLarge!\n",
 		 config_fname, cell_idx, SLconfig->discRxPool_ResourceConfig_offsetIndicator_present);
-	      
+
   RRC_CONFIGURATION_REQ (msg_p).discRxPool_ResourceConfig_offsetIndicator_choice[cc_idx] = SLconfig->discRxPool_ResourceConfig_offsetIndicator_choice;
-	      
+
   if (strcmp(SLconfig->discRxPool_ResourceConfig_subframeBitmap_present,"prNothing")==0) {
     RRC_CONFIGURATION_REQ (msg_p).discRxPool_ResourceConfig_subframeBitmap_present[cc_idx] = LTE_SubframeBitmapSL_r12_PR_NOTHING;
   } else if (strcmp(SLconfig->discRxPool_ResourceConfig_subframeBitmap_present,"prBs4")==0) {
@@ -211,11 +211,11 @@ void fill_SL_configuration(MessageDef *msg_p,  ccparams_sidelink_t *SLconfig,int
     AssertFatal (0,
 		 "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for discRxPool_ResourceConfig_subframeBitmap_present choice: prNothing,prBs4,prBs8,prBs12,prBs16,prBs30,prBs40,prBs42!\n",
 		 config_fname, cell_idx, SLconfig->discRxPool_ResourceConfig_subframeBitmap_present);
-	      
+
   RRC_CONFIGURATION_REQ (msg_p).discRxPool_ResourceConfig_subframeBitmap_choice_bs_buf[cc_idx] = SLconfig->discRxPool_ResourceConfig_subframeBitmap_choice_bs_buf;
   RRC_CONFIGURATION_REQ (msg_p).discRxPool_ResourceConfig_subframeBitmap_choice_bs_size[cc_idx] = SLconfig->discRxPool_ResourceConfig_subframeBitmap_choice_bs_size;
   RRC_CONFIGURATION_REQ (msg_p).discRxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused[cc_idx] = SLconfig->discRxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused;
-	      
+
   //SIB19 - For discRxPoolPS
   if (strcmp(SLconfig->discRxPoolPS_cp_Len,"normal")==0) {
     RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_cp_Len[cc_idx] = LTE_SL_CP_Len_r12_normal;
@@ -225,7 +225,7 @@ void fill_SL_configuration(MessageDef *msg_p,  ccparams_sidelink_t *SLconfig,int
     AssertFatal (0,
 		 "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for discRxPoolPS_cp_Len choice: normal,extended!\n",
 		 config_fname, cell_idx, SLconfig->discRxPoolPS_cp_Len);
-	      
+
   if (strcmp(SLconfig->discRxPoolPS_discPeriod,"rf32")==0) {
     RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_discPeriod[cc_idx] = LTE_SL_DiscResourcePool_r12__discPeriod_r12_rf32;
   } else if (strcmp(SLconfig->discRxPoolPS_discPeriod,"rf64")==0) {
@@ -246,13 +246,13 @@ void fill_SL_configuration(MessageDef *msg_p,  ccparams_sidelink_t *SLconfig,int
     AssertFatal (0,
 		 "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for discRxPoolPS_discPeriod choice: rf32,rf64,rf128,rf512,rf1024,rf16,spare!\n",
 		 config_fname, cell_idx, SLconfig->discRxPoolPS_discPeriod);
-	      
+
   RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_numRetx[cc_idx] = SLconfig->discRxPoolPS_numRetx;
   RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_numRepetition[cc_idx] = SLconfig->discRxPoolPS_numRepetition;
   RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_ResourceConfig_prb_Num[cc_idx] = SLconfig->discRxPoolPS_ResourceConfig_prb_Num;
   RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_ResourceConfig_prb_Start[cc_idx] = SLconfig->discRxPoolPS_ResourceConfig_prb_Start;
   RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_ResourceConfig_prb_End[cc_idx] = SLconfig->discRxPoolPS_ResourceConfig_prb_End;
-	      
+
   if (strcmp(SLconfig->discRxPoolPS_ResourceConfig_offsetIndicator_present,"prNothing")==0) {
     RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_ResourceConfig_offsetIndicator_present[cc_idx] = LTE_SL_OffsetIndicator_r12_PR_NOTHING;
   } else if (strcmp(SLconfig->discRxPoolPS_ResourceConfig_offsetIndicator_present,"prSmall")==0) {
@@ -263,9 +263,9 @@ void fill_SL_configuration(MessageDef *msg_p,  ccparams_sidelink_t *SLconfig,int
     AssertFatal (0,
 		 "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for discRxPoolPS_ResourceConfig_offsetIndicator_present choice: prNothing,prSmal,prLarge!\n",
 		 config_fname, cell_idx, SLconfig->discRxPoolPS_ResourceConfig_offsetIndicator_present);
-	      
+
   RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_ResourceConfig_offsetIndicator_choice[cc_idx] = SLconfig->discRxPoolPS_ResourceConfig_offsetIndicator_choice;
-	      
+
   if (strcmp(SLconfig->discRxPoolPS_ResourceConfig_subframeBitmap_present,"prNothing")==0) {
     RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_ResourceConfig_subframeBitmap_present[cc_idx] = LTE_SubframeBitmapSL_r12_PR_NOTHING;
   } else if (strcmp(SLconfig->discRxPoolPS_ResourceConfig_subframeBitmap_present,"prBs4")==0) {
@@ -286,7 +286,7 @@ void fill_SL_configuration(MessageDef *msg_p,  ccparams_sidelink_t *SLconfig,int
     AssertFatal (0,
 		 "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for discRxPoolPS_ResourceConfig_subframeBitmap_present choice: prNothing,prBs4,prBs8,prBs12,prBs16,prBs30,prBs40,prBs42!\n",
 		 config_fname, cell_idx, SLconfig->discRxPoolPS_ResourceConfig_subframeBitmap_present);
-	      
+
   RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_buf[cc_idx] = SLconfig->discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_buf;
   RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_size[cc_idx] = SLconfig->discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_size;
   RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_bits_unused[cc_idx] = SLconfig->discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_bits_unused;
diff --git a/openair2/ENB_APP/enb_config_eMTC.c b/openair2/ENB_APP/enb_config_eMTC.c
index f0a829c42487d3126592940b08a33a123591838e..5a8362300e094f99e9be3c344ac64b5d913ac863 100644
--- a/openair2/ENB_APP/enb_config_eMTC.c
+++ b/openair2/ENB_APP/enb_config_eMTC.c
@@ -38,7 +38,7 @@
 #include "common/config/config_userapi.h"
 #include "RRC_config_tools.h"
 #include "enb_paramdef.h"
- 
+
 void fill_eMTC_configuration(MessageDef *msg_p,  ccparams_eMTC_t *eMTCconfig, int cell_idx,int cc_idx,char *config_fname,char *brparamspath) {
 
   paramdef_t schedulingInfoBrParams[] = SI_INFO_BR_DESC(eMTCconfig);
@@ -58,8 +58,8 @@ void fill_eMTC_configuration(MessageDef *msg_p,  ccparams_eMTC_t *eMTCconfig, in
 
   printf("Found parameters for eMTC from %s : %s\n",config_fname,brparamspath);
   RRC_CONFIGURATION_REQ(msg_p).schedulingInfoSIB1_BR_r13[cc_idx] = eMTCconfig->schedulingInfoSIB1_BR_r13;
-  
-  
+
+
   if (!strcmp(eMTCconfig->cellSelectionInfoCE_r13, "ENABLE")) {
     RRC_CONFIGURATION_REQ(msg_p).cellSelectionInfoCE_r13[cc_idx] = TRUE;
     RRC_CONFIGURATION_REQ(msg_p).q_RxLevMinCE_r13[cc_idx]= eMTCconfig->q_RxLevMinCE_r13;
@@ -68,14 +68,14 @@ void fill_eMTC_configuration(MessageDef *msg_p,  ccparams_eMTC_t *eMTCconfig, in
   } else {
     RRC_CONFIGURATION_REQ(msg_p).cellSelectionInfoCE_r13[cc_idx] = FALSE;
   }
-  
-	      
-	      
+
+
+
   if (!strcmp(eMTCconfig->bandwidthReducedAccessRelatedInfo_r13, "ENABLE")) {
     RRC_CONFIGURATION_REQ(msg_p).bandwidthReducedAccessRelatedInfo_r13[cc_idx] = TRUE;
-		
-		
-		
+
+
+
     if (!strcmp(eMTCconfig->si_WindowLength_BR_r13, "ms20")) {
       RRC_CONFIGURATION_REQ(msg_p).si_WindowLength_BR_r13[cc_idx] = 0;
     } else if (!strcmp(eMTCconfig->si_WindowLength_BR_r13, "ms40")) {
@@ -93,8 +93,8 @@ void fill_eMTC_configuration(MessageDef *msg_p,  ccparams_eMTC_t *eMTCconfig, in
     } else if (!strcmp(eMTCconfig->si_WindowLength_BR_r13, "spare")) {
       RRC_CONFIGURATION_REQ(msg_p).si_WindowLength_BR_r13[cc_idx] = 7;
     }
-		
-		
+
+
     if (!strcmp(eMTCconfig->si_RepetitionPattern_r13, "everyRF")) {
       RRC_CONFIGURATION_REQ(msg_p).si_RepetitionPattern_r13[cc_idx] = 0;
     } else if (!strcmp(eMTCconfig->si_RepetitionPattern_r13, "every2ndRF")) {
@@ -104,11 +104,11 @@ void fill_eMTC_configuration(MessageDef *msg_p,  ccparams_eMTC_t *eMTCconfig, in
     } else if (!strcmp(eMTCconfig->si_RepetitionPattern_r13, "every8thRF")) {
       RRC_CONFIGURATION_REQ(msg_p).si_RepetitionPattern_r13[cc_idx] = 3;
     }
-		
+
   } else {
     RRC_CONFIGURATION_REQ(msg_p).bandwidthReducedAccessRelatedInfo_r13[cc_idx] = FALSE;
   }
-	      
+
   char schedulingInfoBrPath[MAX_OPTNAME_SIZE * 2];
   config_getlist(&schedulingInfoBrParamList, NULL, 0, brparamspath);
   RRC_CONFIGURATION_REQ (msg_p).scheduling_info_br_size[cc_idx] = schedulingInfoBrParamList.numelt;
@@ -119,12 +119,12 @@ void fill_eMTC_configuration(MessageDef *msg_p,  ccparams_eMTC_t *eMTCconfig, in
     RRC_CONFIGURATION_REQ (msg_p).si_Narrowband_r13[cc_idx][siInfoindex] = eMTCconfig->si_Narrowband_r13;
     RRC_CONFIGURATION_REQ (msg_p).si_TBS_r13[cc_idx][siInfoindex] = eMTCconfig->si_TBS_r13;
   }
-	      
-	      
-	      
+
+
+
   //                        RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[cc_idx].system_info_value_tag_SI_size[cc_idx] = 0;
-	      
-	      
+
+
   RRC_CONFIGURATION_REQ(msg_p).fdd_DownlinkOrTddSubframeBitmapBR_r13[cc_idx] = CALLOC(1, sizeof(BOOLEAN_t));
   if (!strcmp(eMTCconfig->fdd_DownlinkOrTddSubframeBitmapBR_r13, "subframePattern40-r13")) {
     *RRC_CONFIGURATION_REQ(msg_p).fdd_DownlinkOrTddSubframeBitmapBR_r13[cc_idx] = FALSE;
@@ -133,17 +133,17 @@ void fill_eMTC_configuration(MessageDef *msg_p,  ccparams_eMTC_t *eMTCconfig, in
     *RRC_CONFIGURATION_REQ(msg_p).fdd_DownlinkOrTddSubframeBitmapBR_r13[cc_idx] = TRUE;
     RRC_CONFIGURATION_REQ(msg_p).fdd_DownlinkOrTddSubframeBitmapBR_val_r13[cc_idx] = eMTCconfig->fdd_DownlinkOrTddSubframeBitmapBR_val_r13;
   }
-	      
+
   RRC_CONFIGURATION_REQ(msg_p).startSymbolBR_r13[cc_idx] = eMTCconfig->startSymbolBR_r13;
-	      
-	      
+
+
   if (!strcmp(eMTCconfig->si_HoppingConfigCommon_r13, "off")) {
     RRC_CONFIGURATION_REQ(msg_p).si_HoppingConfigCommon_r13[cc_idx] = 1;
   } else if (!strcmp(eMTCconfig->si_HoppingConfigCommon_r13, "on")) {
     RRC_CONFIGURATION_REQ(msg_p).si_HoppingConfigCommon_r13[cc_idx] = 0;
   }
-	      
-	      
+
+
   RRC_CONFIGURATION_REQ(msg_p).si_ValidityTime_r13[cc_idx] = calloc(1, sizeof(long));
   if (!strcmp(eMTCconfig->si_ValidityTime_r13, "true")) {
     *RRC_CONFIGURATION_REQ(msg_p).si_ValidityTime_r13[cc_idx] = 0;
@@ -152,24 +152,24 @@ void fill_eMTC_configuration(MessageDef *msg_p,  ccparams_eMTC_t *eMTCconfig, in
 		"Failed to parse eNB configuration file %s, enb %d  si_ValidityTime_r13 unknown value!\n",
 		config_fname, cell_idx);
   }
-	      
-	      
+
+
   if (!strcmp(eMTCconfig->freqHoppingParametersDL_r13, "ENABLE"))
     {
       RRC_CONFIGURATION_REQ(msg_p).freqHoppingParametersDL_r13[cc_idx] = TRUE;
-		  
+
       if (!strcmp(eMTCconfig->interval_DLHoppingConfigCommonModeA_r13, "interval-TDD-r13"))
 	RRC_CONFIGURATION_REQ(msg_p).interval_DLHoppingConfigCommonModeA_r13[cc_idx] = FALSE;
       else
 	RRC_CONFIGURATION_REQ(msg_p).interval_DLHoppingConfigCommonModeA_r13[cc_idx] = TRUE;
       RRC_CONFIGURATION_REQ(msg_p).interval_DLHoppingConfigCommonModeA_r13_val[cc_idx] = eMTCconfig->interval_DLHoppingConfigCommonModeA_r13_val;
-		  
+
       if (!strcmp(eMTCconfig->interval_DLHoppingConfigCommonModeB_r13, "interval-TDD-r13"))
 	RRC_CONFIGURATION_REQ(msg_p).interval_DLHoppingConfigCommonModeB_r13[cc_idx] = FALSE;
       else
 	RRC_CONFIGURATION_REQ(msg_p).interval_DLHoppingConfigCommonModeB_r13[cc_idx] = TRUE;
       RRC_CONFIGURATION_REQ(msg_p).interval_DLHoppingConfigCommonModeB_r13_val[cc_idx] = eMTCconfig->interval_DLHoppingConfigCommonModeB_r13_val;
-		  
+
       RRC_CONFIGURATION_REQ(msg_p).mpdcch_pdsch_HoppingNB_r13[cc_idx] = calloc(1, sizeof(long));
       if (!strcmp(eMTCconfig->mpdcch_pdsch_HoppingNB_r13, "nb2")) {
 	*RRC_CONFIGURATION_REQ(msg_p).mpdcch_pdsch_HoppingNB_r13[cc_idx] = 0;
@@ -184,30 +184,30 @@ void fill_eMTC_configuration(MessageDef *msg_p,  ccparams_eMTC_t *eMTCconfig, in
 
       RRC_CONFIGURATION_REQ(msg_p).mpdcch_pdsch_HoppingOffset_r13[cc_idx] = calloc(1, sizeof(long));
       *RRC_CONFIGURATION_REQ(msg_p).mpdcch_pdsch_HoppingOffset_r13[cc_idx] = eMTCconfig->mpdcch_pdsch_HoppingOffset_r13;
-		  
+
     }
   else
     {
       RRC_CONFIGURATION_REQ(msg_p).freqHoppingParametersDL_r13[cc_idx] = FALSE;
     }
-	      
+
   /** ------------------------------SIB2/3 BR------------------------------------------ */
-	      
-	      
+
+
   RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].prach_root =  eMTCconfig->ccparams.prach_root;
-	      
+
   if ((eMTCconfig->ccparams.prach_root <0) || (eMTCconfig->ccparams.prach_root > 1023))
     AssertFatal (0,
 		 "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for prach_root choice: 0..1023 !\n",
 		 config_fname, cell_idx,eMTCconfig->ccparams.prach_root);
-	      
+
   RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].prach_config_index = eMTCconfig->ccparams.prach_config_index;
-	      
+
   if ((eMTCconfig->ccparams.prach_config_index <0) || (eMTCconfig->ccparams.prach_config_index > 63))
     AssertFatal (0,
 		 "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for prach_config_index choice: 0..1023 !\n",
 		 config_fname, cell_idx,eMTCconfig->ccparams.prach_config_index);
-	      
+
   if (!eMTCconfig->ccparams.prach_high_speed)
     AssertFatal (0,
 		 "Failed to parse eNB configuration file %s, enb %d define %s: ENABLE,DISABLE!\n",
@@ -220,71 +220,71 @@ void fill_eMTC_configuration(MessageDef *msg_p,  ccparams_eMTC_t *eMTCconfig, in
     AssertFatal (0,
 		 "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for prach_config choice: ENABLE,DISABLE !\n",
 		 config_fname, cell_idx,eMTCconfig->ccparams.prach_high_speed);
-	      
+
   RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].prach_zero_correlation = eMTCconfig->ccparams.prach_zero_correlation;
-	      
+
   if ((eMTCconfig->ccparams.prach_zero_correlation <0) || (eMTCconfig->ccparams.prach_zero_correlation > 15))
     AssertFatal (0,
 		 "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for prach_zero_correlation choice: 0..15!\n",
 		 config_fname, cell_idx,eMTCconfig->ccparams.prach_zero_correlation);
-	      
+
   RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].prach_freq_offset = eMTCconfig->ccparams.prach_freq_offset;
-	      
+
   if ((eMTCconfig->ccparams.prach_freq_offset <0) || (eMTCconfig->ccparams.prach_freq_offset > 94))
     AssertFatal (0,
 		 "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for prach_freq_offset choice: 0..94!\n",
 		 config_fname, cell_idx,eMTCconfig->ccparams.prach_freq_offset);
-	      
+
   RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].pucch_delta_shift = eMTCconfig->ccparams.pucch_delta_shift-1;
-	      
+
   if ((eMTCconfig->ccparams.pucch_delta_shift <1) || (eMTCconfig->ccparams.pucch_delta_shift > 3))
     AssertFatal (0,
 		 "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for pucch_delta_shift choice: 1..3!\n",
 		 config_fname, cell_idx,eMTCconfig->ccparams.pucch_delta_shift);
-	      
+
   RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].pucch_nRB_CQI = eMTCconfig->ccparams.pucch_nRB_CQI;
-	      
+
   if ((eMTCconfig->ccparams.pucch_nRB_CQI <0) || (eMTCconfig->ccparams.pucch_nRB_CQI > 98))
     AssertFatal (0,
 		 "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for pucch_nRB_CQI choice: 0..98!\n",
 		 config_fname, cell_idx,eMTCconfig->ccparams.pucch_nRB_CQI);
-	      
+
   RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].pucch_nCS_AN = eMTCconfig->ccparams.pucch_nCS_AN;
-	      
+
   if ((eMTCconfig->ccparams.pucch_nCS_AN <0) || (eMTCconfig->ccparams.pucch_nCS_AN > 7))
     AssertFatal (0,
 		 "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for pucch_nCS_AN choice: 0..7!\n",
 		 config_fname, cell_idx,eMTCconfig->ccparams.pucch_nCS_AN);
-	      
+
   RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].pucch_n1_AN = eMTCconfig->ccparams.pucch_n1_AN;
-	      
+
   if ((eMTCconfig->ccparams.pucch_n1_AN <0) || (eMTCconfig->ccparams.pucch_n1_AN > 2047))
     AssertFatal (0,
 		 "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for pucch_n1_AN choice: 0..2047!\n",
 		 config_fname, cell_idx,eMTCconfig->ccparams.pucch_n1_AN);
-	      
+
   //#endif
   RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].pdsch_referenceSignalPower = eMTCconfig->ccparams.pdsch_referenceSignalPower;
-	      
+
   if ((eMTCconfig->ccparams.pdsch_referenceSignalPower <-60) || (eMTCconfig->ccparams.pdsch_referenceSignalPower > 50))
     AssertFatal (0,
 		 "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for pdsch_referenceSignalPower choice:-60..50!\n",
 		 config_fname, cell_idx,eMTCconfig->ccparams.pdsch_referenceSignalPower);
-	      
+
   RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].pdsch_p_b = eMTCconfig->ccparams.pdsch_p_b;
-	      
+
   if ((eMTCconfig->ccparams.pdsch_p_b <0) || (eMTCconfig->ccparams.pdsch_p_b > 3))
     AssertFatal (0,
 		 "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for pdsch_p_b choice: 0..3!\n",
 		 config_fname, cell_idx,eMTCconfig->ccparams.pdsch_p_b);
-	      
+
   RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].pusch_n_SB = eMTCconfig->ccparams.pusch_n_SB;
-	      
+
   if ((eMTCconfig->ccparams.pusch_n_SB <1) || (eMTCconfig->ccparams.pusch_n_SB > 4))
     AssertFatal (0,
 		 "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for pusch_n_SB choice: 1..4!\n",
 		 config_fname, cell_idx,eMTCconfig->ccparams.pusch_n_SB);
-	      
+
   if (!eMTCconfig->ccparams.pusch_hoppingMode)
     AssertFatal (0,
 		 "Failed to parse eNB configuration file %s, enb %d define %s: interSubframe,intraAndInterSubframe!\n",
@@ -297,14 +297,14 @@ void fill_eMTC_configuration(MessageDef *msg_p,  ccparams_eMTC_t *eMTCconfig, in
     AssertFatal (0,
 		 "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for pusch_hoppingMode choice: interSubframe,intraAndInterSubframe!\n",
 		 config_fname, cell_idx,eMTCconfig->ccparams.pusch_hoppingMode);
-	      
+
   RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].pusch_hoppingOffset = eMTCconfig->ccparams.pusch_hoppingOffset;
-	      
+
   if ((eMTCconfig->ccparams.pusch_hoppingOffset<0) || (eMTCconfig->ccparams.pusch_hoppingOffset>98))
     AssertFatal (0,
 		 "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for pusch_hoppingOffset choice: 0..98!\n",
 		 config_fname, cell_idx,eMTCconfig->ccparams.pusch_hoppingMode);
-	      
+
   if (!eMTCconfig->ccparams.pusch_enable64QAM)
     AssertFatal (0,
 		 "Failed to parse eNB configuration file %s, enb %d define %s: ENABLE,DISABLE!\n",
@@ -317,7 +317,7 @@ void fill_eMTC_configuration(MessageDef *msg_p,  ccparams_eMTC_t *eMTCconfig, in
     AssertFatal (0,
 		 "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for pusch_enable64QAM choice: ENABLE,DISABLE!\n",
 		 config_fname, cell_idx,eMTCconfig->ccparams.pusch_enable64QAM);
-	      
+
   if (!eMTCconfig->ccparams.pusch_groupHoppingEnabled)
     AssertFatal (0,
 		 "Failed to parse eNB configuration file %s, enb %d define %s: ENABLE,DISABLE!\n",
@@ -330,14 +330,14 @@ void fill_eMTC_configuration(MessageDef *msg_p,  ccparams_eMTC_t *eMTCconfig, in
     AssertFatal (0,
 		 "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for pusch_groupHoppingEnabled choice: ENABLE,DISABLE!\n",
 		 config_fname, cell_idx,eMTCconfig->ccparams.pusch_groupHoppingEnabled);
-	      
+
   RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].pusch_groupAssignment = eMTCconfig->ccparams.pusch_groupAssignment;
-	      
+
   if ((eMTCconfig->ccparams.pusch_groupAssignment<0)||(eMTCconfig->ccparams.pusch_groupAssignment>29))
     AssertFatal (0,
 		 "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for pusch_groupAssignment choice: 0..29!\n",
 		 config_fname, cell_idx,eMTCconfig->ccparams.pusch_groupAssignment);
-	      
+
   if (!eMTCconfig->ccparams.pusch_sequenceHoppingEnabled)
     AssertFatal (0,
 		 "Failed to parse eNB configuration file %s, enb %d define %s: ENABLE,DISABLE!\n",
@@ -350,14 +350,14 @@ void fill_eMTC_configuration(MessageDef *msg_p,  ccparams_eMTC_t *eMTCconfig, in
     AssertFatal (0,
 		 "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for pusch_sequenceHoppingEnabled choice: ENABLE,DISABLE!\n",
 		 config_fname, cell_idx,eMTCconfig->ccparams.pusch_sequenceHoppingEnabled);
-	      
+
   RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].pusch_nDMRS1= eMTCconfig->ccparams.pusch_nDMRS1;  //cyclic_shift in RRC!
-	      
+
   if ((eMTCconfig->ccparams.pusch_nDMRS1 <0) || (eMTCconfig->ccparams.pusch_nDMRS1>7))
     AssertFatal (0,
 		 "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for pusch_nDMRS1 choice: 0..7!\n",
 		 config_fname, cell_idx,eMTCconfig->ccparams.pusch_nDMRS1);
-	      
+
   if (strcmp(eMTCconfig->ccparams.phich_duration,"NORMAL")==0) {
     RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].phich_duration= LTE_PHICH_Config__phich_Duration_normal;
   } else if (strcmp(eMTCconfig->ccparams.phich_duration,"EXTENDED")==0) {
@@ -366,7 +366,7 @@ void fill_eMTC_configuration(MessageDef *msg_p,  ccparams_eMTC_t *eMTCconfig, in
     AssertFatal (0,
 		 "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for phich_duration choice: NORMAL,EXTENDED!\n",
 		 config_fname, cell_idx,eMTCconfig->ccparams.phich_duration);
-	      
+
   if (strcmp(eMTCconfig->ccparams.phich_resource,"ONESIXTH")==0) {
     RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].phich_resource= LTE_PHICH_Config__phich_Resource_oneSixth ;
   } else if (strcmp(eMTCconfig->ccparams.phich_resource,"HALF")==0) {
@@ -379,11 +379,11 @@ void fill_eMTC_configuration(MessageDef *msg_p,  ccparams_eMTC_t *eMTCconfig, in
     AssertFatal (0,
 		 "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for phich_resource choice: ONESIXTH,HALF,ONE,TWO!\n",
 		 config_fname, cell_idx,eMTCconfig->ccparams.phich_resource);
-	      
+
   printf("phich.resource eMTC %ld (%s), phich.duration eMTC %ld (%s)\n",
 	 RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].phich_resource,eMTCconfig->ccparams.phich_resource,
 	 RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].phich_duration,eMTCconfig->ccparams.phich_duration);
-	      
+
   if (strcmp(eMTCconfig->ccparams.srs_enable, "ENABLE") == 0) {
     RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].srs_enable= TRUE;
   } else if (strcmp(eMTCconfig->ccparams.srs_enable, "DISABLE") == 0) {
@@ -392,21 +392,21 @@ void fill_eMTC_configuration(MessageDef *msg_p,  ccparams_eMTC_t *eMTCconfig, in
     AssertFatal (0,
 		 "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for srs_BandwidthConfig choice: ENABLE,DISABLE !\n",
 		 config_fname, cell_idx,eMTCconfig->ccparams.srs_enable);
-	      
+
   if (RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].srs_enable== TRUE) {
     RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].srs_BandwidthConfig= eMTCconfig->ccparams.srs_BandwidthConfig;
-		
+
     if ((eMTCconfig->ccparams.srs_BandwidthConfig < 0) || (eMTCconfig->ccparams.srs_BandwidthConfig >7))
       AssertFatal (0, "Failed to parse eNB configuration file %s, enb %d unknown value %d for srs_BandwidthConfig choice: 0...7\n",
 		   config_fname, cell_idx,eMTCconfig->ccparams.srs_BandwidthConfig);
-		
+
     RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].srs_SubframeConfig= eMTCconfig->ccparams.srs_SubframeConfig;
-		
+
     if ((eMTCconfig->ccparams.srs_SubframeConfig<0) || (eMTCconfig->ccparams.srs_SubframeConfig>15))
       AssertFatal (0,
 		   "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for srs_SubframeConfig choice: 0..15 !\n",
 		   config_fname, cell_idx,eMTCconfig->ccparams.srs_SubframeConfig);
-		
+
     if (strcmp(eMTCconfig->ccparams.srs_ackNackST, "ENABLE") == 0) {
       RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].srs_ackNackST= TRUE;
     } else if (strcmp(eMTCconfig->ccparams.srs_ackNackST, "DISABLE") == 0) {
@@ -415,7 +415,7 @@ void fill_eMTC_configuration(MessageDef *msg_p,  ccparams_eMTC_t *eMTCconfig, in
       AssertFatal (0,
 		   "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for srs_BandwidthConfig choice: ENABLE,DISABLE !\n",
 		   config_fname, cell_idx,eMTCconfig->ccparams.srs_ackNackST);
-		
+
     if (strcmp(eMTCconfig->ccparams.srs_MaxUpPts, "ENABLE") == 0) {
       RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].srs_MaxUpPts= TRUE;
     } else if (strcmp(eMTCconfig->ccparams.srs_MaxUpPts, "DISABLE") == 0) {
@@ -425,14 +425,14 @@ void fill_eMTC_configuration(MessageDef *msg_p,  ccparams_eMTC_t *eMTCconfig, in
 		   "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for srs_MaxUpPts choice: ENABLE,DISABLE !\n",
 		   config_fname, cell_idx,eMTCconfig->ccparams.srs_MaxUpPts);
   }
-	      
+
   RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].pusch_p0_Nominal= eMTCconfig->ccparams.pusch_p0_Nominal;
-	      
+
   if ((eMTCconfig->ccparams.pusch_p0_Nominal<-126) || (eMTCconfig->ccparams.pusch_p0_Nominal>24))
     AssertFatal (0,
 		 "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for pusch_p0_Nominal choice: -126..24 !\n",
 		 config_fname, cell_idx,eMTCconfig->ccparams.pusch_p0_Nominal);
-	      
+
   if (strcmp(eMTCconfig->ccparams.pusch_alpha,"AL0")==0) {
     RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].pusch_alpha= LTE_Alpha_r12_al0;
   } else if (strcmp(eMTCconfig->ccparams.pusch_alpha,"AL04")==0) {
@@ -450,26 +450,26 @@ void fill_eMTC_configuration(MessageDef *msg_p,  ccparams_eMTC_t *eMTCconfig, in
   } else if (strcmp(eMTCconfig->ccparams.pusch_alpha,"AL1")==0) {
     RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].pusch_alpha= LTE_Alpha_r12_al1;
   }
-	      
+
   else
     AssertFatal (0,
 		 "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for pucch_Alpha choice: AL0,AL04,AL05,AL06,AL07,AL08,AL09,AL1!\n",
 		 config_fname, cell_idx,eMTCconfig->ccparams.pusch_alpha);
-	      
+
   RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].pucch_p0_Nominal= eMTCconfig->ccparams.pucch_p0_Nominal;
-	      
+
   if ((eMTCconfig->ccparams.pucch_p0_Nominal<-127) || (eMTCconfig->ccparams.pucch_p0_Nominal>-96))
     AssertFatal (0,
 		 "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for pucch_p0_Nominal choice: -127..-96 !\n",
 		 config_fname, cell_idx,eMTCconfig->ccparams.pucch_p0_Nominal);
-	      
+
   RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].msg3_delta_Preamble= eMTCconfig->ccparams.msg3_delta_Preamble;
-	      
+
   if ((eMTCconfig->ccparams.msg3_delta_Preamble<-1) || (eMTCconfig->ccparams.msg3_delta_Preamble>6))
     AssertFatal (0,
 		 "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for msg3_delta_Preamble choice: -1..6 !\n",
 		 config_fname, cell_idx,eMTCconfig->ccparams.msg3_delta_Preamble);
-	      
+
   if (strcmp(eMTCconfig->ccparams.pucch_deltaF_Format1,"deltaF_2")==0) {
     RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].pucch_deltaF_Format1= LTE_DeltaFList_PUCCH__deltaF_PUCCH_Format1_deltaF_2;
   } else if (strcmp(eMTCconfig->ccparams.pucch_deltaF_Format1,"deltaF0")==0) {
@@ -480,7 +480,7 @@ void fill_eMTC_configuration(MessageDef *msg_p,  ccparams_eMTC_t *eMTCconfig, in
     AssertFatal (0,
 		 "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for pucch_deltaF_Format1 choice: deltaF_2,dltaF0,deltaF2!\n",
 		 config_fname, cell_idx,eMTCconfig->ccparams.pucch_deltaF_Format1);
-	      
+
   if (strcmp(eMTCconfig->ccparams.pucch_deltaF_Format1b,"deltaF1")==0) {
     RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].pucch_deltaF_Format1b= LTE_DeltaFList_PUCCH__deltaF_PUCCH_Format1b_deltaF1;
   } else if (strcmp(eMTCconfig->ccparams.pucch_deltaF_Format1b,"deltaF3")==0) {
@@ -491,7 +491,7 @@ void fill_eMTC_configuration(MessageDef *msg_p,  ccparams_eMTC_t *eMTCconfig, in
     AssertFatal (0,
 		 "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for pucch_deltaF_Format1b choice: deltaF1,dltaF3,deltaF5!\n",
 		 config_fname, cell_idx,eMTCconfig->ccparams.pucch_deltaF_Format1b);
-	      
+
   if (strcmp(eMTCconfig->ccparams.pucch_deltaF_Format2,"deltaF_2")==0) {
     RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].pucch_deltaF_Format2= LTE_DeltaFList_PUCCH__deltaF_PUCCH_Format2_deltaF_2;
   } else if (strcmp(eMTCconfig->ccparams.pucch_deltaF_Format2,"deltaF0")==0) {
@@ -504,7 +504,7 @@ void fill_eMTC_configuration(MessageDef *msg_p,  ccparams_eMTC_t *eMTCconfig, in
     AssertFatal (0,
 		 "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for pucch_deltaF_Format2 choice: deltaF_2,dltaF0,deltaF1,deltaF2!\n",
 		 config_fname, cell_idx,eMTCconfig->ccparams.pucch_deltaF_Format2);
-	      
+
   if (strcmp(eMTCconfig->ccparams.pucch_deltaF_Format2a,"deltaF_2")==0) {
     RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].pucch_deltaF_Format2a= LTE_DeltaFList_PUCCH__deltaF_PUCCH_Format2a_deltaF_2;
   } else if (strcmp(eMTCconfig->ccparams.pucch_deltaF_Format2a,"deltaF0")==0) {
@@ -515,7 +515,7 @@ void fill_eMTC_configuration(MessageDef *msg_p,  ccparams_eMTC_t *eMTCconfig, in
     AssertFatal (0,
 		 "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for pucch_deltaF_Format2a choice: deltaF_2,dltaF0,deltaF2!\n",
 		 config_fname, cell_idx,eMTCconfig->ccparams.pucch_deltaF_Format2a);
-	      
+
   if (strcmp(eMTCconfig->ccparams.pucch_deltaF_Format2b,"deltaF_2")==0) {
     RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].pucch_deltaF_Format2b= LTE_DeltaFList_PUCCH__deltaF_PUCCH_Format2b_deltaF_2;
   } else if (strcmp(eMTCconfig->ccparams.pucch_deltaF_Format2b,"deltaF0")==0) {
@@ -526,47 +526,47 @@ void fill_eMTC_configuration(MessageDef *msg_p,  ccparams_eMTC_t *eMTCconfig, in
     AssertFatal (0,
 		 "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for pucch_deltaF_Format2b choice: deltaF_2,dltaF0,deltaF2!\n",
 		 config_fname, cell_idx,eMTCconfig->ccparams.pucch_deltaF_Format2b);
-	      
+
   RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].rach_numberOfRA_Preambles= (eMTCconfig->ccparams.rach_numberOfRA_Preambles/4)-1;
-	      
+
   if ((eMTCconfig->ccparams.rach_numberOfRA_Preambles <4) || (eMTCconfig->ccparams.rach_numberOfRA_Preambles >64) || ((eMTCconfig->ccparams.rach_numberOfRA_Preambles&3)!=0))
     AssertFatal (0,
 		 "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for rach_numberOfRA_Preambles choice: 4,8,12,...,64!\n",
 		 config_fname, cell_idx,eMTCconfig->ccparams.rach_numberOfRA_Preambles);
-	      
+
   if (strcmp(eMTCconfig->ccparams.rach_preamblesGroupAConfig, "ENABLE") == 0) {
     RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].rach_preamblesGroupAConfig= TRUE;
     RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].rach_sizeOfRA_PreamblesGroupA= (eMTCconfig->ccparams.rach_sizeOfRA_PreamblesGroupA/4)-1;
-		
+
     if ((eMTCconfig->ccparams.rach_numberOfRA_Preambles <4) || (eMTCconfig->ccparams.rach_numberOfRA_Preambles>60) || ((eMTCconfig->ccparams.rach_numberOfRA_Preambles&3)!=0))
       AssertFatal (0,
 		   "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for rach_sizeOfRA_PreamblesGroupA choice: 4,8,12,...,60!\n",
 		   config_fname, cell_idx,eMTCconfig->ccparams.rach_sizeOfRA_PreamblesGroupA);
-		
+
     switch (eMTCconfig->ccparams.rach_messageSizeGroupA) {
     case 56:
       RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].rach_messageSizeGroupA= LTE_RACH_ConfigCommon__preambleInfo__preamblesGroupAConfig__messageSizeGroupA_b56;
       break;
-		  
+
     case 144:
       RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].rach_messageSizeGroupA= LTE_RACH_ConfigCommon__preambleInfo__preamblesGroupAConfig__messageSizeGroupA_b144;
       break;
-		  
+
     case 208:
       RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].rach_messageSizeGroupA= LTE_RACH_ConfigCommon__preambleInfo__preamblesGroupAConfig__messageSizeGroupA_b208;
       break;
-		  
+
     case 256:
       RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].rach_messageSizeGroupA= LTE_RACH_ConfigCommon__preambleInfo__preamblesGroupAConfig__messageSizeGroupA_b256;
       break;
-		  
+
     default:
       AssertFatal (0,
 		   "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for rach_messageSizeGroupA choice: 56,144,208,256!\n",
 		   config_fname, cell_idx,eMTCconfig->ccparams.rach_messageSizeGroupA);
       break;
     }
-		
+
     if (strcmp(eMTCconfig->ccparams.rach_messagePowerOffsetGroupB,"minusinfinity")==0) {
       RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].rach_messagePowerOffsetGroupB= LTE_RACH_ConfigCommon__preambleInfo__preamblesGroupAConfig__messagePowerOffsetGroupB_minusinfinity;
     } else if (strcmp(eMTCconfig->ccparams.rach_messagePowerOffsetGroupB,"dB0")==0) {
@@ -593,118 +593,118 @@ void fill_eMTC_configuration(MessageDef *msg_p,  ccparams_eMTC_t *eMTCconfig, in
     AssertFatal (0,
 		 "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for rach_preamblesGroupAConfig choice: ENABLE,DISABLE !\n",
 		 config_fname, cell_idx,eMTCconfig->ccparams.rach_preamblesGroupAConfig);
-	      
+
   RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].rach_preambleInitialReceivedTargetPower= (eMTCconfig->ccparams.rach_preambleInitialReceivedTargetPower+120)/2;
-	      
+
   if ((eMTCconfig->ccparams.rach_preambleInitialReceivedTargetPower<-120) || (eMTCconfig->ccparams.rach_preambleInitialReceivedTargetPower>-90) || ((eMTCconfig->ccparams.rach_preambleInitialReceivedTargetPower&1)!=0))
     AssertFatal (0,
 		 "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for rach_preambleInitialReceivedTargetPower choice: -120,-118,...,-90 !\n",
 		 config_fname, cell_idx,eMTCconfig->ccparams.rach_preambleInitialReceivedTargetPower);
-	      
+
   RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].rach_powerRampingStep= eMTCconfig->ccparams.rach_powerRampingStep/2;
-	      
+
   if ((eMTCconfig->ccparams.rach_powerRampingStep<0) || (eMTCconfig->ccparams.rach_powerRampingStep>6) || ((eMTCconfig->ccparams.rach_powerRampingStep&1)!=0))
     AssertFatal (0,
 		 "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for rach_powerRampingStep choice: 0,2,4,6 !\n",
 		 config_fname, cell_idx,eMTCconfig->ccparams.rach_powerRampingStep);
-	      
+
   switch (eMTCconfig->ccparams.rach_preambleTransMax) {
   case 3:
     RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].rach_preambleTransMax=  LTE_PreambleTransMax_n3;
     break;
-		
+
   case 4:
     RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].rach_preambleTransMax=  LTE_PreambleTransMax_n4;
     break;
-		
+
   case 5:
     RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].rach_preambleTransMax=  LTE_PreambleTransMax_n5;
     break;
-		
+
   case 6:
     RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].rach_preambleTransMax=  LTE_PreambleTransMax_n6;
     break;
-		
+
   case 7:
     RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].rach_preambleTransMax=  LTE_PreambleTransMax_n7;
     break;
-		
+
   case 8:
     RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].rach_preambleTransMax=  LTE_PreambleTransMax_n8;
     break;
-		
+
   case 10:
     RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].rach_preambleTransMax=  LTE_PreambleTransMax_n10;
     break;
-		
+
   case 20:
     RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].rach_preambleTransMax=  LTE_PreambleTransMax_n20;
     break;
-		
+
   case 50:
     RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].rach_preambleTransMax=  LTE_PreambleTransMax_n50;
     break;
-		
+
   case 100:
     RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].rach_preambleTransMax=  LTE_PreambleTransMax_n100;
     break;
-		
+
   case 200:
     RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].rach_preambleTransMax=  LTE_PreambleTransMax_n200;
     break;
-		
+
   default:
     AssertFatal (0,
 		 "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for rach_preambleTransMax choice: 3,4,5,6,7,8,10,20,50,100,200!\n",
 		 config_fname, cell_idx,eMTCconfig->ccparams.rach_preambleTransMax);
     break;
   }
-	      
+
   RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].rach_raResponseWindowSize=  (eMTCconfig->ccparams.rach_raResponseWindowSize==10)?7:eMTCconfig->ccparams.rach_raResponseWindowSize-2;
-	      
+
   if ((eMTCconfig->ccparams.rach_raResponseWindowSize<0)||(eMTCconfig->ccparams.rach_raResponseWindowSize==9)||(eMTCconfig->ccparams.rach_raResponseWindowSize>10))
     AssertFatal (0,
 		 "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for rach_raResponseWindowSize choice: 2,3,4,5,6,7,8,10!\n",
 		 config_fname, cell_idx,eMTCconfig->ccparams.rach_raResponseWindowSize);
-	      
+
   RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].rach_macContentionResolutionTimer= (eMTCconfig->ccparams.rach_macContentionResolutionTimer/8)-1;
-	      
+
   if ((eMTCconfig->ccparams.rach_macContentionResolutionTimer<8) || (eMTCconfig->ccparams.rach_macContentionResolutionTimer>64) || ((eMTCconfig->ccparams.rach_macContentionResolutionTimer&7)!=0))
     AssertFatal (0,
 		 "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for rach_macContentionResolutionTimer choice: 8,16,...,56,64!\n",
 		 config_fname, cell_idx,eMTCconfig->ccparams.rach_macContentionResolutionTimer);
-	      
+
   RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].rach_maxHARQ_Msg3Tx= eMTCconfig->ccparams.rach_maxHARQ_Msg3Tx;
-	      
+
   if ((eMTCconfig->ccparams.rach_maxHARQ_Msg3Tx<0) || (eMTCconfig->ccparams.rach_maxHARQ_Msg3Tx>8))
     AssertFatal (0,
 		 "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for rach_maxHARQ_Msg3Tx choice: 1..8!\n",
 		 config_fname, cell_idx,eMTCconfig->ccparams.rach_maxHARQ_Msg3Tx);
-	      
+
   switch (eMTCconfig->ccparams.pcch_defaultPagingCycle) {
   case 32:
     RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].pcch_defaultPagingCycle= LTE_PCCH_Config__defaultPagingCycle_rf32;
     break;
-		
+
   case 64:
     RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].pcch_defaultPagingCycle= LTE_PCCH_Config__defaultPagingCycle_rf64;
     break;
-		
+
   case 128:
     RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].pcch_defaultPagingCycle= LTE_PCCH_Config__defaultPagingCycle_rf128;
     break;
-		
+
   case 256:
     RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].pcch_defaultPagingCycle= LTE_PCCH_Config__defaultPagingCycle_rf256;
     break;
-		
+
   default:
     AssertFatal (0,
 		 "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for pcch_defaultPagingCycle choice: 32,64,128,256!\n",
 		 config_fname, cell_idx,eMTCconfig->ccparams.pcch_defaultPagingCycle);
     break;
   }
-	      
+
   if (strcmp(eMTCconfig->ccparams.pcch_nB, "fourT") == 0) {
     RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].pcch_nB= LTE_PCCH_Config__nB_fourT;
   } else if (strcmp(eMTCconfig->ccparams.pcch_nB, "twoT") == 0) {
@@ -725,86 +725,86 @@ void fill_eMTC_configuration(MessageDef *msg_p,  ccparams_eMTC_t *eMTCconfig, in
     AssertFatal (0,
 		 "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for pcch_nB choice: fourT,twoT,oneT,halfT,quarterT,oneighthT,oneSixteenthT,oneThirtySecondT !\n",
 		 config_fname, cell_idx,eMTCconfig->ccparams.pcch_nB);
-	      
+
   switch (eMTCconfig->ccparams.bcch_modificationPeriodCoeff) {
   case 2:
     RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].bcch_modificationPeriodCoeff= LTE_BCCH_Config__modificationPeriodCoeff_n2;
     break;
-		
+
   case 4:
     RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].bcch_modificationPeriodCoeff= LTE_BCCH_Config__modificationPeriodCoeff_n4;
     break;
-		
+
   case 8:
     RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].bcch_modificationPeriodCoeff= LTE_BCCH_Config__modificationPeriodCoeff_n8;
     break;
-		
+
   case 16:
     RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].bcch_modificationPeriodCoeff= LTE_BCCH_Config__modificationPeriodCoeff_n16;
     break;
-		
+
   default:
     AssertFatal (0,
 		 "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for bcch_modificationPeriodCoeff choice: 2,4,8,16",
 		 config_fname, cell_idx,eMTCconfig->ccparams.bcch_modificationPeriodCoeff);
     break;
   }
-	      
+
   RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].ue_TimersAndConstants_t300= eMTCconfig->ccparams.ue_TimersAndConstants_t300;
   RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].ue_TimersAndConstants_t301= eMTCconfig->ccparams.ue_TimersAndConstants_t301;
   RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].ue_TimersAndConstants_t310= eMTCconfig->ccparams.ue_TimersAndConstants_t310;
   RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].ue_TimersAndConstants_t311= eMTCconfig->ccparams.ue_TimersAndConstants_t311;
   RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].ue_TimersAndConstants_n310= eMTCconfig->ccparams.ue_TimersAndConstants_n310;
   RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].ue_TimersAndConstants_n311= eMTCconfig->ccparams.ue_TimersAndConstants_n311;
-	      
+
   switch (eMTCconfig->ccparams.ue_TransmissionMode) {
   case 1:
     RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].ue_TransmissionMode= LTE_AntennaInfoDedicated__transmissionMode_tm1;
     break;
-		
+
   case 2:
     RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].ue_TransmissionMode= LTE_AntennaInfoDedicated__transmissionMode_tm2;
     break;
-		
+
   case 3:
     RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].ue_TransmissionMode= LTE_AntennaInfoDedicated__transmissionMode_tm3;
     break;
-		
+
   case 4:
     RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].ue_TransmissionMode= LTE_AntennaInfoDedicated__transmissionMode_tm4;
     break;
-		
+
   case 5:
     RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].ue_TransmissionMode= LTE_AntennaInfoDedicated__transmissionMode_tm5;
     break;
-		
+
   case 6:
     RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].ue_TransmissionMode= LTE_AntennaInfoDedicated__transmissionMode_tm6;
     break;
-		
+
   case 7:
     RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].ue_TransmissionMode= LTE_AntennaInfoDedicated__transmissionMode_tm7;
     break;
-		
+
   default:
     AssertFatal (0,
 		 "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for ue_TransmissionMode choice: 1,2,3,4,5,6,7",
 		 config_fname, cell_idx, eMTCconfig->ccparams.ue_TransmissionMode);
     break;
   }
-	      
-	      
+
+
   if (!strcmp(eMTCconfig->prach_ConfigCommon_v1310, "ENABLE")) {
     RRC_CONFIGURATION_REQ(msg_p).radioresourceconfig_BR[cc_idx].prach_ConfigCommon_v1310 = TRUE;
-    
+
     RRC_CONFIGURATION_REQ(msg_p).radioresourceconfig_BR[cc_idx].mpdcch_startSF_CSS_RA_r13 = calloc(1, sizeof(BOOLEAN_t));
-    
+
     if (!strcmp(eMTCconfig->mpdcch_startSF_CSS_RA_r13, "tdd-r13")) {
       *RRC_CONFIGURATION_REQ(msg_p).radioresourceconfig_BR[cc_idx].mpdcch_startSF_CSS_RA_r13 = FALSE;
     } else {
       *RRC_CONFIGURATION_REQ(msg_p).radioresourceconfig_BR[cc_idx].mpdcch_startSF_CSS_RA_r13 = TRUE;
     }
-    
+
     if (!strcmp(eMTCconfig->mpdcch_startSF_CSS_RA_r13_val, "v1")) {
       RRC_CONFIGURATION_REQ(msg_p).radioresourceconfig_BR[cc_idx].mpdcch_startSF_CSS_RA_r13_val = 0;
     } else if (!strcmp(eMTCconfig->mpdcch_startSF_CSS_RA_r13_val, "v1dot5")) {
@@ -832,8 +832,8 @@ void fill_eMTC_configuration(MessageDef *msg_p,  ccparams_eMTC_t *eMTCconfig, in
   } else {
     RRC_CONFIGURATION_REQ(msg_p).radioresourceconfig_BR[cc_idx].prach_ConfigCommon_v1310 = FALSE;
   }
-  
-	      
+
+
   RRC_CONFIGURATION_REQ(msg_p).pdsch_maxNumRepetitionCEmodeA_r13[cc_idx] = CALLOC(1, sizeof(long));
   if (!strcmp(eMTCconfig->pdsch_maxNumRepetitionCEmodeA_r13, "r16")) {
     *RRC_CONFIGURATION_REQ(msg_p).pdsch_maxNumRepetitionCEmodeA_r13[cc_idx] = 0;
@@ -844,8 +844,8 @@ void fill_eMTC_configuration(MessageDef *msg_p,  ccparams_eMTC_t *eMTCconfig, in
 		 "Failed to parse eNB configuration file %s, pdsch_maxNumRepetitionCEmodeA_r13 unknown value!\n",
 		 config_fname);
   }
-	      
-	      
+
+
   RRC_CONFIGURATION_REQ(msg_p).pusch_maxNumRepetitionCEmodeA_r13[cc_idx] = CALLOC(1, sizeof(long));
   if (!strcmp(eMTCconfig->pusch_maxNumRepetitionCEmodeA_r13, "r8")) {
     *RRC_CONFIGURATION_REQ(msg_p).pusch_maxNumRepetitionCEmodeA_r13[cc_idx] =  0;
@@ -858,7 +858,7 @@ void fill_eMTC_configuration(MessageDef *msg_p,  ccparams_eMTC_t *eMTCconfig, in
 		 "Failed to parse eNB configuration file %s, pusch_maxNumRepetitionCEmodeA_r13 unknown value!\n",
 		 config_fname);
   }
-	      
+
   char rachCELevelInfoListPath[MAX_OPTNAME_SIZE * 2];
   config_getlist(&rachcelevellist, NULL, 0, brparamspath);
   RRC_CONFIGURATION_REQ (msg_p).rach_CE_LevelInfoList_r13_size[cc_idx] = rachcelevellist.numelt;
@@ -866,7 +866,7 @@ void fill_eMTC_configuration(MessageDef *msg_p,  ccparams_eMTC_t *eMTCconfig, in
   for (rachCEInfoIndex = 0; rachCEInfoIndex < rachcelevellist.numelt; rachCEInfoIndex++) {
     sprintf(rachCELevelInfoListPath, "%s.%s.[%i]", brparamspath, ENB_CONFIG_STRING_RACH_CE_LEVELINFOLIST_R13, rachCEInfoIndex);
     config_get(rachcelevelParams, sizeof(rachcelevelParams) / sizeof(paramdef_t), rachCELevelInfoListPath);
-		
+
     RRC_CONFIGURATION_REQ (msg_p).firstPreamble_r13[cc_idx][rachCEInfoIndex] = eMTCconfig->firstPreamble_r13;
     RRC_CONFIGURATION_REQ (msg_p).lastPreamble_r13[cc_idx][rachCEInfoIndex]  = eMTCconfig->lastPreamble_r13;
 
@@ -899,7 +899,7 @@ void fill_eMTC_configuration(MessageDef *msg_p,  ccparams_eMTC_t *eMTCconfig, in
       AssertFatal(1==0,
 		"Illegal ra_ResponseWindowSize_r13 %d\n",eMTCconfig->ra_ResponseWindowSize_r13);
     }
-		
+
 
     switch(eMTCconfig->mac_ContentionResolutionTimer_r13) {
     case 80:
@@ -935,33 +935,33 @@ void fill_eMTC_configuration(MessageDef *msg_p,  ccparams_eMTC_t *eMTCconfig, in
     AssertFatal(eMTCconfig->rar_HoppingConfig_r13 == 0 || eMTCconfig->rar_HoppingConfig_r13 == 1,
 		"illegal rar_HoppingConfig_r13 %d\n",eMTCconfig->rar_HoppingConfig_r13);
   } // end for loop (rach ce level info)
-	      
+
   char rsrpRangeListPath[MAX_OPTNAME_SIZE * 2];
   config_getlist(&rsrprangelist, NULL, 0, brparamspath);
   RRC_CONFIGURATION_REQ (msg_p).rsrp_range_list_size[cc_idx] = rsrprangelist.numelt;
-	      
-	      
+
+
   int rsrprangeindex;
   for (rsrprangeindex = 0; rsrprangeindex < rsrprangelist.numelt; rsrprangeindex++) {
     sprintf(rsrpRangeListPath, "%s.%s.[%i]", brparamspath, ENB_CONFIG_STRING_RSRP_RANGE_LIST, rsrprangeindex);
     config_get(rsrprangeParams, sizeof(rsrprangeParams) / sizeof(paramdef_t), rsrpRangeListPath);
     RRC_CONFIGURATION_REQ (msg_p).rsrp_range[cc_idx][rsrprangeindex] = eMTCconfig->rsrp_range_br;
-		
+
   }
-	      
-	      
+
+
   char prachparameterscePath[MAX_OPTNAME_SIZE * 2];
   config_getlist(&prachParamslist, NULL, 0, brparamspath);
   RRC_CONFIGURATION_REQ (msg_p).prach_parameters_list_size[cc_idx] = prachParamslist.numelt;
-	      
+
   int prachparamsindex;
   for (prachparamsindex = 0; prachparamsindex < prachParamslist.numelt; prachparamsindex++) {
     sprintf(prachparameterscePath, "%s.%s.[%i]", brparamspath, ENB_CONFIG_STRING_PRACH_PARAMETERS_CE_R13, prachparamsindex);
     config_get(prachParams, sizeof(prachParams) / sizeof(paramdef_t), prachparameterscePath);
-		
+
     RRC_CONFIGURATION_REQ (msg_p).prach_config_index[cc_idx][prachparamsindex]                  = eMTCconfig->prach_config_index_br;
     RRC_CONFIGURATION_REQ (msg_p).prach_freq_offset[cc_idx][prachparamsindex]                   = eMTCconfig->prach_freq_offset_br;
-		
+
     RRC_CONFIGURATION_REQ (msg_p).prach_StartingSubframe_r13[cc_idx][prachparamsindex] = calloc(1, sizeof(long));
     switch(eMTCconfig->prach_StartingSubframe_r13) {
     case 2:
@@ -1000,9 +1000,9 @@ void fill_eMTC_configuration(MessageDef *msg_p,  ccparams_eMTC_t *eMTCconfig, in
     AssertFatal(eMTCconfig->maxNumPreambleAttemptCE_r13 > 2 && eMTCconfig->maxNumPreambleAttemptCE_r13 <11,
 		"prachparamsindex %d: Illegal maxNumPreambleAttemptCE_r13 %d\n",
 		prachparamsindex,eMTCconfig->maxNumPreambleAttemptCE_r13);
-		
 
-    switch(eMTCconfig->numRepetitionPerPreambleAttempt_r13) { 
+
+    switch(eMTCconfig->numRepetitionPerPreambleAttempt_r13) {
     case 1:
       RRC_CONFIGURATION_REQ (msg_p).numRepetitionPerPreambleAttempt_r13[cc_idx][prachparamsindex] = LTE_PRACH_ParametersCE_r13__numRepetitionPerPreambleAttempt_r13_n1;
       break;
@@ -1067,15 +1067,15 @@ void fill_eMTC_configuration(MessageDef *msg_p,  ccparams_eMTC_t *eMTCconfig, in
 		   eMTCconfig->mpdcch_NumRepetition_RA_r13);
       break;
     }
-		
+
     RRC_CONFIGURATION_REQ (msg_p).prach_HoppingConfig_r13[cc_idx][prachparamsindex] = eMTCconfig->prach_HoppingConfig_r13;
-		
+
     AssertFatal (eMTCconfig->prach_HoppingConfig_r13 >=0 && eMTCconfig->prach_HoppingConfig_r13 < 2,
 		 "Illegal prach_HoppingConfig_r13 %d\n",eMTCconfig->prach_HoppingConfig_r13);
-		
-		
+
+
     int maxavailablenarrowband_count = prachParams[7].numelt;
-		
+
     RRC_CONFIGURATION_REQ (msg_p).max_available_narrow_band_size[cc_idx][prachparamsindex] = maxavailablenarrowband_count;
     int narrow_band_index;
     for (narrow_band_index = 0; narrow_band_index < maxavailablenarrowband_count; narrow_band_index++) {
@@ -1086,22 +1086,22 @@ void fill_eMTC_configuration(MessageDef *msg_p,  ccparams_eMTC_t *eMTCconfig, in
   char n1PUCCHInfoParamsPath[MAX_OPTNAME_SIZE * 2];
   config_getlist(&n1PUCCHInfoList, NULL, 0, brparamspath);
   RRC_CONFIGURATION_REQ (msg_p).pucch_info_value_size[cc_idx] = n1PUCCHInfoList.numelt;
-	      
+
   int n1PUCCHinfolistindex;
   for (n1PUCCHinfolistindex = 0; n1PUCCHinfolistindex < n1PUCCHInfoList.numelt; n1PUCCHinfolistindex++) {
     sprintf(n1PUCCHInfoParamsPath, "%s.%s.[%i]", brparamspath, ENB_CONFIG_STRING_N1PUCCH_AN_INFOLIST_R13, n1PUCCHinfolistindex);
     config_get(n1PUCCH_ANR13Params, sizeof(n1PUCCH_ANR13Params) / sizeof(paramdef_t), n1PUCCHInfoParamsPath);
     RRC_CONFIGURATION_REQ (msg_p).pucch_info_value[cc_idx][n1PUCCHinfolistindex] = eMTCconfig->pucch_info_value;
   }
-	      
+
   char PCCHConfigv1310Path[MAX_OPTNAME_SIZE*2 + 16];
   sprintf(PCCHConfigv1310Path, "%s.%s", brparamspath, ENB_CONFIG_STRING_PCCH_CONFIG_V1310);
   config_get(pcchv1310Params, sizeof(pcchv1310Params)/sizeof(paramdef_t), PCCHConfigv1310Path);
-	      
-	      
-	      
+
+
+
   /** PCCH CONFIG V1310 */
-	      
+
   RRC_CONFIGURATION_REQ(msg_p).pcch_config_v1310[cc_idx] = TRUE;
   RRC_CONFIGURATION_REQ(msg_p).paging_narrowbands_r13[cc_idx] = eMTCconfig->paging_narrowbands_r13;
   RRC_CONFIGURATION_REQ(msg_p).mpdcch_numrepetition_paging_r13[cc_idx] = eMTCconfig->mpdcch_numrepetition_paging_r13;
@@ -1116,8 +1116,8 @@ void fill_eMTC_configuration(MessageDef *msg_p,  ccparams_eMTC_t *eMTCconfig, in
 	       eMTCconfig->mpdcch_numrepetition_paging_r13 == 256,
 	       "illegal mpdcch_numrepetition_paging_r13 %d\n",
 	       eMTCconfig->mpdcch_numrepetition_paging_r13);
-	      
-	      
+
+
   //                        RRC_CONFIGURATION_REQ(msg_p).nb_v1310[cc_idx] = CALLOC(1, sizeof(long));
   //                        if (!strcmp(nb_v1310, "one64thT")) {
   //                            *RRC_CONFIGURATION_REQ(msg_p).nb_v1310[cc_idx] = 0;
@@ -1130,9 +1130,9 @@ void fill_eMTC_configuration(MessageDef *msg_p,  ccparams_eMTC_t *eMTCconfig, in
   //                                        "Failed to parse eNB configuration file %s, nb_v1310, unknown value !\n",
   //                                        config_fname);
   //                        }
-	      
-	      
-	      
+
+
+
   RRC_CONFIGURATION_REQ (msg_p).pucch_NumRepetitionCE_Msg4_Level0_r13[cc_idx] = CALLOC(1, sizeof(long));
   // ++cnt; // check this ,, the conter is up above
   if (!strcmp(eMTCconfig->pucch_NumRepetitionCE_Msg4_Level0_r13, "n1")) {
@@ -1148,21 +1148,21 @@ void fill_eMTC_configuration(MessageDef *msg_p,  ccparams_eMTC_t *eMTCconfig, in
 		 "Failed to parse eNB configuration file %s, pucch_NumRepetitionCE_Msg4_Level0_r13 unknown value!\n",
 		 config_fname);
   }
-	      
-	      
-	      
+
+
+
   /** SIB2 FREQ HOPPING PARAMETERS R13 */
   RRC_CONFIGURATION_REQ(msg_p).sib2_freq_hoppingParameters_r13_exists[cc_idx] = TRUE;
-	      
+
   char sib2FreqHoppingParametersR13Path[MAX_OPTNAME_SIZE*2 + 16];
   sprintf(sib2FreqHoppingParametersR13Path, "%s.%s", brparamspath, ENB_CONFIG_STRING_SIB2_FREQ_HOPPINGPARAMETERS_R13);
   config_get(sib2freqhoppingParams, sizeof(sib2freqhoppingParams)/sizeof(paramdef_t), sib2FreqHoppingParametersR13Path);
-	      
-	      
+
+
   RRC_CONFIGURATION_REQ(msg_p).sib2_interval_ULHoppingConfigCommonModeA_r13[cc_idx] = CALLOC(1, sizeof(long));
   if (!strcmp(eMTCconfig->sib2_interval_ULHoppingConfigCommonModeA_r13, "FDD")) {
     *RRC_CONFIGURATION_REQ(msg_p).sib2_interval_ULHoppingConfigCommonModeA_r13[cc_idx] = 0;
-    
+
     switch(eMTCconfig->sib2_interval_ULHoppingConfigCommonModeA_r13_val) {
     case 1:
       RRC_CONFIGURATION_REQ(msg_p).sib2_interval_ULHoppingConfigCommonModeA_r13_val[cc_idx] = 0;
@@ -1207,4 +1207,4 @@ void fill_eMTC_configuration(MessageDef *msg_p,  ccparams_eMTC_t *eMTCconfig, in
 		 "Failed to parse eNB configuration file %s, sib2_interval_ULHoppingConfigCommonModeA_r13 unknown value !!\n",
 		 config_fname);
   }
-} 
+}
diff --git a/openair2/ENB_APP/enb_paramdef.h b/openair2/ENB_APP/enb_paramdef.h
index 04c8795a2a49d28ddc4212de02347049f7fc51c6..1f496ba3c5870557c851fbc2e3aa9b1227606679 100644
--- a/openair2/ENB_APP/enb_paramdef.h
+++ b/openair2/ENB_APP/enb_paramdef.h
@@ -101,6 +101,8 @@ typedef enum {
 #define CONFIG_STRING_RU_NBIOTRRC_LIST            "NbIoT_RRC_instances"
 #define CONFIG_STRING_RU_SDR_ADDRS                "sdr_addrs"
 #define CONFIG_STRING_RU_SDR_CLK_SRC              "clock_src"
+#define CONFIG_STRING_RU_SF_EXTENSION             "sf_extension"
+#define CONFIG_STRING_RU_END_OF_BURST_DELAY       "end_of_burst_delay"
 
 #define RU_LOCAL_IF_NAME_IDX          0
 #define RU_LOCAL_ADDRESS_IDX          1
@@ -122,6 +124,8 @@ typedef enum {
 #define RU_NBIOTRRC_LIST_IDX          17
 #define RU_SDR_ADDRS                  18
 #define RU_SDR_CLK_SRC                19
+#define RU_SF_EXTENSION_IDX           20
+#define RU_END_OF_BURST_DELAY_IDX     21
 
 
 
@@ -149,7 +153,9 @@ typedef enum {
 {CONFIG_STRING_RU_ATT_RX,                   	 NULL,       0,       uptr:NULL,       defintval:0,		TYPE_UINT,	  0}, \
 {CONFIG_STRING_RU_NBIOTRRC_LIST,                 NULL,       0,       uptr:NULL,       defintarrayval:DEFENBS,  TYPE_INTARRAY,    1}, \
 {CONFIG_STRING_RU_SDR_ADDRS,                 	 NULL,       0,       strptr:NULL,     defstrval:"type=b200",   TYPE_STRING,      0}, \
-{CONFIG_STRING_RU_SDR_CLK_SRC,               	 NULL,       0,       strptr:NULL,     defstrval:"internal",   TYPE_STRING,      0}, \
+{CONFIG_STRING_RU_SDR_CLK_SRC,               	 NULL,       0,       strptr:NULL,     defstrval:"internal",    TYPE_STRING,      0}, \
+{CONFIG_STRING_RU_SF_EXTENSION,                  NULL,       0,       uptr:NULL,       defuintval:312,          TYPE_UINT,        0}, \
+{CONFIG_STRING_RU_END_OF_BURST_DELAY,            NULL,       0,       uptr:NULL,       defuintval:400,          TYPE_UINT,        0}, \
 }
 
 /*---------------------------------------------------------------------------------------------------------------------------------------*/
@@ -197,6 +203,7 @@ typedef enum {
 #define ENB_CONFIG_STRING_REMOTE_S_PORTC                "remote_s_portc"
 #define ENB_CONFIG_STRING_LOCAL_S_PORTD                 "local_s_portd"
 #define ENB_CONFIG_STRING_REMOTE_S_PORTD                "remote_s_portd"
+#define ENB_CONFIG_STRING_NR_CELLID                     "nr_cellid"
 #define ENB_CONFIG_STRING_RRC_INACTIVITY_THRESHOLD      "rrc_inactivity_threshold"
 
 /*-----------------------------------------------------------------------------------------------------------------------------------------*/
@@ -218,6 +225,7 @@ typedef enum {
 {ENB_CONFIG_STRING_REMOTE_S_PORTC,               NULL,   0,            uptr:NULL,   defuintval:50000,            TYPE_UINT,      0},  \
 {ENB_CONFIG_STRING_LOCAL_S_PORTD,                NULL,   0,            uptr:NULL,   defuintval:50001,            TYPE_UINT,      0},  \
 {ENB_CONFIG_STRING_REMOTE_S_PORTD,               NULL,   0,            uptr:NULL,   defuintval:50001,            TYPE_UINT,      0},  \
+{ENB_CONFIG_STRING_NR_CELLID,                    NULL,   0,            u64ptr:NULL, defint64val:0,               TYPE_UINT64,    0},  \
 {ENB_CONFIG_STRING_RRC_INACTIVITY_THRESHOLD,     NULL,   0,            uptr:NULL,   defintval:0,                 TYPE_UINT,      0},  \
 }															     	
 #define ENB_ENB_ID_IDX                  0
@@ -234,7 +242,8 @@ typedef enum {
 #define ENB_REMOTE_S_PORTC_IDX          11
 #define ENB_LOCAL_S_PORTD_IDX           12
 #define ENB_REMOTE_S_PORTD_IDX          13
-#define ENB_RRC_INACTIVITY_THRES_IDX    14
+#define ENB_NRCELLID_IDX                14
+#define ENB_RRC_INACTIVITY_THRES_IDX    15
 
 
 #define TRACKING_AREA_CODE_OKRANGE {0x0001,0xFFFD}
@@ -254,6 +263,7 @@ typedef enum {
   { .s5 = { NULL } },                                             \
   { .s5 = { NULL } },                                             \
   { .s5 = { NULL } },                                             \
+  { .s5 = { NULL } },                                             \
 }
 
 /*-------------------------------------------------------------------------------------------------------------------------------------------------*/
@@ -313,7 +323,7 @@ typedef enum {
 #define ENB_CONFIG_STRING_NB_V1310                               "nb_v1310"
 
 
-#define ENB_CONFIG_STRING_PUCCH_NUM_REPETITION_CE_MSG4_LEVEL0    "pucch_NumRepetitionCE_Msg4_Level0_r13" 
+#define ENB_CONFIG_STRING_PUCCH_NUM_REPETITION_CE_MSG4_LEVEL0    "pucch_NumRepetitionCE_Msg4_Level0_r13"
 #define ENB_CONFIG_STRING_PUCCH_NUM_REPETITION_CE_MSG4_LEVEL1    "pucch_NumRepetitionCE_Msg4_Level1_r13"
 #define ENB_CONFIG_STRING_PUCCH_NUM_REPETITION_CE_MSG4_LEVEL2    "pucch_NumRepetitionCE_Msg4_Level2_r13"
 #define ENB_CONFIG_STRING_PUCCH_NUM_REPETITION_CE_MSG4_LEVEL3    "pucch_NumRepetitionCE_Msg4_Level3_r13"
@@ -378,7 +388,7 @@ typedef enum {
 #define ENB_CONFIG_STRING_PUSCH_MAX_NUM_REPETITION_CE_MODE_B_R13        "pusch_maxNumRepetitionCEmodeB_r13"
 #define ENB_CONFIG_STRING_PUSCH_HOPPING_OFFSET_V1310                    "pusch_HoppingOffset_v1310"
 
-		
+
 //TTN - for D2D
 //SIB18
 #define ENB_CONFIG_STRING_RXPOOL_SC_CP_LEN                              "rxPool_sc_CP_Len"
@@ -962,6 +972,58 @@ typedef struct srb1_params_s {
 {CONFIG_STRING_FLEXRAN_AWAIT_RECONF,           NULL,   0,   strptr:NULL,   defstrval:"no",                    TYPE_STRING,   0}            \
 }
 
+/*----------------------------------------------------------------------------------------------------------------------------------------------------*/
+/*----------------------------------------------------------------------------------------------------------------------------------------------------*/
+/* CU/DU configuration section names*/
+#define CONFIG_STRING_DU_LIST			"DU"
+#define CONFIG_STRING_CU_LIST			"CU"
+#define DU_TYPE_LTE					0
+#define DU_TYPE_WIFI					1
+#define ENB_CONFIG_STRING_CU_INTERFACES_CONFIG		"CU_INTERFACES"
+#define ENB_CONFIG_STRING_CU_INTERFACE_NAME_FOR_F1U     "CU_INTERFACE_NAME_FOR_F1U"
+#define ENB_CONFIG_STRING_CU_IPV4_ADDRESS_FOR_F1U       "CU_IPV4_ADDRESS_FOR_F1U"
+#define ENB_CONFIG_STRING_CU_PORT_FOR_F1U               "CU_PORT_FOR_F1U"
+#define ENB_CONFIG_STRING_DU_TYPE	                "DU_TYPE"
+#define ENB_CONFIG_STRING_F1_U_CU_TRANSPORT_TYPE        "F1_U_CU_TRANSPORT_TYPE"
+
+#define ENB_CONFIG_STRING_DU_INTERFACES_CONFIG		"DU_INTERFACES"
+#define ENB_CONFIG_STRING_DU_INTERFACE_NAME_FOR_F1U     "DU_INTERFACE_NAME_FOR_F1U"
+#define ENB_CONFIG_STRING_DU_IPV4_ADDRESS_FOR_F1U       "DU_IPV4_ADDRESS_FOR_F1U"
+#define ENB_CONFIG_STRING_DU_PORT_FOR_F1U               "DU_PORT_FOR_F1U"
+#define ENB_CONFIG_STRING_F1_U_DU_TRANSPORT_TYPE        "F1_U_DU_TRANSPORT_TYPE"
+
+#define CONFIG_STRING_CU_BALANCING			"CU_BALANCING"
+
+#define CUPARAMS_DESC { \
+{ENB_CONFIG_STRING_CU_INTERFACE_NAME_FOR_F1U,           	NULL,   0,   strptr:NULL,   defstrval:"eth0",   	TYPE_STRING,   0},           \
+{ENB_CONFIG_STRING_CU_IPV4_ADDRESS_FOR_F1U,                   	NULL,   0,   strptr:NULL,   defstrval:"127.0.0.1",   	TYPE_STRING,   0},           \
+{ENB_CONFIG_STRING_CU_PORT_FOR_F1U,                 	 	NULL,   0,   uptr:NULL,     defintval:2210,   		TYPE_UINT,     0},            \
+{ENB_CONFIG_STRING_F1_U_CU_TRANSPORT_TYPE,                  	NULL,   0,   strptr:NULL,   defstrval:"TCP",   		TYPE_STRING,   0},            \
+{ENB_CONFIG_STRING_DU_TYPE,                  			NULL,   0,   strptr:NULL,   defstrval:"LTE",   		TYPE_STRING,   0},            \
+}
+
+#define DUPARAMS_DESC { \
+{ENB_CONFIG_STRING_DU_INTERFACE_NAME_FOR_F1U,           	NULL,   0,   strptr:NULL,   defstrval:"eth0",   	TYPE_STRING,   0},           \
+{ENB_CONFIG_STRING_DU_IPV4_ADDRESS_FOR_F1U,                  	NULL,   0,   strptr:NULL,   defstrval:"127.0.0.1",   	TYPE_STRING,   0},           \
+{ENB_CONFIG_STRING_DU_PORT_FOR_F1U,                  		NULL,   0,   uptr:NULL,     defintval:2210,   		TYPE_UINT,     0},            \
+{ENB_CONFIG_STRING_F1_U_DU_TRANSPORT_TYPE,                   	NULL,   0,   strptr:NULL,   defstrval:"TCP",   		TYPE_STRING,   0},           \
+}
+
+#define CU_BAL_DESC { \
+{CONFIG_STRING_CU_BALANCING,           				NULL,   0,   strptr:NULL,   defstrval:"ALL",   	TYPE_STRING,   0},           \
+}
+
+#define CU_INTERFACE_F1U 	                     0
+#define CU_ADDRESS_F1U 		  		     1
+#define CU_PORT_F1U 	              		     2
+#define CU_TYPE_F1U 	              		     3
+
+#define DU_INTERFACE_F1U	                     0
+#define DU_ADDRESS_F1U		  		     1
+#define DU_PORT_F1U	               		     2
+#define DU_TYPE_F1U	               		     3
+#define DU_TECH					     4
+
 /*----------------------------------------------------------------------------------------------------------------------------------------------------*/
 /*----------------------------------------------------------------------------------------------------------------------------------------------------*/
 /* MACRLC configuration section names   */
diff --git a/openair2/ENB_APP/enb_paramdef_sidelink.h b/openair2/ENB_APP/enb_paramdef_sidelink.h
index 3e73ba43b738dcfbc8771e8faa8db176fae51aa7..dd3aa5f0fbb75d32131bec58d0c8fd187ffc9c63 100644
--- a/openair2/ENB_APP/enb_paramdef_sidelink.h
+++ b/openair2/ENB_APP/enb_paramdef_sidelink.h
@@ -20,7 +20,7 @@
  */
 
 /*! \file openair2/ENB_APP/enb_paramdef_sidelink.h
- * \brief definition of configuration parameters for sidelink eNodeB modules 
+ * \brief definition of configuration parameters for sidelink eNodeB modules
  * \author Raymond KNOPP
  * \date 2018
  * \version 0.1
@@ -180,4 +180,3 @@ typedef struct ccparams_sidelink_s {
 {ENB_CONFIG_STRING_DISCRXPOOLPS_RC_SFBITMAP_CHOICE_BS_ASN_BITS_UNUSED,NULL,   0,   iptr:(int32_t *)&SLparams.discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_bits_unused,         defintval:1,       TYPE_UINT,    0} \
 }
 #endif
-
diff --git a/openair2/ENB_APP/flexran_agent.c b/openair2/ENB_APP/flexran_agent.c
index 9c0af82e900e0965a75319dd8501841d49f51f62..24ed07ac9255d0448af4d92c3f73ee1c31282e39 100644
--- a/openair2/ENB_APP/flexran_agent.c
+++ b/openair2/ENB_APP/flexran_agent.c
@@ -26,11 +26,12 @@
  * \version 0.1
  */
 
+#define _GNU_SOURCE
 #include "flexran_agent.h"
 
+#include <pthread.h>
 #include <arpa/inet.h>
 
-void *send_thread(void *args);
 void *receive_thread(void *args);
 pthread_t new_thread(void *(*f)(void *), void *b);
 Protocol__FlexranMessage *flexran_agent_timeout(void* args);
@@ -110,10 +111,11 @@ void *receive_thread(void *args) {
   err_code_t             err_code=0;
 
   Protocol__FlexranMessage *msg;
+  pthread_setname_np(pthread_self(), "flexran_rx_thr");
   
   while (1) {
 
-    while (flexran_agent_msg_recv(d->mod_id, FLEXRAN_AGENT_DEFAULT, &data, &size, &priority) == 0) {
+    while ((size = flexran_agent_msg_recv(d->mod_id, FLEXRAN_AGENT_DEFAULT, &data, &priority)) > 0) {
       
       LOG_D(FLEXRAN_AGENT,"received message with size %d\n", size);
   
@@ -201,6 +203,11 @@ int flexran_agent_start(mid_t mod_id)
   /*Create the async channel info*/
   flexran_agent_async_channel_t *channel_info = flexran_agent_async_channel_info(mod_id, in_ip, in_port);
 
+  if (!channel_info) {
+    LOG_E(FLEXRAN_AGENT, "could not create channel_info\n");
+    exit(1);
+  }
+
   /*Create a channel using the async channel info*/
   channel_id = flexran_agent_create_channel((void *) channel_info, 
 					flexran_agent_async_msg_send, 
@@ -209,12 +216,14 @@ int flexran_agent_start(mid_t mod_id)
 
   
   if (channel_id <= 0) {
+    LOG_E(FLEXRAN_AGENT, "could not create channel\n");
     goto error;
   }
 
   flexran_agent_channel_t *channel = get_channel(channel_id);
   
   if (channel == NULL) {
+    LOG_E(FLEXRAN_AGENT, "could not get channel for channel_id %d\n", channel_id);
     goto error;
   }
 
@@ -226,21 +235,48 @@ int flexran_agent_start(mid_t mod_id)
    */
 
   /*Initialize the continuous stats update mechanism*/
-  flexran_agent_init_cont_stats_update(mod_id);
-  
+  if (flexran_agent_init_cont_stats_update(mod_id) < 0) {
+    LOG_E(FLEXRAN_AGENT, "could not initialize continuous stats updates\n");
+    goto error;
+  }
+
   new_thread(receive_thread, flexran);
 
-  /*Initialize and register the mac xface. Must be modified later
-   *for more flexibility in agent management */
+  /* Register and initialize the control modules depending on capabilities.
+   * After registering, calling flexran_agent_get_*_xface() tells whether a
+   * control module is operational */
+  uint16_t caps = flexran_get_capabilities_mask(mod_id);
+  LOG_I(FLEXRAN_AGENT, "Agent handles BS ID %ld, capabilities=0x%x => handling%s%s%s%s%s%s%s%s\n",
+        flexran_get_bs_id(mod_id), caps,
+        FLEXRAN_CAP_LOPHY(caps) ? " LOPHY" : "",
+        FLEXRAN_CAP_HIPHY(caps) ? " HIPHY" : "",
+        FLEXRAN_CAP_LOMAC(caps) ? " LOMAC" : "",
+        FLEXRAN_CAP_HIMAC(caps) ? " HIMAC" : "",
+        FLEXRAN_CAP_RLC(caps)   ? " RLC"   : "",
+        FLEXRAN_CAP_PDCP(caps)  ? " PDCP"  : "",
+        FLEXRAN_CAP_SDAP(caps)  ? " SDAP"  : "",
+        FLEXRAN_CAP_RRC(caps)   ? " RRC"   : "");
+
+  if (FLEXRAN_CAP_LOPHY(caps) || FLEXRAN_CAP_HIPHY(caps)) {
+    flexran_agent_register_phy_xface(mod_id);
+    LOG_I(FLEXRAN_AGENT, "registered PHY interface/CM for eNB %d\n", mod_id);
+  }
 
-  AGENT_MAC_xface *mac_agent_xface = (AGENT_MAC_xface *) malloc(sizeof(AGENT_MAC_xface));
-  flexran_agent_register_mac_xface(mod_id, mac_agent_xface);
-  
-  AGENT_RRC_xface *rrc_agent_xface = (AGENT_RRC_xface *) malloc(sizeof(AGENT_RRC_xface));
-  flexran_agent_register_rrc_xface(mod_id, rrc_agent_xface);
+  if (FLEXRAN_CAP_LOMAC(caps) || FLEXRAN_CAP_HIMAC(caps)) {
+    flexran_agent_register_mac_xface(mod_id);
+    flexran_agent_init_mac_agent(mod_id);
+    LOG_I(FLEXRAN_AGENT, "registered MAC interface/CM for eNB %d\n", mod_id);
+  }
+
+  if (FLEXRAN_CAP_RRC(caps)) {
+    flexran_agent_register_rrc_xface(mod_id);
+    LOG_I(FLEXRAN_AGENT, "registered RRC interface/CM for eNB %d\n", mod_id);
+  }
 
-  AGENT_PDCP_xface *pdcp_agent_xface = (AGENT_PDCP_xface *) malloc(sizeof(AGENT_PDCP_xface));
-  flexran_agent_register_pdcp_xface(mod_id, pdcp_agent_xface);
+  if (FLEXRAN_CAP_PDCP(caps)) {
+    flexran_agent_register_pdcp_xface(mod_id);
+    LOG_I(FLEXRAN_AGENT, "registered PDCP interface/CM for eNB %d\n", mod_id);
+  }
 
   /* 
    * initilize a timer 
@@ -248,11 +284,6 @@ int flexran_agent_start(mid_t mod_id)
   
   flexran_agent_init_timer();
 
-  /*
-   * Initialize the mac agent
-   */
-  flexran_agent_init_mac_agent(mod_id);
-  
   /* 
    * start the enb agent task for tx and interaction with the underlying network function
    */ 
@@ -288,7 +319,7 @@ int flexran_agent_start(mid_t mod_id)
   return 0;
 
 error:
-  LOG_I(FLEXRAN_AGENT,"there was an error\n");
+  LOG_E(FLEXRAN_AGENT, "%s(): there was an error\n", __func__);
   return 1;
 
 }
diff --git a/openair2/ENB_APP/flexran_agent.h b/openair2/ENB_APP/flexran_agent.h
index 4ce727ff1c7c89e305ccb7ff2d1641010122e64a..e50a2be4f65cf6a0e0f29541cb0333a645cc5064 100644
--- a/openair2/ENB_APP/flexran_agent.h
+++ b/openair2/ENB_APP/flexran_agent.h
@@ -36,6 +36,7 @@
 #include "flexran_agent_defs.h"
 #include "flexran_agent_net_comm.h"
 #include "flexran_agent_ran_api.h"
+#include "flexran_agent_phy.h"
 #include "flexran_agent_mac.h"
 #include "flexran_agent_rrc.h"
 #include "flexran_agent_pdcp.h"
diff --git a/openair2/ENB_APP/flexran_agent_async.c b/openair2/ENB_APP/flexran_agent_async.c
index 88be77d5bb2c93fb9c1501f7ace1222c1119478d..fa2e0c9ff583c1f5d7e697f325f2b514b5f3cffb 100644
--- a/openair2/ENB_APP/flexran_agent_async.c
+++ b/openair2/ENB_APP/flexran_agent_async.c
@@ -36,13 +36,18 @@ flexran_agent_async_channel_t * flexran_agent_async_channel_info(mid_t mod_id, c
   flexran_agent_async_channel_t *channel;
   channel = (flexran_agent_async_channel_t *) malloc(sizeof(flexran_agent_channel_t));
   
-  if (channel == NULL)
-    goto error;
+  if (channel == NULL) {
+    LOG_E(FLEXRAN_AGENT, "could not allocate memory for flexran_agent_async_channel_t\n");
+    return NULL;
+  }
 
   channel->enb_id = mod_id;
   /*Create a socket*/
   channel->link = new_link_client(dst_ip, dst_port);
-  if (channel->link == NULL) goto error;
+  if (channel->link == NULL) {
+    LOG_E(FLEXRAN_AGENT, "could not create new link client\n");
+    goto error;
+  }
   
   LOG_I(FLEXRAN_AGENT,"starting enb agent client for module id %d on ipv4 %s, port %d\n",  
 	channel->enb_id,
@@ -53,21 +58,32 @@ flexran_agent_async_channel_t * flexran_agent_async_channel_info(mid_t mod_id, c
    * create a message queue
    */ 
   // Set size of queues statically for now
-  channel->send_queue = new_message_queue(500);
-  if (channel->send_queue == NULL) goto error;
-  channel->receive_queue = new_message_queue(500);
-  if (channel->receive_queue == NULL) goto error;
+//  channel->send_queue = new_message_queue(500);
+  // not using the circular buffer: affects the PDCP split
+  channel->send_queue = new_message_queue();
+  if (channel->send_queue == NULL) {
+    LOG_E(FLEXRAN_AGENT, "could not create send_queue\n");
+    goto error;
+  }
+  // not using the circular buffer: affects the PDCP split
+  //channel->receive_queue = new_message_queue(500);
+  channel->receive_queue = new_message_queue();
+  if (channel->receive_queue == NULL) {
+    LOG_E(FLEXRAN_AGENT, "could not create send_queue\n");
+    goto error;
+  }
   
-   /* 
-   * create a link manager 
-   */  
+  /* create a link manager */
   channel->manager = create_link_manager(channel->send_queue, channel->receive_queue, channel->link);
-  if (channel->manager == NULL) goto error;
+  if (channel->manager == NULL) {
+    LOG_E(FLEXRAN_AGENT, "could not create link_manager\n");
+    goto error;
+  }
   
   return channel;
 
  error:
-  LOG_I(FLEXRAN_AGENT,"there was an error\n");
+  LOG_I(FLEXRAN_AGENT, "%s(): there was an error\n", __func__);
   return NULL;
 }
 
@@ -78,11 +94,11 @@ int flexran_agent_async_msg_send(void *data, int size, int priority, void *chann
   return message_put(channel->send_queue, data, size, priority);
 }
 
-int flexran_agent_async_msg_recv(void **data, int *size, int *priority, void *channel_info) {
+int flexran_agent_async_msg_recv(void **data, int *priority, void *channel_info) {
   flexran_agent_async_channel_t *channel;
   channel = (flexran_agent_async_channel_t *)channel_info;
 
-  return message_get(channel->receive_queue, data, size, priority);
+  return message_get(channel->receive_queue, data, priority);
 }
 
 void flexran_agent_async_release(flexran_agent_channel_t *channel) {
diff --git a/openair2/ENB_APP/flexran_agent_async.h b/openair2/ENB_APP/flexran_agent_async.h
index 03aebd0058fc6c3293baa664119124e6921f6ef2..1ebc565f62b31a5555ac00add7a9d4e50912878a 100644
--- a/openair2/ENB_APP/flexran_agent_async.h
+++ b/openair2/ENB_APP/flexran_agent_async.h
@@ -46,7 +46,7 @@ flexran_agent_async_channel_t * flexran_agent_async_channel_info(mid_t mod_id, c
 int flexran_agent_async_msg_send(void *data, int size, int priority, void *channel_info);
 
 /* Receive a message from a given channel */
-int flexran_agent_async_msg_recv(void **data, int *size, int *priority, void *channel_info);
+int flexran_agent_async_msg_recv(void **data, int *priority, void *channel_info);
 
 /* Release a channel */
 void flexran_agent_async_release(flexran_agent_channel_t *channel);
diff --git a/openair2/ENB_APP/flexran_agent_common.c b/openair2/ENB_APP/flexran_agent_common.c
index 19a1394cbd2b844790be33bc89fed5cf98d51c07..539c7f2a5c21abcaad1cb5e3d98288f876acf819 100644
--- a/openair2/ENB_APP/flexran_agent_common.c
+++ b/openair2/ENB_APP/flexran_agent_common.c
@@ -35,6 +35,9 @@
 #include "flexran_agent_extern.h"
 #include "flexran_agent_net_comm.h"
 #include "flexran_agent_ran_api.h"
+#include "flexran_agent_phy.h"
+#include "flexran_agent_mac.h"
+#include "flexran_agent_rrc.h"
 //#include "PHY/extern.h"
 #include "common/utils/LOG/log.h"
 #include "flexran_agent_mac_internal.h"
@@ -121,6 +124,10 @@ int flexran_agent_hello(mid_t mod_id, const void *params, Protocol__FlexranMessa
     goto error;
 
   hello_msg->header = header;
+  hello_msg->bs_id  = flexran_get_bs_id(mod_id);
+  hello_msg->has_bs_id = 1;
+  hello_msg->n_capabilities = flexran_get_capabilities(mod_id, &hello_msg->capabilities);
+
   *msg = malloc(sizeof(Protocol__FlexranMessage));
 
   if(*msg == NULL)
@@ -153,6 +160,7 @@ int flexran_agent_destroy_hello(Protocol__FlexranMessage *msg) {
     goto error;
 
   free(msg->hello_msg->header);
+  free(msg->hello_msg->capabilities);
   free(msg->hello_msg);
   free(msg);
   return 0;
@@ -283,25 +291,26 @@ int flexran_agent_destroy_enb_config_reply(Protocol__FlexranMessage *msg) {
     goto error;
 
   free(msg->enb_config_reply_msg->header);
-  int i, j;
   Protocol__FlexEnbConfigReply *reply = msg->enb_config_reply_msg;
 
-  for(i = 0; i < reply->n_cell_config; i++) {
-    free(reply->cell_config[i]->mbsfn_subframe_config_rfoffset);
-    free(reply->cell_config[i]->mbsfn_subframe_config_rfperiod);
-    free(reply->cell_config[i]->mbsfn_subframe_config_sfalloc);
+  for (int i = 0; i < reply->n_cell_config; i++) {
+    if (reply->cell_config[i]->mbsfn_subframe_config_rfoffset)
+      free(reply->cell_config[i]->mbsfn_subframe_config_rfoffset);
+    if (reply->cell_config[i]->mbsfn_subframe_config_rfperiod)
+      free(reply->cell_config[i]->mbsfn_subframe_config_rfperiod);
+    if (reply->cell_config[i]->mbsfn_subframe_config_sfalloc);
+      free(reply->cell_config[i]->mbsfn_subframe_config_sfalloc);
 
-    if (reply->cell_config[i]->si_config != NULL) {
-      for(j = 0; j < reply->cell_config[i]->si_config->n_si_message; j++) {
+    if (reply->cell_config[i]->si_config) {
+      for(int j = 0; j < reply->cell_config[i]->si_config->n_si_message; j++) {
         free(reply->cell_config[i]->si_config->si_message[j]);
       }
-
       free(reply->cell_config[i]->si_config->si_message);
       free(reply->cell_config[i]->si_config);
     }
 
-    if (reply->cell_config[i]->slice_config != NULL) {
-      for (j = 0; j < reply->cell_config[i]->slice_config->n_dl; ++j) {
+    if (reply->cell_config[i]->slice_config) {
+      for (int j = 0; j < reply->cell_config[i]->slice_config->n_dl; ++j) {
         if (reply->cell_config[i]->slice_config->dl[j]->n_sorting > 0)
           free(reply->cell_config[i]->slice_config->dl[j]->sorting);
 
@@ -310,8 +319,7 @@ int flexran_agent_destroy_enb_config_reply(Protocol__FlexranMessage *msg) {
       }
 
       free(reply->cell_config[i]->slice_config->dl);
-
-      for (j = 0; j < reply->cell_config[i]->slice_config->n_ul; ++j) {
+      for (int j = 0; j < reply->cell_config[i]->slice_config->n_ul; ++j) {
         if (reply->cell_config[i]->slice_config->ul[j]->n_sorting > 0)
           free(reply->cell_config[i]->slice_config->ul[j]->sorting);
 
@@ -472,8 +480,6 @@ int flexran_agent_lc_config_reply(mid_t mod_id, const void *params, Protocol__Fl
   Protocol__FlexranMessage *input = (Protocol__FlexranMessage *)params;
   Protocol__FlexLcConfigRequest *lc_config_request_msg = input->lc_config_request_msg;
   xid = (lc_config_request_msg->header)->xid;
-  int i, j;
-  int UE_id;
   Protocol__FlexLcConfigReply *lc_config_reply_msg;
   lc_config_reply_msg = malloc(sizeof(Protocol__FlexLcConfigReply));
 
@@ -486,9 +492,16 @@ int flexran_agent_lc_config_reply(mid_t mod_id, const void *params, Protocol__Fl
     goto error;
 
   lc_config_reply_msg->header = header;
-  lc_config_reply_msg->n_lc_ue_config = flexran_get_num_ues(mod_id);
-  Protocol__FlexLcUeConfig **lc_ue_config;
 
+  /* the lc_config_reply entirely depends on MAC except for the
+   * mac_eNB_get_rrc_status() function (which in the current OAI implementation
+   * is reachable if F1 is present). Therefore we check here wether MAC CM is
+   * present and the message gets properly filled if it is or remains empty if
+   * not */
+  lc_config_reply_msg->n_lc_ue_config =
+      flexran_agent_get_mac_xface(mod_id) ? flexran_get_mac_num_ues(mod_id) : 0;
+
+  Protocol__FlexLcUeConfig **lc_ue_config = NULL;
   if (lc_config_reply_msg->n_lc_ue_config > 0) {
     lc_ue_config = malloc(sizeof(Protocol__FlexLcUeConfig *) * lc_config_reply_msg->n_lc_ue_config);
 
@@ -497,76 +510,13 @@ int flexran_agent_lc_config_reply(mid_t mod_id, const void *params, Protocol__Fl
     }
 
     // Fill the config for each UE
-    for (i = 0; i < lc_config_reply_msg->n_lc_ue_config; i++) {
+    for (int i = 0; i < lc_config_reply_msg->n_lc_ue_config; i++) {
       lc_ue_config[i] = malloc(sizeof(Protocol__FlexLcUeConfig));
-      protocol__flex_lc_ue_config__init(lc_ue_config[i]);
-      UE_id = flexran_get_ue_id(mod_id, i);
-      lc_ue_config[i]->has_rnti = 1;
-      lc_ue_config[i]->rnti = flexran_get_ue_crnti(mod_id, UE_id);
-      //TODO: Set the number of LC configurations that will be reported for this UE
-      //Set this according to the current state of the UE. This is only a temporary fix
-      int status = 0;
-      status = mac_eNB_get_rrc_status(mod_id, flexran_get_ue_crnti(mod_id, UE_id));
-
-      /* TODO needs to be revised and appropriate API to be implemented */
-      if (status < RRC_CONNECTED) {
-        lc_ue_config[i]->n_lc_config = 0;
-      } else if (status == RRC_CONNECTED) {
-        lc_ue_config[i]->n_lc_config = 1;
-      } else {
-        lc_ue_config[i]->n_lc_config = 3;
-      }
+      if (!lc_ue_config[i]) goto error;
 
-      Protocol__FlexLcConfig **lc_config;
-
-      if (lc_ue_config[i]->n_lc_config > 0) {
-        lc_config = malloc(sizeof(Protocol__FlexLcConfig *) * lc_ue_config[i]->n_lc_config);
-
-        if (lc_config == NULL) {
-          goto error;
-        }
-
-        for (j = 0; j < lc_ue_config[i]->n_lc_config; j++) {
-          lc_config[j] = malloc(sizeof(Protocol__FlexLcConfig));
-          protocol__flex_lc_config__init(lc_config[j]);
-          lc_config[j]->has_lcid = 1;
-          lc_config[j]->lcid = j+1;
-          int lcg = flexran_get_lcg(mod_id, UE_id, j+1);
-
-          if (lcg >= 0 && lcg <= 3) {
-            lc_config[j]->has_lcg = 1;
-            lc_config[j]->lcg = flexran_get_lcg(mod_id, UE_id, j+1);
-          }
-
-          lc_config[j]->has_direction = 1;
-          lc_config[j]->direction = flexran_get_direction(UE_id, j+1);
-          //TODO: Bearer type. One of FLQBT_* values. Currently only default bearer supported
-          lc_config[j]->has_qos_bearer_type = 1;
-          lc_config[j]->qos_bearer_type = PROTOCOL__FLEX_QOS_BEARER_TYPE__FLQBT_NON_GBR;
-          //TODO: Set the QCI defined in TS 23.203, coded as defined in TS 36.413
-          // One less than the actual QCI value. Needs to be generalized
-          lc_config[j]->has_qci = 1;
-          lc_config[j]->qci = 1;
-
-          if (lc_config[j]->direction == PROTOCOL__FLEX_QOS_BEARER_TYPE__FLQBT_GBR) {
-            /* TODO all of the need to be taken from API */
-            //TODO: Set the max bitrate (UL)
-            lc_config[j]->has_e_rab_max_bitrate_ul = 0;
-            lc_config[j]->e_rab_max_bitrate_ul = 0;
-            //TODO: Set the max bitrate (DL)
-            lc_config[j]->has_e_rab_max_bitrate_dl = 0;
-            lc_config[j]->e_rab_max_bitrate_dl = 0;
-            //TODO: Set the guaranteed bitrate (UL)
-            lc_config[j]->has_e_rab_guaranteed_bitrate_ul = 0;
-            lc_config[j]->e_rab_guaranteed_bitrate_ul = 0;
-            //TODO: Set the guaranteed bitrate (DL)
-            lc_config[j]->has_e_rab_guaranteed_bitrate_dl = 0;
-            lc_config[j]->e_rab_guaranteed_bitrate_dl = 0;
-          }
-        }
-
-        lc_ue_config[i]->lc_config = lc_config;
-      }
+      protocol__flex_lc_ue_config__init(lc_ue_config[i]);
+      const int UE_id = flexran_get_mac_ue_id(mod_id, i);
+      flexran_agent_fill_mac_lc_ue_config(mod_id, UE_id, lc_ue_config[i]);
     } // end for UE
 
     lc_config_reply_msg->lc_ue_config = lc_ue_config;
@@ -604,14 +554,24 @@ error:
  * ************************************
  */
 
+int sort_ue_config(const void *a, const void *b)
+{
+  const Protocol__FlexUeConfig *fa = a;
+  const Protocol__FlexUeConfig *fb = b;
+
+  if (fa->rnti < fb->rnti)
+    return -1;
+  else if (fa->rnti < fb->rnti)
+    return 1;
+  return 0;
+}
+
 int flexran_agent_ue_config_reply(mid_t mod_id, const void *params, Protocol__FlexranMessage **msg) {
   xid_t xid;
   Protocol__FlexHeader *header = NULL;
   Protocol__FlexranMessage *input = (Protocol__FlexranMessage *)params;
   Protocol__FlexUeConfigRequest *ue_config_request_msg = input->ue_config_request_msg;
   xid = (ue_config_request_msg->header)->xid;
-  int i;
-  int UE_id;
   Protocol__FlexUeConfigReply *ue_config_reply_msg;
   ue_config_reply_msg = malloc(sizeof(Protocol__FlexUeConfigReply));
 
@@ -624,7 +584,22 @@ int flexran_agent_ue_config_reply(mid_t mod_id, const void *params, Protocol__Fl
     goto error;
 
   ue_config_reply_msg->header = header;
-  ue_config_reply_msg->n_ue_config = flexran_get_num_ues(mod_id);
+
+  ue_config_reply_msg->n_ue_config = 0;
+  if (flexran_agent_get_rrc_xface(mod_id))
+    ue_config_reply_msg->n_ue_config = flexran_get_rrc_num_ues(mod_id);
+  else if (flexran_agent_get_mac_xface(mod_id))
+    ue_config_reply_msg->n_ue_config = flexran_get_mac_num_ues(mod_id);
+
+  if (flexran_agent_get_rrc_xface(mod_id) && flexran_agent_get_mac_xface(mod_id)
+      && flexran_get_rrc_num_ues(mod_id) != flexran_get_mac_num_ues(mod_id)) {
+    const int nrrc = flexran_get_rrc_num_ues(mod_id);
+    const int nmac = flexran_get_mac_num_ues(mod_id);
+    ue_config_reply_msg->n_ue_config = nrrc < nmac ? nrrc : nmac;
+    LOG_E(FLEXRAN_AGENT, "%s(): different numbers of UEs in RRC (%d) and MAC (%d), reporting for %lu UEs\n",
+        __func__, nrrc, nmac, ue_config_reply_msg->n_ue_config);
+  }
+
   Protocol__FlexUeConfig **ue_config;
 
   if (ue_config_reply_msg->n_ue_config > 0) {
@@ -633,157 +608,20 @@ int flexran_agent_ue_config_reply(mid_t mod_id, const void *params, Protocol__Fl
     if (ue_config == NULL) {
       goto error;
     }
-
-    for (i = 0; i < ue_config_reply_msg->n_ue_config; i++) {
+    rnti_t rntis[ue_config_reply_msg->n_ue_config];
+    flexran_get_rrc_rnti_list(mod_id, rntis, ue_config_reply_msg->n_ue_config);
+    for (int i = 0; i < ue_config_reply_msg->n_ue_config; i++) {
+      const rnti_t rnti = rntis[i];
       ue_config[i] = malloc(sizeof(Protocol__FlexUeConfig));
       protocol__flex_ue_config__init(ue_config[i]);
-      UE_id = flexran_get_ue_id(mod_id, i);
-      ue_config[i]->rnti = flexran_get_ue_crnti(mod_id, UE_id);
-      ue_config[i]->has_rnti = 1;
-      ue_config[i]->imsi = flexran_get_ue_imsi(mod_id, UE_id);
-      ue_config[i]->has_imsi = 1;
-      ue_config[i]->dl_slice_id = flexran_get_ue_dl_slice_id(mod_id, UE_id);
-      ue_config[i]->has_dl_slice_id = 1;
-      ue_config[i]->ul_slice_id = flexran_get_ue_ul_slice_id(mod_id, UE_id);
-      ue_config[i]->has_ul_slice_id = 1;
-      //TODO: Set the DRX configuration (optional)
-      //Not supported for now, so we do not set it
-
-      if (flexran_get_time_alignment_timer(mod_id, UE_id) != -1) {
-        ue_config[i]->time_alignment_timer = flexran_get_time_alignment_timer(mod_id, UE_id);
-        ue_config[i]->has_time_alignment_timer = 1;
-      }
-
-      if (flexran_get_meas_gap_config(mod_id, UE_id) != -1) {
-        ue_config[i]->meas_gap_config_pattern = flexran_get_meas_gap_config(mod_id, UE_id);
-        ue_config[i]->has_meas_gap_config_pattern = 1;
-      }
-
-      if (ue_config[i]->has_meas_gap_config_pattern == 1 &&
-          ue_config[i]->meas_gap_config_pattern != PROTOCOL__FLEX_MEAS_GAP_CONFIG_PATTERN__FLMGCP_OFF) {
-        ue_config[i]->meas_gap_config_sf_offset = flexran_get_meas_gap_config_offset(mod_id, UE_id);
-        ue_config[i]->has_meas_gap_config_sf_offset = 1;
-      }
-
-      //TODO: Set the SPS configuration (Optional)
-      //Not supported for noe, so we do not set it
-
-      //TODO: Set the SR configuration (Optional)
-      //We do not set it for now
-
-      //TODO: Set the CQI configuration (Optional)
-      //We do not set it for now
-
-      if (flexran_get_ue_transmission_mode(mod_id, UE_id) != -1) {
-        ue_config[i]->transmission_mode = flexran_get_ue_transmission_mode(mod_id, UE_id);
-        ue_config[i]->has_transmission_mode = 1;
-      }
-
-      ue_config[i]->ue_aggregated_max_bitrate_ul = flexran_get_ue_aggregated_max_bitrate_ul(mod_id, UE_id);
-      ue_config[i]->has_ue_aggregated_max_bitrate_ul = 1;
-      ue_config[i]->ue_aggregated_max_bitrate_dl = flexran_get_ue_aggregated_max_bitrate_dl(mod_id, UE_id);
-      ue_config[i]->has_ue_aggregated_max_bitrate_dl = 1;
-      Protocol__FlexUeCapabilities *capabilities;
-      capabilities = malloc(sizeof(Protocol__FlexUeCapabilities));
-      protocol__flex_ue_capabilities__init(capabilities);
-      capabilities->has_half_duplex = 1;
-      capabilities->half_duplex = flexran_get_half_duplex(mod_id, UE_id);
-      capabilities->has_intra_sf_hopping = 1;
-      capabilities->intra_sf_hopping = flexran_get_intra_sf_hopping(mod_id, UE_id);
-      capabilities->has_type2_sb_1 = 1;
-      capabilities->type2_sb_1 = flexran_get_type2_sb_1(mod_id, UE_id);
-      capabilities->has_ue_category = 1;
-      capabilities->ue_category = flexran_get_ue_category(mod_id, UE_id);
-      capabilities->has_res_alloc_type1 = 1;
-      capabilities->res_alloc_type1 = flexran_get_res_alloc_type1(mod_id, UE_id);
-      //Set the capabilites to the message
-      ue_config[i]->capabilities = capabilities;
-
-      if (flexran_get_ue_transmission_antenna(mod_id, UE_id) != -1) {
-        ue_config[i]->has_ue_transmission_antenna = 1;
-        ue_config[i]->ue_transmission_antenna = flexran_get_ue_transmission_antenna(mod_id, UE_id);
-      }
-
-      if (flexran_get_tti_bundling(mod_id, UE_id) != -1) {
-        ue_config[i]->has_tti_bundling = 1;
-        ue_config[i]->tti_bundling = flexran_get_tti_bundling(mod_id, UE_id);
-      }
-
-      if (flexran_get_maxHARQ_TX(mod_id, UE_id) != -1) {
-        ue_config[i]->has_max_harq_tx = 1;
-        ue_config[i]->max_harq_tx = flexran_get_maxHARQ_TX(mod_id, UE_id);
-      }
-
-      if (flexran_get_beta_offset_ack_index(mod_id, UE_id) != -1) {
-        ue_config[i]->has_beta_offset_ack_index = 1;
-        ue_config[i]->beta_offset_ack_index = flexran_get_beta_offset_ack_index(mod_id, UE_id);
-      }
-
-      if (flexran_get_beta_offset_ri_index(mod_id, UE_id) != -1) {
-        ue_config[i]->has_beta_offset_ri_index = 1;
-        ue_config[i]->beta_offset_ri_index = flexran_get_beta_offset_ri_index(mod_id, UE_id);
-      }
-
-      if (flexran_get_beta_offset_cqi_index(mod_id, UE_id) != -1) {
-        ue_config[i]->has_beta_offset_cqi_index = 1;
-        ue_config[i]->beta_offset_cqi_index = flexran_get_beta_offset_cqi_index(mod_id, UE_id);
-      }
-
-      /* assume primary carrier */
-      if (flexran_get_ack_nack_simultaneous_trans(mod_id, UE_id, 0) != -1) {
-        ue_config[i]->has_ack_nack_simultaneous_trans = 1;
-        ue_config[i]->ack_nack_simultaneous_trans = flexran_get_ack_nack_simultaneous_trans(mod_id, UE_id, 0);
-      }
 
-      if (flexran_get_simultaneous_ack_nack_cqi(mod_id, UE_id) != -1) {
-        ue_config[i]->has_simultaneous_ack_nack_cqi = 1;
-        ue_config[i]->simultaneous_ack_nack_cqi = flexran_get_simultaneous_ack_nack_cqi(mod_id, UE_id);
-      }
-
-      if (flexran_get_aperiodic_cqi_rep_mode(mod_id, UE_id) != -1) {
-        ue_config[i]->has_aperiodic_cqi_rep_mode = 1;
-        int mode = flexran_get_aperiodic_cqi_rep_mode(mod_id, UE_id);
-
-        if (mode > 4) {
-          ue_config[i]->aperiodic_cqi_rep_mode = PROTOCOL__FLEX_APERIODIC_CQI_REPORT_MODE__FLACRM_NONE;
-        } else {
-          ue_config[i]->aperiodic_cqi_rep_mode = mode;
-        }
-      }
-
-      if (flexran_get_tdd_ack_nack_feedback_mode(mod_id, UE_id) != -1) {
-        ue_config[i]->has_tdd_ack_nack_feedback = 1;
-        ue_config[i]->tdd_ack_nack_feedback = flexran_get_tdd_ack_nack_feedback_mode(mod_id, UE_id);
-      }
-
-      if(flexran_get_ack_nack_repetition_factor(mod_id, UE_id) != -1) {
-        ue_config[i]->has_ack_nack_repetition_factor = 1;
-        ue_config[i]->ack_nack_repetition_factor = flexran_get_ack_nack_repetition_factor(mod_id, UE_id);
-      }
-
-      if (flexran_get_extended_bsr_size(mod_id, UE_id) != -1) {
-        ue_config[i]->has_extended_bsr_size = 1;
-        ue_config[i]->extended_bsr_size = flexran_get_extended_bsr_size(mod_id, UE_id);
-      }
-
-      //TODO: Set carrier aggregation support (boolean)
-      ue_config[i]->has_ca_support = 0;
-      ue_config[i]->ca_support = 0;
-      ue_config[i]->has_pcell_carrier_index = 1;
-      ue_config[i]->pcell_carrier_index = UE_PCCID(mod_id, UE_id);
-
-      if(ue_config[i]->has_ca_support) {
-        //TODO: Set cross carrier scheduling support (boolean)
-        ue_config[i]->has_cross_carrier_sched_support = 0;
-        ue_config[i]->cross_carrier_sched_support = 0;
-        //TODO: Set secondary cells configuration
-        // We do not set it for now. No carrier aggregation support
-        //TODO: Set deactivation timer for secondary cell
-        ue_config[i]->has_scell_deactivation_timer = 0;
-        ue_config[i]->scell_deactivation_timer = 0;
+      if (flexran_agent_get_rrc_xface(mod_id))
+        flexran_agent_fill_rrc_ue_config(mod_id, rnti, ue_config[i]);
+      if (flexran_agent_get_mac_xface(mod_id)) {
+        const int UE_id = flexran_get_mac_ue_id_rnti(mod_id, rnti);
+        flexran_agent_fill_mac_ue_config(mod_id, UE_id, ue_config[i]);
       }
     }
-
     ue_config_reply_msg->ue_config = ue_config;
   }
 
@@ -867,7 +705,6 @@ int flexran_agent_enb_config_reply(mid_t mod_id, const void *params, Protocol__F
   Protocol__FlexranMessage *input = (Protocol__FlexranMessage *)params;
   Protocol__FlexEnbConfigRequest *enb_config_req_msg = input->enb_config_request_msg;
   xid = (enb_config_req_msg->header)->xid;
-  int i, j;
   Protocol__FlexEnbConfigReply *enb_config_reply_msg;
   enb_config_reply_msg = malloc(sizeof(Protocol__FlexEnbConfigReply));
 
@@ -880,8 +717,6 @@ int flexran_agent_enb_config_reply(mid_t mod_id, const void *params, Protocol__F
     goto error;
 
   enb_config_reply_msg->header = header;
-  enb_config_reply_msg->enb_id = RC.flexran[mod_id]->agent_id;
-  enb_config_reply_msg->has_enb_id = 1;
   enb_config_reply_msg->n_cell_config = MAX_NUM_CCs;
   Protocol__FlexCellConfig **cell_conf;
 
@@ -890,200 +725,19 @@ int flexran_agent_enb_config_reply(mid_t mod_id, const void *params, Protocol__F
 
     if(cell_conf == NULL)
       goto error;
-
-    for(i = 0; i < enb_config_reply_msg->n_cell_config; i++) {
+    for(int i = 0; i < enb_config_reply_msg->n_cell_config; i++){
       cell_conf[i] = malloc(sizeof(Protocol__FlexCellConfig));
+      if (!cell_conf[i]) goto error;
       protocol__flex_cell_config__init(cell_conf[i]);
-      cell_conf[i]->phy_cell_id = flexran_get_cell_id(mod_id,i);
-      cell_conf[i]->has_phy_cell_id = 1;
-      cell_conf[i]->cell_id = i;
-      cell_conf[i]->has_cell_id = 1;
-      cell_conf[i]->pusch_hopping_offset = flexran_get_hopping_offset(mod_id,i);
-      cell_conf[i]->has_pusch_hopping_offset = 1;
-
-      if (flexran_get_hopping_mode(mod_id,i) == 0) {
-        cell_conf[i]->hopping_mode = PROTOCOL__FLEX_HOPPING_MODE__FLHM_INTER;
-      } else if(flexran_get_hopping_mode(mod_id,i) == 1) {
-        cell_conf[i]->hopping_mode = PROTOCOL__FLEX_HOPPING_MODE__FLHM_INTERINTRA;
-      }
-
-      cell_conf[i]->has_hopping_mode = 1;
-      cell_conf[i]->n_sb = flexran_get_n_SB(mod_id,i);
-      cell_conf[i]->has_n_sb = 1;
-
-      if (flexran_get_phich_resource(mod_id,i) == 0) {
-        cell_conf[i]->phich_resource = PROTOCOL__FLEX_PHICH_RESOURCE__FLPR_ONE_SIXTH; //0
-      } else if (flexran_get_phich_resource(mod_id,i) == 1) {
-        cell_conf[i]->phich_resource = PROTOCOL__FLEX_PHICH_RESOURCE__FLPR_HALF; //1
-      } else if (flexran_get_phich_resource(mod_id,i) == 2) {
-        cell_conf[i]->phich_resource = PROTOCOL__FLEX_PHICH_RESOURCE__FLPR_ONE; // 2
-      } else if (flexran_get_phich_resource(mod_id,i) == 3) {
-        cell_conf[i]->phich_resource = PROTOCOL__FLEX_PHICH_RESOURCE__FLPR_TWO;//3
-      }
-
-      cell_conf[i]->has_phich_resource = 1;
-
-      if (flexran_get_phich_duration(mod_id,i) == 0) {
-        cell_conf[i]->phich_duration = PROTOCOL__FLEX_PHICH_DURATION__FLPD_NORMAL;
-      } else if(flexran_get_phich_duration(mod_id,i) == 1) {
-        cell_conf[i]->phich_duration = PROTOCOL__FLEX_PHICH_DURATION__FLPD_EXTENDED;
-      }
-
-      cell_conf[i]->has_phich_duration = 1;
-      cell_conf[i]->init_nr_pdcch_ofdm_sym = flexran_get_num_pdcch_symb(mod_id,i);
-      cell_conf[i]->has_init_nr_pdcch_ofdm_sym = 1;
-      Protocol__FlexSiConfig *si_config;
-      si_config = malloc(sizeof(Protocol__FlexSiConfig));
-
-      if(si_config == NULL)
-        goto error;
-
-      protocol__flex_si_config__init(si_config);
-      si_config->sfn = flexran_get_current_system_frame_num(mod_id);
-      si_config->has_sfn = 1;
-      si_config->sib1_length = flexran_get_sib1_length(mod_id,i);
-      si_config->has_sib1_length = 1;
-      si_config->si_window_length = (uint32_t) flexran_get_si_window_length(mod_id, i);
-      si_config->has_si_window_length = 1;
-      si_config->n_si_message = 0;
-      /* Protocol__FlexSiMessage **si_message; */
-      /* si_message = malloc(sizeof(Protocol__FlexSiMessage *) * si_config->n_si_message); */
-      /* if(si_message == NULL) */
-      /*  goto error; */
-      /* for(j = 0; j < si_config->n_si_message; j++){ */
-      /*  si_message[j] = malloc(sizeof(Protocol__FlexSiMessage)); */
-      /*  if(si_message[j] == NULL) */
-      /*    goto error; */
-      /*  protocol__flex_si_message__init(si_message[j]); */
-      /*  //TODO: Fill in with actual value, Periodicity of SI msg in radio frames */
-      /*  si_message[j]->periodicity = 1;       //SIPeriod */
-      /*  si_message[j]->has_periodicity = 1; */
-      /*  //TODO: Fill in with actual value, rhe length of the SI message in bytes */
-      /*  si_message[j]->length = 10; */
-      /*  si_message[j]->has_length = 1; */
-      /* } */
-      /* if(si_config->n_si_message > 0){ */
-      /*  si_config->si_message = si_message; */
-      /* } */
-      cell_conf[i]->si_config = si_config;
-      cell_conf[i]->dl_bandwidth = flexran_get_N_RB_DL(mod_id,i);
-      cell_conf[i]->has_dl_bandwidth = 1;
-      cell_conf[i]->ul_bandwidth = flexran_get_N_RB_UL(mod_id,i);
-      cell_conf[i]->has_ul_bandwidth = 1;
-
-      if (flexran_get_ul_cyclic_prefix_length(mod_id, i) == 0) {
-        cell_conf[i]->ul_cyclic_prefix_length = PROTOCOL__FLEX_UL_CYCLIC_PREFIX_LENGTH__FLUCPL_NORMAL;
-      } else if(flexran_get_ul_cyclic_prefix_length(mod_id, i) == 1) {
-        cell_conf[i]->ul_cyclic_prefix_length = PROTOCOL__FLEX_UL_CYCLIC_PREFIX_LENGTH__FLUCPL_EXTENDED;
-      }
-
-      cell_conf[i]->has_ul_cyclic_prefix_length = 1;
-
-      if (flexran_get_ul_cyclic_prefix_length(mod_id,i) == 0) {
-        cell_conf[i]->ul_cyclic_prefix_length = PROTOCOL__FLEX_DL_CYCLIC_PREFIX_LENGTH__FLDCPL_NORMAL;
-      } else if (flexran_get_ul_cyclic_prefix_length(mod_id,i) == 1) {
-        cell_conf[i]->ul_cyclic_prefix_length = PROTOCOL__FLEX_DL_CYCLIC_PREFIX_LENGTH__FLDCPL_EXTENDED;
-      }
-
-      cell_conf[i]->has_dl_cyclic_prefix_length = 1;
-      cell_conf[i]->antenna_ports_count = flexran_get_antenna_ports(mod_id, i);
-      cell_conf[i]->has_antenna_ports_count = 1;
-
-      if (flexran_get_duplex_mode(mod_id,i) == 1) {
-        cell_conf[i]->duplex_mode = PROTOCOL__FLEX_DUPLEX_MODE__FLDM_FDD;
-      } else if(flexran_get_duplex_mode(mod_id,i) == 0) {
-        cell_conf[i]->duplex_mode = PROTOCOL__FLEX_DUPLEX_MODE__FLDM_TDD;
-      }
-
-      cell_conf[i]->has_duplex_mode = 1;
-      cell_conf[i]->subframe_assignment = flexran_get_subframe_assignment(mod_id, i);
-      cell_conf[i]->has_subframe_assignment = 1;
-      cell_conf[i]->special_subframe_patterns = flexran_get_special_subframe_assignment(mod_id,i);
-      cell_conf[i]->has_special_subframe_patterns = 1;
-      //TODO: Fill in with actual value, The MBSFN radio frame period
-      cell_conf[i]->n_mbsfn_subframe_config_rfperiod = 0;
-      uint32_t *elem_rfperiod;
-      elem_rfperiod = (uint32_t *) malloc(sizeof(uint32_t) *cell_conf[i]->n_mbsfn_subframe_config_rfperiod);
-
-      if(elem_rfperiod == NULL)
-        goto error;
-
-      for(j = 0; j < cell_conf[i]->n_mbsfn_subframe_config_rfperiod; j++) {
-        elem_rfperiod[j] = 1;
-      }
-
-      cell_conf[i]->mbsfn_subframe_config_rfperiod = elem_rfperiod;
-      //TODO: Fill in with actual value, The MBSFN radio frame offset
-      cell_conf[i]->n_mbsfn_subframe_config_rfoffset = 0;
-      uint32_t *elem_rfoffset;
-      elem_rfoffset = (uint32_t *) malloc(sizeof(uint32_t) *cell_conf[i]->n_mbsfn_subframe_config_rfoffset);
-
-      if(elem_rfoffset == NULL)
-        goto error;
+      if (flexran_agent_get_phy_xface(mod_id))
+        flexran_agent_fill_phy_cell_config(mod_id, i, cell_conf[i]);
+      if (flexran_agent_get_rrc_xface(mod_id))
+        flexran_agent_fill_rrc_cell_config(mod_id, i, cell_conf[i]);
+      if (flexran_agent_get_mac_xface(mod_id))
+        flexran_agent_fill_mac_cell_config(mod_id, i, cell_conf[i]);
 
-      for(j = 0; j < cell_conf[i]->n_mbsfn_subframe_config_rfoffset; j++) {
-        elem_rfoffset[j] = 1;
-      }
-
-      cell_conf[i]->mbsfn_subframe_config_rfoffset = elem_rfoffset;
-      //TODO: Fill in with actual value, Bitmap indicating the MBSFN subframes
-      cell_conf[i]->n_mbsfn_subframe_config_sfalloc = 0;
-      uint32_t *elem_sfalloc;
-      elem_sfalloc = (uint32_t *) malloc(sizeof(uint32_t) *cell_conf[i]->n_mbsfn_subframe_config_sfalloc);
-
-      if(elem_sfalloc == NULL)
-        goto error;
-
-      for(j = 0; j < cell_conf[i]->n_mbsfn_subframe_config_sfalloc; j++) {
-        elem_sfalloc[j] = 1;
-      }
-
-      cell_conf[i]->mbsfn_subframe_config_sfalloc = elem_sfalloc;
-      cell_conf[i]->prach_config_index = flexran_get_prach_ConfigIndex(mod_id,i);
-      cell_conf[i]->has_prach_config_index = 1;
-      cell_conf[i]->prach_freq_offset = flexran_get_prach_FreqOffset(mod_id,i);
-      cell_conf[i]->has_prach_freq_offset = 1;
-      cell_conf[i]->ra_response_window_size = flexran_get_ra_ResponseWindowSize(mod_id,i);
-      cell_conf[i]->has_ra_response_window_size = 1;
-      cell_conf[i]->mac_contention_resolution_timer = flexran_get_mac_ContentionResolutionTimer(mod_id,i);
-      cell_conf[i]->has_mac_contention_resolution_timer = 1;
-      cell_conf[i]->max_harq_msg3tx = flexran_get_maxHARQ_Msg3Tx(mod_id,i);
-      cell_conf[i]->has_max_harq_msg3tx = 1;
-      cell_conf[i]->n1pucch_an = flexran_get_n1pucch_an(mod_id,i);
-      cell_conf[i]->has_n1pucch_an = 1;
-      cell_conf[i]->deltapucch_shift = flexran_get_deltaPUCCH_Shift(mod_id,i);
-      cell_conf[i]->has_deltapucch_shift = 1;
-      cell_conf[i]->nrb_cqi = flexran_get_nRB_CQI(mod_id,i);
-      cell_conf[i]->has_nrb_cqi = 1;
-      cell_conf[i]->srs_subframe_config = flexran_get_srs_SubframeConfig(mod_id,i);
-      cell_conf[i]->has_srs_subframe_config = 1;
-      cell_conf[i]->srs_bw_config = flexran_get_srs_BandwidthConfig(mod_id,i);
-      cell_conf[i]->has_srs_bw_config = 1;
-      cell_conf[i]->srs_mac_up_pts = flexran_get_srs_MaxUpPts(mod_id,i);
-      cell_conf[i]->has_srs_mac_up_pts = 1;
-      cell_conf[i]->dl_freq = flexran_agent_get_operating_dl_freq (mod_id,i);
-      cell_conf[i]->has_dl_freq = 1;
-      cell_conf[i]->ul_freq = flexran_agent_get_operating_ul_freq (mod_id, i);
-      cell_conf[i]->has_ul_freq = 1;
-      cell_conf[i]->eutra_band = flexran_agent_get_operating_eutra_band (mod_id,i);
-      cell_conf[i]->has_eutra_band = 1;
-      cell_conf[i]->dl_pdsch_power = flexran_agent_get_operating_pdsch_refpower(mod_id, i);
-      cell_conf[i]->has_dl_pdsch_power = 1;
-      cell_conf[i]->ul_pusch_power = flexran_agent_get_operating_pusch_p0 (mod_id,i);
-      cell_conf[i]->has_ul_pusch_power = 1;
-
-      if (flexran_get_enable64QAM(mod_id,i) == 0) {
-        cell_conf[i]->enable_64qam = PROTOCOL__FLEX_QAM__FLEQ_MOD_16QAM;
-      } else if(flexran_get_enable64QAM(mod_id,i) == 1) {
-        cell_conf[i]->enable_64qam = PROTOCOL__FLEX_QAM__FLEQ_MOD_64QAM;
-      }
-
-      cell_conf[i]->has_enable_64qam = 1;
       cell_conf[i]->carrier_index = i;
       cell_conf[i]->has_carrier_index = 1;
-      /* get a pointer to the config which is maintained in the agent throughout
-      * its lifetime */
-      cell_conf[i]->slice_config = flexran_agent_get_slice_config(mod_id);
     }
 
     enb_config_reply_msg->cell_config=cell_conf;
@@ -1150,11 +804,10 @@ int flexran_agent_handle_enb_config_reply(mid_t mod_id, const void *params, Prot
 
   if (enb_config->n_cell_config > 1)
     LOG_W(FLEXRAN_AGENT, "ignoring slice configs for other cell except cell 0\n");
-
-  if (enb_config->cell_config[0]->slice_config) {
+  if (flexran_agent_get_mac_xface(mod_id) && enb_config->cell_config[0]->slice_config) {
     prepare_update_slice_config(mod_id, enb_config->cell_config[0]->slice_config);
-  } else {
-    initiate_soft_restart(mod_id, enb_config->cell_config[0]);
+  //} else {
+  //  initiate_soft_restart(mod_id, enb_config->cell_config[0]);
   }
 
   *msg = NULL;
@@ -1166,7 +819,7 @@ int flexran_agent_handle_ue_config_reply(mid_t mod_id, const void *params, Proto
   Protocol__FlexranMessage *input = (Protocol__FlexranMessage *)params;
   Protocol__FlexUeConfigReply *ue_config_reply = input->ue_config_reply_msg;
 
-  for (i = 0; i < ue_config_reply->n_ue_config; i++)
+  for (i = 0; flexran_agent_get_mac_xface(mod_id) && i < ue_config_reply->n_ue_config; i++)
     prepare_ue_slice_assoc_update(mod_id, ue_config_reply->ue_config[i]);
 
   *msg = NULL;
diff --git a/openair2/ENB_APP/flexran_agent_common.h b/openair2/ENB_APP/flexran_agent_common.h
index c83d3c24819ad30e0dad650a17d8c7c3d7a1c620..8419dae62d1a69c7a748d8aaa7aa3999c8fb5434 100644
--- a/openair2/ENB_APP/flexran_agent_common.h
+++ b/openair2/ENB_APP/flexran_agent_common.h
@@ -154,6 +154,7 @@ int flexran_agent_handle_stats(mid_t mod_id, const void *params, Protocol__Flexr
 
 /* Function to be used to handle reply message . */
 int flexran_agent_stats_reply(mid_t enb_id, xid_t xid, const report_config_t *report_config, Protocol__FlexranMessage **msg);
+int flexran_agent_destroy_stats_reply(Protocol__FlexranMessage *msg);
 
 /* Top level Statistics request protocol message constructor and destructor */
 int flexran_agent_stats_request(mid_t mod_id, xid_t xid, const stats_request_config_t *report_config, Protocol__FlexranMessage **msg);
@@ -161,8 +162,6 @@ int flexran_agent_destroy_stats_request(Protocol__FlexranMessage *msg);
 
 err_code_t flexran_agent_init_cont_stats_update(mid_t mod_id);
 
-void flexran_agent_send_update_stats(mid_t mod_id);
-
 err_code_t flexran_agent_enable_cont_stats_update(mid_t mod_id, xid_t xid, stats_request_config_t *stats_req) ;
 err_code_t flexran_agent_disable_cont_stats_update(mid_t mod_id);
 
diff --git a/openair2/ENB_APP/flexran_agent_common_internal.c b/openair2/ENB_APP/flexran_agent_common_internal.c
index 9f1a1d3710a8a106400f2bd0bd4499110110c5bd..9091753f9ac9e26795e01f0a473787cf89036dbb 100644
--- a/openair2/ENB_APP/flexran_agent_common_internal.c
+++ b/openair2/ENB_APP/flexran_agent_common_internal.c
@@ -159,7 +159,7 @@ int parse_enb_id(mid_t mod_id, yaml_parser_t *parser) {
       }
       // Check what key needs to be set
       // use eNB egistered
-      if (mac_agent_registered[mod_id]) {
+      if (flexran_agent_get_mac_xface(mod_id)) {
 	LOG_I(ENB_APP, "Setting parameter for eNB %s\n", event.data.scalar.value);
 	if (strcmp((char *) event.data.scalar.tag, YAML_INT_TAG) == 0) { // if int 
 	  if ((strtol((char *) event.data.scalar.value, &endptr, 10))== mod_id ) { // enb_id == mod_id: right enb instance to be configured
@@ -542,7 +542,7 @@ int apply_parameter_modification(void *parameter, yaml_parser_t *parser) {
 
 void initiate_soft_restart(module_id_t mod_id, Protocol__FlexCellConfig *c)
 {
-  uint8_t cc_id = c->has_cell_id ? c->cell_id : 0;
+  const uint8_t cc_id = 0;
   if (c->has_eutra_band) {
     flexran_agent_set_operating_eutra_band(mod_id, cc_id, c->eutra_band);
     LOG_I(ENB_APP, "Setting eutra_band to %d\n", c->eutra_band);
diff --git a/openair2/ENB_APP/flexran_agent_defs.h b/openair2/ENB_APP/flexran_agent_defs.h
index 57265b38b74a654a60e57411125cf94aeda3a425..b97e56092da7013169633c75fdcb36d807910883 100644
--- a/openair2/ENB_APP/flexran_agent_defs.h
+++ b/openair2/ENB_APP/flexran_agent_defs.h
@@ -138,14 +138,14 @@ typedef enum {
   FLEXRAN_AGENT_TIMER_STATE_MAX,
 } flexran_agent_timer_state_t;
 
-#define FLEXRAN_CAP_LOPHY 1
-#define FLEXRAN_CAP_HIPHY 2
-#define FLEXRAN_CAP_LOMAC 4
-#define FLEXRAN_CAP_HIMAC 8
-#define FLEXRAN_CAP_RLC   16
-#define FLEXRAN_CAP_PDCP  32
-#define FLEXRAN_CAP_SDAP  64
-#define FLEXRAN_CAP_RRC   128
+#define FLEXRAN_CAP_LOPHY(cApS) (((cApS) & (1 << PROTOCOL__FLEX_BS_CAPABILITY__LOPHY)) > 0)
+#define FLEXRAN_CAP_HIPHY(cApS) (((cApS) & (1 << PROTOCOL__FLEX_BS_CAPABILITY__HIPHY)) > 0)
+#define FLEXRAN_CAP_LOMAC(cApS) (((cApS) & (1 << PROTOCOL__FLEX_BS_CAPABILITY__LOMAC)) > 0)
+#define FLEXRAN_CAP_HIMAC(cApS) (((cApS) & (1 << PROTOCOL__FLEX_BS_CAPABILITY__HIMAC)) > 0)
+#define FLEXRAN_CAP_RLC(cApS)   (((cApS) & (1 << PROTOCOL__FLEX_BS_CAPABILITY__RLC))   > 0)
+#define FLEXRAN_CAP_PDCP(cApS)  (((cApS) & (1 << PROTOCOL__FLEX_BS_CAPABILITY__PDCP))  > 0)
+#define FLEXRAN_CAP_SDAP(cApS)  (((cApS) & (1 << PROTOCOL__FLEX_BS_CAPABILITY__SDAP))  > 0)
+#define FLEXRAN_CAP_RRC(cApS)   (((cApS) & (1 << PROTOCOL__FLEX_BS_CAPABILITY__RRC))   > 0)
 
 typedef enum {
   ENB_NORMAL_OPERATION = 0x0,
@@ -162,8 +162,6 @@ typedef struct {
   char    *cache_name;
 
   mid_t    mod_id;
-  uint64_t agent_id;
-  uint8_t  capability_mask;
 
   /* lock for waiting before starting or soft-restart */
   pthread_cond_t      cond_node_ctrl;
diff --git a/openair2/ENB_APP/flexran_agent_extern.h b/openair2/ENB_APP/flexran_agent_extern.h
index ae77e9227aa960afa13823ff9fe67996253d356a..e1dec8506ce6c257429d773981c3edd2bbb9d91d 100644
--- a/openair2/ENB_APP/flexran_agent_extern.h
+++ b/openair2/ENB_APP/flexran_agent_extern.h
@@ -31,27 +31,22 @@
 #define __FLEXRAN_AGENT_EXTERN_H__
 
 #include "flexran_agent_defs.h"
+#include "flexran_agent_phy_defs.h"
 #include "flexran_agent_mac_defs.h"
 #include "flexran_agent_rrc_defs.h"
 #include "flexran_agent_pdcp_defs.h"
 
-/* Control module interface for the communication of the MAC Control Module with the agent */
-extern AGENT_MAC_xface *agent_mac_xface[NUM_MAX_ENB];
+/* Control module interface for the communication of the PHY control module with the agent */
+AGENT_PHY_xface *flexran_agent_get_phy_xface(mid_t mod_id);
 
-/* Flag indicating whether the VSFs for the MAC control module have been registered */
-extern unsigned int mac_agent_registered[NUM_MAX_ENB];
+/* Control module interface for the communication of the MAC Control Module with the agent */
+AGENT_MAC_xface *flexran_agent_get_mac_xface(mid_t mod_id);
 
 /* Control module interface for the communication of the RRC Control Module with the agent */
-extern AGENT_RRC_xface *agent_rrc_xface[NUM_MAX_ENB];
-
-/* Flag indicating whether the VSFs for the RRC control module have been registered */
-extern unsigned int rrc_agent_registered[NUM_MAX_ENB];
+AGENT_RRC_xface *flexran_agent_get_rrc_xface(mid_t mod_id);
 
 /* Control module interface for the communication of the RRC Control Module with the agent */
-extern AGENT_PDCP_xface *agent_pdcp_xface[NUM_MAX_ENB];
-
-/* Flag indicating whether the VSFs for the RRC control module have been registered */
-extern unsigned int pdcp_agent_registered[NUM_MAX_ENB];
+AGENT_PDCP_xface *flexran_agent_get_pdcp_xface(mid_t mod_id);
 
 /* Requried to know which UEs had a harq updated over some subframe */
 extern int harq_pid_updated[NUM_MAX_UE][8];
diff --git a/openair2/ENB_APP/flexran_agent_handler.c b/openair2/ENB_APP/flexran_agent_handler.c
index 74ea5bfa1fa80fa69d59a0af958bb7985f56aaa3..9ffb1e6cecef63c49b4f38da4d057c4954c3664b 100644
--- a/openair2/ENB_APP/flexran_agent_handler.c
+++ b/openair2/ENB_APP/flexran_agent_handler.c
@@ -63,7 +63,7 @@ flexran_agent_message_destruction_callback message_destruction_callback[] = {
   flexran_agent_destroy_echo_request,
   flexran_agent_destroy_echo_reply,
   flexran_agent_destroy_stats_request,
-  flexran_agent_mac_destroy_stats_reply,
+  flexran_agent_destroy_stats_reply,
   flexran_agent_mac_destroy_sf_trigger,
   flexran_agent_mac_destroy_sr_info,
   flexran_agent_destroy_enb_config_request,
@@ -90,7 +90,8 @@ Protocol__FlexranMessage* flexran_agent_handle_message (mid_t mod_id,
 							uint8_t *data, 
 							uint32_t size){
   
-  Protocol__FlexranMessage *decoded_message, *reply_message;
+  Protocol__FlexranMessage *decoded_message = NULL;
+  Protocol__FlexranMessage *reply_message = NULL;
   err_code_t err_code;
   DevAssert(data != NULL);
 
@@ -113,7 +114,7 @@ Protocol__FlexranMessage* flexran_agent_handle_message (mid_t mod_id,
   err_code = ((*agent_messages_callback[decoded_message->msg_case-1][decoded_message->msg_dir-1])(mod_id, (void *) decoded_message, &reply_message));
   if ( err_code < 0 ){
     goto error;
-  } else if (err_code == 1) { //If err_code > 1, we do not want to dispose the message yet
+  } else if (err_code == 0) { //If err_code > 1, we do not want to dispose the message yet
     protocol__flexran_message__free_unpacked(decoded_message, NULL);
   }
   return reply_message;
@@ -204,13 +205,12 @@ int flexran_agent_handle_stats(mid_t mod_id, const void *params, Protocol__Flexr
   // TODO: Must resolve conflicts among stats requests
 
   int i;
-  err_code_t err_code;
+  err_code_t err_code = 0;
   xid_t xid;
   uint32_t usec_interval, sec_interval;
 
   //TODO: We do not deal with multiple CCs at the moment and eNB id is 0
   int enb_id = mod_id;
-  int UE_id;
 
   //eNB_MAC_INST *eNB = &eNB_mac_inst[enb_id];
   //UE_list_t *eNB_UE_list=  &eNB->UE_list;
@@ -242,91 +242,115 @@ int flexran_agent_handle_stats(mid_t mod_id, const void *params, Protocol__Flexr
       //Create a list of all eNB RNTIs and cells
 
       //Set the number of UEs and create list with their RNTIs stats configs
-      report_config.nr_ue = flexran_get_num_ues(mod_id); //eNB_UE_list->num_UEs
-      report_config.ue_report_type = (ue_report_type_t *) malloc(sizeof(ue_report_type_t) * report_config.nr_ue);
+      report_config.nr_ue = 0;
+      if (flexran_agent_get_rrc_xface(mod_id))
+        report_config.nr_ue = flexran_get_rrc_num_ues(mod_id);
+      else if (flexran_agent_get_mac_xface(mod_id))
+        report_config.nr_ue = flexran_get_mac_num_ues(mod_id);
+
+      if (flexran_agent_get_rrc_xface(mod_id) && flexran_agent_get_mac_xface(mod_id)
+          && flexran_get_rrc_num_ues(mod_id) != flexran_get_mac_num_ues(mod_id)) {
+        const int nrrc = flexran_get_rrc_num_ues(mod_id);
+        const int nmac = flexran_get_mac_num_ues(mod_id);
+        report_config.nr_ue = nrrc < nmac ? nrrc : nmac;
+        LOG_E(FLEXRAN_AGENT, "%s(): different numbers of UEs in RRC (%d) and MAC (%d), reporting for %d UEs\n",
+              __func__, nrrc, nmac, report_config.nr_ue);
+      }
+      report_config.ue_report_type = malloc(sizeof(ue_report_type_t) * report_config.nr_ue);
       if (report_config.ue_report_type == NULL) {
-  // TODO: Add appropriate error code
-  err_code = -100;
-  goto error;
+        // TODO: Add appropriate error code
+        err_code = -100;
+        goto error;
+      }
+      if (flexran_agent_get_rrc_xface(mod_id)) {
+        rnti_t rntis[report_config.nr_ue];
+        flexran_get_rrc_rnti_list(mod_id, rntis, report_config.nr_ue);
+        for (i = 0; i < report_config.nr_ue; i++) {
+          report_config.ue_report_type[i].ue_rnti = rntis[i];
+          report_config.ue_report_type[i].ue_report_flags = ue_flags;
+        }
       }
-      for (i = 0; i < report_config.nr_ue; i++) {
-        UE_id = flexran_get_ue_id(mod_id, i);
-        report_config.ue_report_type[i].ue_rnti = flexran_get_ue_crnti(enb_id, UE_id); //eNB_UE_list->eNB_UE_stats[UE_PCCID(enb_id,i)][i].crnti;
-        report_config.ue_report_type[i].ue_report_flags = ue_flags;
+      if (flexran_agent_get_mac_xface(mod_id) && !flexran_agent_get_rrc_xface(mod_id)) {
+        for (i = 0; i < report_config.nr_ue; i++) {
+          const int UE_id = flexran_get_mac_ue_id(mod_id, i);
+          report_config.ue_report_type[i].ue_rnti = flexran_get_mac_ue_crnti(enb_id, UE_id);
+          report_config.ue_report_type[i].ue_report_flags = ue_flags;
+        }
       }
       //Set the number of CCs and create a list with the cell stats configs
       report_config.nr_cc = MAX_NUM_CCs;
-      report_config.cc_report_type = (cc_report_type_t *) malloc(sizeof(cc_report_type_t) * report_config.nr_cc);
+      report_config.cc_report_type = malloc(sizeof(cc_report_type_t) * report_config.nr_cc);
       if (report_config.cc_report_type == NULL) {
-  // TODO: Add appropriate error code
-  err_code = -100;
-  goto error;
+        // TODO: Add appropriate error code
+        err_code = -100;
+        goto error;
       }
       for (i = 0; i < report_config.nr_cc; i++) {
-  //TODO: Must fill in the proper cell ids
-  report_config.cc_report_type[i].cc_id = i;
-  report_config.cc_report_type[i].cc_report_flags = c_flags;
+        //TODO: Must fill in the proper cell ids
+        report_config.cc_report_type[i].cc_id = i;
+        report_config.cc_report_type[i].cc_report_flags = c_flags;
       }
       /* Check if request was periodical */
       if (comp_req->report_frequency == PROTOCOL__FLEX_STATS_REPORT_FREQ__FLSRF_PERIODICAL) {
-  /* Create a one off flexran message as an argument for the periodical task */
-  Protocol__FlexranMessage *timer_msg;
-  stats_request_config_t request_config;
-  request_config.report_type = PROTOCOL__FLEX_STATS_TYPE__FLST_COMPLETE_STATS;
-  request_config.report_frequency = PROTOCOL__FLEX_STATS_REPORT_FREQ__FLSRF_ONCE;
-  request_config.period = 0;
-  /* Need to make sure that the ue flags are saved (Bug) */
-  if (report_config.nr_ue == 0) {
-    report_config.nr_ue = 1;
-    report_config.ue_report_type = (ue_report_type_t *) malloc(sizeof(ue_report_type_t));
-     if (report_config.ue_report_type == NULL) {
-       // TODO: Add appropriate error code
-       err_code = -100;
-       goto error;
-     }
-     report_config.ue_report_type[0].ue_rnti = 0; // Dummy value
-     report_config.ue_report_type[0].ue_report_flags = ue_flags;
-  }
-  request_config.config = &report_config;
-  flexran_agent_stats_request(enb_id, xid, &request_config, &timer_msg);
-  /* Create a timer */
-  long timer_id = 0;
-  flexran_agent_timer_args_t *timer_args;
-  timer_args = malloc(sizeof(flexran_agent_timer_args_t));
-  memset (timer_args, 0, sizeof(flexran_agent_timer_args_t));
-  timer_args->mod_id = enb_id;
-  timer_args->msg = timer_msg;
-  /*Convert subframes to usec time*/
-  usec_interval = 1000*comp_req->sf;
-  sec_interval = 0;
-  /*add seconds if required*/
-  if (usec_interval >= 1000*1000) {
-    sec_interval = usec_interval/(1000*1000);
-    usec_interval = usec_interval%(1000*1000);
-  }
-  flexran_agent_create_timer(sec_interval, usec_interval, FLEXRAN_AGENT_DEFAULT, enb_id, FLEXRAN_AGENT_TIMER_TYPE_PERIODIC, xid, flexran_agent_handle_timed_task,(void*) timer_args, &timer_id);
+        /* Create a one off flexran message as an argument for the periodical task */
+        Protocol__FlexranMessage *timer_msg;
+        stats_request_config_t request_config;
+        request_config.report_type = PROTOCOL__FLEX_STATS_TYPE__FLST_COMPLETE_STATS;
+        request_config.report_frequency = PROTOCOL__FLEX_STATS_REPORT_FREQ__FLSRF_ONCE;
+        request_config.period = 0;
+        /* Need to make sure that the ue flags are saved (Bug) */
+        if (report_config.nr_ue == 0) {
+          report_config.nr_ue = 1;
+          report_config.ue_report_type = malloc(sizeof(ue_report_type_t));
+           if (report_config.ue_report_type == NULL) {
+             // TODO: Add appropriate error code
+             err_code = -100;
+             goto error;
+           }
+           report_config.ue_report_type[0].ue_rnti = 0; // Dummy value
+           report_config.ue_report_type[0].ue_report_flags = ue_flags;
+        }
+        request_config.config = &report_config;
+        flexran_agent_stats_request(enb_id, xid, &request_config, &timer_msg);
+        /* Create a timer */
+        long timer_id = 0;
+        flexran_agent_timer_args_t *timer_args = malloc(sizeof(flexran_agent_timer_args_t));
+        memset (timer_args, 0, sizeof(flexran_agent_timer_args_t));
+        timer_args->mod_id = enb_id;
+        timer_args->msg = timer_msg;
+        /*Convert subframes to usec time*/
+        usec_interval = 1000*comp_req->sf;
+        sec_interval = 0;
+        /*add seconds if required*/
+        if (usec_interval >= 1000*1000) {
+          sec_interval = usec_interval/(1000*1000);
+          usec_interval = usec_interval%(1000*1000);
+        }
+        flexran_agent_create_timer(sec_interval, usec_interval, FLEXRAN_AGENT_DEFAULT,
+            enb_id, FLEXRAN_AGENT_TIMER_TYPE_PERIODIC, xid,
+            flexran_agent_handle_timed_task,(void*) timer_args, &timer_id);
       } else if (comp_req->report_frequency == PROTOCOL__FLEX_STATS_REPORT_FREQ__FLSRF_CONTINUOUS) {
-  /*If request was for continuous updates, disable the previous configuration and
-    set up a new one*/
-  flexran_agent_disable_cont_stats_update(mod_id);
-  stats_request_config_t request_config;
-  request_config.report_type = PROTOCOL__FLEX_STATS_TYPE__FLST_COMPLETE_STATS;
-  request_config.report_frequency = PROTOCOL__FLEX_STATS_REPORT_FREQ__FLSRF_ONCE;
-  request_config.period = 0;
-  /* Need to make sure that the ue flags are saved (Bug) */
-  if (report_config.nr_ue == 0) {
-    report_config.nr_ue = 1;
-    report_config.ue_report_type = (ue_report_type_t *) malloc(sizeof(ue_report_type_t));
-    if (report_config.ue_report_type == NULL) {
-      // TODO: Add appropriate error code
-      err_code = -100;
-      goto error;
-    }
-    report_config.ue_report_type[0].ue_rnti = 0; // Dummy value
-    report_config.ue_report_type[0].ue_report_flags = ue_flags;
-  }
-  request_config.config = &report_config;
-  flexran_agent_enable_cont_stats_update(enb_id, xid, &request_config);
+        /*If request was for continuous updates, disable the previous configuration and
+          set up a new one*/
+        flexran_agent_disable_cont_stats_update(mod_id);
+        stats_request_config_t request_config;
+        request_config.report_type = PROTOCOL__FLEX_STATS_TYPE__FLST_COMPLETE_STATS;
+        request_config.report_frequency = PROTOCOL__FLEX_STATS_REPORT_FREQ__FLSRF_ONCE;
+        request_config.period = 0;
+        /* Need to make sure that the ue flags are saved (Bug) */
+        if (report_config.nr_ue == 0) {
+          report_config.nr_ue = 1;
+          report_config.ue_report_type = malloc(sizeof(ue_report_type_t));
+          if (report_config.ue_report_type == NULL) {
+            // TODO: Add appropriate error code
+            err_code = -100;
+            goto error;
+          }
+          report_config.ue_report_type[0].ue_rnti = 0; // Dummy value
+          report_config.ue_report_type[0].ue_report_flags = ue_flags;
+        }
+        request_config.config = &report_config;
+        flexran_agent_enable_cont_stats_update(enb_id, xid, &request_config);
       }
     }
     break;
@@ -336,14 +360,14 @@ int flexran_agent_handle_stats(mid_t mod_id, const void *params, Protocol__Flexr
     report_config.nr_ue = 0;
     report_config.ue_report_type = NULL;
     report_config.nr_cc = cell_req->n_cell;
-    report_config.cc_report_type = (cc_report_type_t *) malloc(sizeof(cc_report_type_t) * report_config.nr_cc);
+    report_config.cc_report_type = malloc(sizeof(cc_report_type_t) * report_config.nr_cc);
     if (report_config.cc_report_type == NULL) {
       // TODO: Add appropriate error code
       err_code = -100;
       goto error;
     }
     for (i = 0; i < report_config.nr_cc; i++) {
-  //TODO: Must fill in the proper cell ids
+      //TODO: Must fill in the proper cell ids
       report_config.cc_report_type[i].cc_id = cell_req->cell[i];
       report_config.cc_report_type[i].cc_report_flags = cell_req->flags;
     }
@@ -354,14 +378,14 @@ int flexran_agent_handle_stats(mid_t mod_id, const void *params, Protocol__Flexr
     report_config.nr_cc = 0;
     report_config.cc_report_type = NULL;
     report_config.nr_ue = ue_req->n_rnti;
-    report_config.ue_report_type = (ue_report_type_t *) malloc(sizeof(ue_report_type_t) * report_config.nr_ue);
+    report_config.ue_report_type = malloc(sizeof(ue_report_type_t) * report_config.nr_ue);
     if (report_config.ue_report_type == NULL) {
       // TODO: Add appropriate error code
       err_code = -100;
       goto error;
     }
     for (i = 0; i < report_config.nr_ue; i++) {
-      UE_id = flexran_get_ue_id(mod_id, i);
+      const int UE_id = flexran_get_mac_ue_id(mod_id, i);
       report_config.ue_report_type[i].ue_rnti = ue_req->rnti[UE_id];
       report_config.ue_report_type[i].ue_report_flags = ue_req->flags;
     }
@@ -372,18 +396,20 @@ int flexran_agent_handle_stats(mid_t mod_id, const void *params, Protocol__Flexr
     goto error;
   }
 
-   if (flexran_agent_stats_reply(enb_id, xid, &report_config, msg )){  
-      err_code = PROTOCOL__FLEXRAN_ERR__MSG_BUILD;
-      goto error;
-    }
+  if (flexran_agent_stats_reply(enb_id, xid, &report_config, msg )) {
+    err_code = PROTOCOL__FLEXRAN_ERR__MSG_BUILD;
+    goto error;
+  }
 
-  free(report_config.ue_report_type);
-  free(report_config.cc_report_type);
+  if (report_config.ue_report_type)
+    free(report_config.ue_report_type);
+  if (report_config.cc_report_type)
+    free(report_config.cc_report_type);
 
   return 0;
 
  error :
-  LOG_E(FLEXRAN_AGENT, "errno %d occured\n", err_code);
+  LOG_E(FLEXRAN_AGENT, "%s(): errno %d occured\n", __func__, err_code);
   return err_code;
 }
 
@@ -429,8 +455,7 @@ int flexran_agent_stats_reply(mid_t enb_id, xid_t xid, const report_config_t *re
       protocol__flex_ue_stats_report__init(ue_report[i]);
       ue_report[i]->rnti = report_config->ue_report_type[i].ue_rnti;
       ue_report[i]->has_rnti = 1;
-      ue_report[i]->flags = report_config->ue_report_type[i].ue_report_flags;
-      ue_report[i]->has_flags = 1;
+      ue_report[i]->has_flags = 1; /* actual flags are filled in the CMs below */
   
   }
 
@@ -452,39 +477,30 @@ int flexran_agent_stats_reply(mid_t enb_id, xid_t xid, const report_config_t *re
       protocol__flex_cell_stats_report__init(cell_report[i]);
       cell_report[i]->carrier_index = report_config->cc_report_type[i].cc_id;
       cell_report[i]->has_carrier_index = 1;
-      cell_report[i]->flags = report_config->cc_report_type[i].cc_report_flags;
-      cell_report[i]->has_flags = 1;
+      cell_report[i]->has_flags = 1; /* actual flags are filled in the CMs below */
 
   }
 
-      /*
-      MAC reply split
-     */
-
-
-    if (flexran_agent_mac_stats_reply(enb_id, report_config,  ue_report, cell_report) < 0 ) {
-        err_code = PROTOCOL__FLEXRAN_ERR__MSG_BUILD;
-        goto error;
-    }
-
-    /*
-      RRC reply split
-     */
+  /* MAC reply split */
+  if (flexran_agent_get_mac_xface(enb_id)
+      && flexran_agent_mac_stats_reply(enb_id, report_config,  ue_report, cell_report) < 0) {
+    err_code = PROTOCOL__FLEXRAN_ERR__MSG_BUILD;
+    goto error;
+  }
 
-    if (flexran_agent_rrc_stats_reply(enb_id, report_config,  ue_report, cell_report) < 0 ) {
-        err_code = PROTOCOL__FLEXRAN_ERR__MSG_BUILD;
-        goto error;
-    }
-   
+  /* RRC reply split */
+  if (flexran_agent_get_rrc_xface(enb_id)
+      && flexran_agent_rrc_stats_reply(enb_id, report_config,  ue_report, cell_report) < 0) {
+    err_code = PROTOCOL__FLEXRAN_ERR__MSG_BUILD;
+    goto error;
+  }
 
-    /*
-      PDCP reply split
-    */
-    
-    if (flexran_agent_pdcp_stats_reply(enb_id, report_config,  ue_report, cell_report) < 0 ) {
-      err_code = PROTOCOL__FLEXRAN_ERR__MSG_BUILD;
-      goto error;
-    }
+  /* PDCP reply split */
+  if (flexran_agent_get_pdcp_xface(enb_id)
+      && flexran_agent_pdcp_stats_reply(enb_id, report_config,  ue_report, cell_report) < 0) {
+    err_code = PROTOCOL__FLEXRAN_ERR__MSG_BUILD;
+    goto error;
+  }
 
        
   stats_reply_msg->cell_report = cell_report;
@@ -636,61 +652,26 @@ int flexran_agent_destroy_stats_request(Protocol__FlexranMessage *msg) {
   return -1;
 }
 
-/*
-  Top Level Update 
- */
-
-void flexran_agent_send_update_stats(mid_t mod_id) {
-
-  Protocol__FlexranMessage *current_report = NULL;
-  void *data;
-  int size;
-  err_code_t err_code;
-  int priority = 0;
-  
-  if (pthread_mutex_lock(stats_context[mod_id].mutex)) {
-    goto error;
+int flexran_agent_destroy_stats_reply(Protocol__FlexranMessage *msg)
+{
+  if (msg->msg_case != PROTOCOL__FLEXRAN_MESSAGE__MSG_STATS_REPLY_MSG) {
+    LOG_E(FLEXRAN_AGENT, "%s(): message is not a msg_stats_reply\n", __func__);
+    return -1;
   }
 
-  if (stats_context[mod_id].cont_update == 1) {
-  
-    /*Create a fresh report with the required flags*/
-    err_code = flexran_agent_handle_stats(mod_id, (void *) stats_context[mod_id].stats_req, &current_report);
-    if (err_code < 0) {
-      goto error;
-    }
-  }
-  /* /\*TODO:Check if a previous reports exists and if yes, generate a report */
-  /*  *that is the diff between the old and the new report, */
-  /*  *respecting the thresholds. Otherwise send the new report*\/ */
-  /* if (stats_context[mod_id].prev_stats_reply != NULL) { */
-
-  /*   msg = flexran_agent_generate_diff_mac_stats_report(current_report, stats_context[mod_id].prev_stats_reply); */
-
-  /*   /\*Destroy the old stats*\/ */
-  /*    flexran_agent_destroy_flexran_message(stats_context[mod_id].prev_stats_reply); */
-  /* } */
-  /* /\*Use the current report for future comparissons*\/ */
-  /* stats_context[mod_id].prev_stats_reply = current_report; */
-
-
-  if (pthread_mutex_unlock(stats_context[mod_id].mutex)) {
-    goto error;
-  }
-
-  if (current_report != NULL){
-    data=flexran_agent_pack_message(current_report, &size);
-    /*Send any stats updates using the MAC channel of the eNB*/
-    if (flexran_agent_msg_send(mod_id, FLEXRAN_AGENT_MAC, data, size, priority)) {
-      err_code = PROTOCOL__FLEXRAN_ERR__MSG_ENQUEUING;
-      goto error;
-    }
-
-    LOG_D(FLEXRAN_AGENT,"sent message with size %d\n", size);
-    return;
-  }
- error:
-  LOG_D(FLEXRAN_AGENT, "Could not send sf trigger message\n");
+  flexran_agent_mac_destroy_stats_reply(msg->stats_reply_msg);
+  flexran_agent_rrc_destroy_stats_reply(msg->stats_reply_msg);
+  flexran_agent_pdcp_destroy_stats_reply(msg->stats_reply_msg);
+  for (int i = 0; i < msg->stats_reply_msg->n_cell_report; ++i)
+    free(msg->stats_reply_msg->cell_report[i]);
+  for (int i = 0; i < msg->stats_reply_msg->n_ue_report; ++i)
+    free(msg->stats_reply_msg->ue_report[i]);
+  free(msg->stats_reply_msg->cell_report);
+  free(msg->stats_reply_msg->ue_report);
+  free(msg->stats_reply_msg->header);
+  free(msg->stats_reply_msg);
+  free(msg);
+  return 0;
 }
 
 err_code_t flexran_agent_disable_cont_stats_update(mid_t mod_id) {
@@ -755,7 +736,7 @@ err_code_t flexran_agent_init_cont_stats_update(mid_t mod_id) {
   stats_context[mod_id].mutex = calloc(1, sizeof(pthread_mutex_t));
   if (stats_context[mod_id].mutex == NULL)
     goto error;
-  if (pthread_mutex_init(stats_context[mod_id].mutex, NULL))
+  if (pthread_mutex_init(stats_context[mod_id].mutex, NULL) != 0)
     goto error;
 
   return 0;
@@ -772,6 +753,5 @@ err_code_t flexran_agent_destroy_cont_stats_update(mid_t mod_id) {
   flexran_agent_destroy_flexran_message(stats_context[mod_id].prev_stats_reply);
   free(stats_context[mod_id].mutex);
 
-  // mac_agent_registered[mod_id] = 0;
   return 1;
 }
diff --git a/openair2/ENB_APP/flexran_agent_net_comm.c b/openair2/ENB_APP/flexran_agent_net_comm.c
index d5142e5456eeb10b86c6f7cd944929c0fdaf0804..0d1c52096dce1bc277a217c0dac5e93ce60f8144 100644
--- a/openair2/ENB_APP/flexran_agent_net_comm.c
+++ b/openair2/ENB_APP/flexran_agent_net_comm.c
@@ -53,7 +53,7 @@ int flexran_agent_msg_send(mid_t mod_id, agent_id_t agent_id, void *data, int si
   return -1;
 }
 
-int flexran_agent_msg_recv(mid_t mod_id, agent_id_t agent_id, void **data, int *size, int *priority) {
+int flexran_agent_msg_recv(mid_t mod_id, agent_id_t agent_id, void **data, int *priority) {
   /*Check if agent id is valid*/
   if (agent_id >= FLEXRAN_AGENT_MAX || agent_id < 0) {
     goto error;
@@ -66,7 +66,7 @@ int flexran_agent_msg_recv(mid_t mod_id, agent_id_t agent_id, void **data, int *
     goto error;
   }
   
-  return channel->msg_recv(data, size, priority, channel->channel_info);
+  return channel->msg_recv(data, priority, channel->channel_info);
   
  error:
   LOG_E(FLEXRAN_AGENT, "No channel registered for agent with id %d\n", agent_id);
@@ -104,7 +104,7 @@ void flexran_agent_unregister_channel(mid_t mod_id, agent_id_t agent_id) {
 
 int flexran_agent_create_channel(void *channel_info,
 				 int (*msg_send)(void *data, int size, int priority, void *channel_info),
-				 int (*msg_recv)(void **data, int *size, int *priority, void *channel_info),
+				 int (*msg_recv)(void **data, int *priority, void *channel_info),
 				 void (*release)(flexran_agent_channel_t *channel)) {
   
   int channel_id = ++flexran_agent_channel_id;
diff --git a/openair2/ENB_APP/flexran_agent_net_comm.h b/openair2/ENB_APP/flexran_agent_net_comm.h
index 2f59b0f7a379f90659e127ac2244cbba935b4919..4d012989fd80fe0788b58f8c40451f7aa78d63ef 100644
--- a/openair2/ENB_APP/flexran_agent_net_comm.h
+++ b/openair2/ENB_APP/flexran_agent_net_comm.h
@@ -39,7 +39,7 @@ int channel_id;
 void *channel_info;
 /*Callbacks for channel message Tx and Rx*/
 int (*msg_send)(void *data, int size, int priority, void *channel_info);
-int (*msg_recv)(void **data, int *size, int *priority, void *channel_info);
+int (*msg_recv)(void **data, int *priority, void *channel_info);
 void (*release)(struct flexran_agent_channel_s *channel);
 } flexran_agent_channel_t;
 
@@ -49,7 +49,7 @@ typedef struct flexran_agent_channel_instance_s{
 
 /*Send and receive messages using the channel registered for a specific agent*/
 int flexran_agent_msg_send(mid_t mod_id, agent_id_t agent_id, void *data, int size, int priority);
-int flexran_agent_msg_recv(mid_t mod_id, agent_id_t agent_id, void **data, int *size, int *priority);
+int flexran_agent_msg_recv(mid_t mod_id, agent_id_t agent_id, void **data, int *priority);
 
 /*Register a channel to an agent. Use FLEXRAN_AGENT_MAX to register the
  *same channel to all agents*/
@@ -61,7 +61,7 @@ void flexran_agent_unregister_channel(mid_t mod_id, agent_id_t agent_id);
 /*Create a new channel. Returns the id of the new channel or negative number otherwise*/
 int flexran_agent_create_channel(void *channel_info,
 				 int (*msg_send)(void *data, int size, int priority, void *channel_info),
-				 int (*msg_recv)(void **data, int *size, int *priority, void *channel_info),
+				 int (*msg_recv)(void **data, int *priority, void *channel_info),
 				 void (*release)(flexran_agent_channel_t *channel));
 
 /*Unregister a channel from all agents and destroy it. Returns 0 in case of success*/
diff --git a/openair2/ENB_APP/flexran_agent_ran_api.c b/openair2/ENB_APP/flexran_agent_ran_api.c
index 8ada30cc82d02c36001eabe977ff1c9025f94ed5..500f4f1f3a146cdab816d697efc9a71da2c5098d 100644
--- a/openair2/ENB_APP/flexran_agent_ran_api.c
+++ b/openair2/ENB_APP/flexran_agent_ran_api.c
@@ -74,6 +74,7 @@ sub_frame_t flexran_get_current_subframe(mid_t mod_id)
 /* Why uint16_t, frame_t and sub_frame_t are defined as uint32_t? */
 uint16_t flexran_get_sfn_sf(mid_t mod_id)
 {
+  if (!mac_is_present(mod_id)) return 0;
   frame_t frame = flexran_get_current_system_frame_num(mod_id);
   sub_frame_t subframe = flexran_get_current_subframe(mod_id);
   uint16_t sfn_sf, frame_mask, sf_mask;
@@ -87,6 +88,7 @@ uint16_t flexran_get_sfn_sf(mid_t mod_id)
 
 uint16_t flexran_get_future_sfn_sf(mid_t mod_id, int ahead_of_time)
 {
+  if (!mac_is_present(mod_id)) return 0;
   frame_t frame = flexran_get_current_system_frame_num(mod_id);
   sub_frame_t subframe = flexran_get_current_subframe(mod_id);
   uint16_t sfn_sf, frame_mask, sf_mask;
@@ -107,13 +109,42 @@ uint16_t flexran_get_future_sfn_sf(mid_t mod_id, int ahead_of_time)
   return sfn_sf;
 }
 
-int flexran_get_num_ues(mid_t mod_id)
+int flexran_get_mac_num_ues(mid_t mod_id)
 {
   if (!mac_is_present(mod_id)) return 0;
   return RC.mac[mod_id]->UE_list.num_UEs;
 }
 
-int flexran_get_ue_id(mid_t mod_id, int i)
+int flexran_get_num_ue_lcs(mid_t mod_id, mid_t ue_id)
+{
+  if (!mac_is_present(mod_id)) return 0;
+  // Not sure whether this is needed: if (!rrc_is_present(mod_id)) return 0;
+  const rnti_t rnti = flexran_get_mac_ue_crnti(mod_id, ue_id);
+  const int s = mac_eNB_get_rrc_status(mod_id, rnti);
+  if (s < RRC_CONNECTED)
+    return 0;
+  else if (s == RRC_CONNECTED)
+    return 1;
+  else
+    return 3;
+}
+
+int flexran_get_mac_ue_id_rnti(mid_t mod_id, rnti_t rnti)
+{
+  int n;
+  if (!mac_is_present(mod_id)) return 0;
+  /* get the (active) UE with RNTI i */
+  for (n = 0; n < MAX_MOBILES_PER_ENB; ++n) {
+    if (RC.mac[mod_id]->UE_list.active[n] == TRUE
+        && rnti == UE_RNTI(mod_id, n)) {
+      return n;
+    }
+  }
+  return 0;
+
+}
+
+int flexran_get_mac_ue_id(mid_t mod_id, int i)
 {
   int n;
   if (!mac_is_present(mod_id)) return 0;
@@ -128,8 +159,9 @@ int flexran_get_ue_id(mid_t mod_id, int i)
   return 0;
 }
 
-rnti_t flexran_get_ue_crnti(mid_t mod_id, mid_t ue_id)
+rnti_t flexran_get_mac_ue_crnti(mid_t mod_id, mid_t ue_id)
 {
+  if (!mac_is_present(mod_id)) return 0;
   return UE_RNTI(mod_id, ue_id);
 }
 
@@ -153,7 +185,8 @@ uint8_t flexran_get_ue_wcqi(mid_t mod_id, mid_t ue_id)
 
 rlc_buffer_occupancy_t flexran_get_tx_queue_size(mid_t mod_id, mid_t ue_id, logical_chan_id_t channel_id)
 {
-  rnti_t rnti = flexran_get_ue_crnti(mod_id, ue_id);
+  if (!mac_is_present(mod_id)) return 0;
+  rnti_t rnti = flexran_get_mac_ue_crnti(mod_id, ue_id);
   frame_t frame = flexran_get_current_frame(mod_id);
   sub_frame_t subframe = flexran_get_current_subframe(mod_id);
   mac_rlc_status_resp_t rlc_status = mac_rlc_status_ind(mod_id,rnti, mod_id, frame, subframe, ENB_FLAG_YES,MBMS_FLAG_NO, channel_id, 0
@@ -166,7 +199,8 @@ rlc_buffer_occupancy_t flexran_get_tx_queue_size(mid_t mod_id, mid_t ue_id, logi
 
 rlc_buffer_occupancy_t flexran_get_num_pdus_buffer(mid_t mod_id, mid_t ue_id, logical_chan_id_t channel_id)
 {
-  rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id);
+  if (!mac_is_present(mod_id)) return 0;
+  rnti_t rnti = flexran_get_mac_ue_crnti(mod_id,ue_id);
   frame_t frame = flexran_get_current_frame(mod_id);
   sub_frame_t subframe = flexran_get_current_subframe(mod_id);
   mac_rlc_status_resp_t rlc_status = mac_rlc_status_ind(mod_id,rnti, mod_id, frame, subframe, ENB_FLAG_YES,MBMS_FLAG_NO, channel_id, 0
@@ -179,7 +213,8 @@ rlc_buffer_occupancy_t flexran_get_num_pdus_buffer(mid_t mod_id, mid_t ue_id, lo
 
 frame_t flexran_get_hol_delay(mid_t mod_id, mid_t ue_id, logical_chan_id_t channel_id)
 {
-  rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id);
+  if (!mac_is_present(mod_id)) return 0;
+  rnti_t rnti = flexran_get_mac_ue_crnti(mod_id,ue_id);
   frame_t frame = flexran_get_current_frame(mod_id);
   sub_frame_t subframe = flexran_get_current_subframe(mod_id);
   mac_rlc_status_resp_t rlc_status = mac_rlc_status_ind(mod_id, rnti, mod_id, frame, subframe, ENB_FLAG_YES, MBMS_FLAG_NO, channel_id, 0
@@ -225,7 +260,11 @@ uint32_t flexran_get_total_size_dl_mac_sdus(mid_t mod_id, mid_t ue_id, int cc_id
 uint32_t flexran_get_total_size_ul_mac_sdus(mid_t mod_id, mid_t ue_id, int cc_id)
 {
   if (!mac_is_present(mod_id)) return 0;
-  return RC.mac[mod_id]->eNB_stats[cc_id].total_ulsch_bytes_rx;
+  uint64_t bytes = 0;
+  for (int i = 0; i < NB_RB_MAX; ++i) {
+    bytes += RC.mac[mod_id]->UE_list.eNB_UE_stats[cc_id][ue_id].num_bytes_rx[i];
+  }
+  return bytes;
 }
 
 uint32_t flexran_get_TBS_dl(mid_t mod_id, mid_t ue_id, int cc_id)
@@ -455,7 +494,7 @@ int flexran_get_harq(mid_t       mod_id,
   
   if (mac_xface_not_ready()) return 0 ;
 
-  uint16_t rnti = flexran_get_ue_crnti(mod_id,ue_id);
+  uint16_t rnti = flexran_get_mac_ue_crnti(mod_id,ue_id);
   if (harq_flag == openair_harq_DL){
 
       mac_xface->get_ue_active_harq_pid(mod_id,CC_id,rnti,frame,subframe,&harq_pid,&harq_round,openair_harq_DL);
@@ -528,10 +567,16 @@ uint8_t flexran_get_hopping_offset(mid_t mod_id, uint8_t cc_id)
   return RC.eNB[mod_id][cc_id]->frame_parms.pusch_config_common.pusch_HoppingOffset;
 }
 
-PUSCH_HOPPING_t flexran_get_hopping_mode(mid_t mod_id, uint8_t cc_id)
+Protocol__FlexHoppingMode flexran_get_hopping_mode(mid_t mod_id, uint8_t cc_id)
 {
-  if (!phy_is_present(mod_id, cc_id)) return 0;
-  return RC.eNB[mod_id][cc_id]->frame_parms.pusch_config_common.hoppingMode;
+  if (!phy_is_present(mod_id, cc_id)) return -1;
+  switch (RC.eNB[mod_id][cc_id]->frame_parms.pusch_config_common.hoppingMode) {
+  case interSubFrame:
+    return PROTOCOL__FLEX_HOPPING_MODE__FLHM_INTER;
+  case intraAndInterSubFrame:
+    return PROTOCOL__FLEX_HOPPING_MODE__FLHM_INTERINTRA;
+  }
+  return -1;
 }
 
 uint8_t flexran_get_n_SB(mid_t mod_id, uint8_t cc_id)
@@ -540,33 +585,41 @@ uint8_t flexran_get_n_SB(mid_t mod_id, uint8_t cc_id)
   return RC.eNB[mod_id][cc_id]->frame_parms.pusch_config_common.n_SB;
 }
 
-uint8_t flexran_get_enable64QAM(mid_t mod_id, uint8_t cc_id)
+Protocol__FlexQam flexran_get_enable64QAM(mid_t mod_id, uint8_t cc_id)
 {
   if (!phy_is_present(mod_id, cc_id)) return 0;
-  return RC.eNB[mod_id][cc_id]->frame_parms.pusch_config_common.enable64QAM;
+  if (RC.eNB[mod_id][cc_id]->frame_parms.pusch_config_common.enable64QAM == TRUE)
+    return PROTOCOL__FLEX_QAM__FLEQ_MOD_64QAM;
+  else
+    return PROTOCOL__FLEX_QAM__FLEQ_MOD_16QAM;
 }
 
-PHICH_DURATION_t flexran_get_phich_duration(mid_t mod_id, uint8_t cc_id)
+Protocol__FlexPhichDuration flexran_get_phich_duration(mid_t mod_id, uint8_t cc_id)
 {
-  if (!phy_is_present(mod_id, cc_id)) return 0;
-  return RC.eNB[mod_id][cc_id]->frame_parms.phich_config_common.phich_duration;
+  if (!phy_is_present(mod_id, cc_id)) return -1;
+  switch (RC.eNB[mod_id][cc_id]->frame_parms.phich_config_common.phich_duration) {
+  case normal:
+    return PROTOCOL__FLEX_PHICH_DURATION__FLPD_NORMAL;
+  case extended:
+    return PROTOCOL__FLEX_PHICH_DURATION__FLPD_EXTENDED;
+  }
+  return -1;
 }
 
-int flexran_get_phich_resource(mid_t mod_id, uint8_t cc_id)
+Protocol__FlexPhichResource flexran_get_phich_resource(mid_t mod_id, uint8_t cc_id)
 {
-  if (!phy_is_present(mod_id, cc_id)) return 0;
+  if (!phy_is_present(mod_id, cc_id)) return -1;
   switch (RC.eNB[mod_id][cc_id]->frame_parms.phich_config_common.phich_resource) {
   case oneSixth:
-    return 0;
+    return PROTOCOL__FLEX_PHICH_RESOURCE__FLPR_ONE_SIXTH;
   case half:
-    return 1;
+    return PROTOCOL__FLEX_PHICH_RESOURCE__FLPR_HALF;
   case one:
-    return 2;
+    return PROTOCOL__FLEX_PHICH_RESOURCE__FLPR_ONE;
   case two:
-    return 3;
-  default:
-    return -1;
+    return PROTOCOL__FLEX_PHICH_RESOURCE__FLPR_TWO;
   }
+  return -1;
 }
 
 uint16_t flexran_get_n1pucch_an(mid_t mod_id, uint8_t cc_id)
@@ -605,16 +658,28 @@ uint8_t flexran_get_maxHARQ_Msg3Tx(mid_t mod_id, uint8_t cc_id)
   return RC.eNB[mod_id][cc_id]->frame_parms.maxHARQ_Msg3Tx;
 }
 
-lte_prefix_type_t flexran_get_ul_cyclic_prefix_length(mid_t mod_id, uint8_t cc_id)
+Protocol__FlexUlCyclicPrefixLength flexran_get_ul_cyclic_prefix_length(mid_t mod_id, uint8_t cc_id)
 {
-  if (!phy_is_present(mod_id, cc_id)) return 0;
-  return RC.eNB[mod_id][cc_id]->frame_parms.Ncp_UL;
+  if (!phy_is_present(mod_id, cc_id)) return -1;
+  switch (RC.eNB[mod_id][cc_id]->frame_parms.Ncp_UL) {
+  case EXTENDED:
+    return PROTOCOL__FLEX_UL_CYCLIC_PREFIX_LENGTH__FLUCPL_EXTENDED;
+  case NORMAL:
+    return PROTOCOL__FLEX_UL_CYCLIC_PREFIX_LENGTH__FLUCPL_NORMAL;
+  }
+  return -1;
 }
 
-lte_prefix_type_t flexran_get_dl_cyclic_prefix_length(mid_t mod_id, uint8_t cc_id)
+Protocol__FlexDlCyclicPrefixLength flexran_get_dl_cyclic_prefix_length(mid_t mod_id, uint8_t cc_id)
 {
-  if (!phy_is_present(mod_id, cc_id)) return 0;
-  return RC.eNB[mod_id][cc_id]->frame_parms.Ncp;
+  if (!phy_is_present(mod_id, cc_id)) return -1;
+  switch (RC.eNB[mod_id][cc_id]->frame_parms.Ncp) {
+  case EXTENDED:
+    return PROTOCOL__FLEX_DL_CYCLIC_PREFIX_LENGTH__FLDCPL_EXTENDED;
+  case NORMAL:
+    return PROTOCOL__FLEX_DL_CYCLIC_PREFIX_LENGTH__FLDCPL_NORMAL;
+  }
+  return -1;
 }
 
 uint16_t flexran_get_cell_id(mid_t mod_id, uint8_t cc_id)
@@ -721,27 +786,49 @@ uint8_t flexran_get_num_pdcch_symb(mid_t mod_id, uint8_t cc_id)
  * Get Messages for UE Configuration Reply
  * ************************************
  */
+int flexran_get_rrc_num_ues(mid_t mod_id)
+{
+  if (!rrc_is_present(mod_id)) return 0;
+  return RC.rrc[mod_id]->Nb_ue;
+}
 
+rnti_t flexran_get_rrc_rnti_nth_ue(mid_t mod_id, int index)
+{
+  if (!rrc_is_present(mod_id)) return 0;
+  struct rrc_eNB_ue_context_s* ue_context_p = NULL;
+  RB_FOREACH(ue_context_p, rrc_ue_tree_s, &RC.rrc[mod_id]->rrc_ue_head) {
+    if (index == 0) return ue_context_p->ue_context.rnti;
+    --index;
+  }
+  return 0;
+}
 
-LTE_TimeAlignmentTimer_t flexran_get_time_alignment_timer(mid_t mod_id, mid_t ue_id)
+int flexran_get_rrc_rnti_list(mid_t mod_id, rnti_t *list, int max_list)
 {
-  if (!rrc_is_present(mod_id)) return -1;
+  if (!rrc_is_present(mod_id)) return 0;
+  int n = 0;
+  struct rrc_eNB_ue_context_s* ue_context_p = NULL;
+  RB_FOREACH(ue_context_p, rrc_ue_tree_s, &RC.rrc[mod_id]->rrc_ue_head) {
+    if (n >= max_list) break;
+    list[n] = ue_context_p->ue_context.rnti;
+    ++n;
+  }
+  return n;
+}
 
-  rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id);
+LTE_TimeAlignmentTimer_t  flexran_get_time_alignment_timer(mid_t mod_id, rnti_t rnti)
+{
+  if (!rrc_is_present(mod_id)) return -1;
   struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
-
   if (!ue_context_p) return -1;
   if (!ue_context_p->ue_context.mac_MainConfig) return -1;
   return ue_context_p->ue_context.mac_MainConfig->timeAlignmentTimerDedicated;
 }
 
-Protocol__FlexMeasGapConfigPattern flexran_get_meas_gap_config(mid_t mod_id, mid_t ue_id)
+Protocol__FlexMeasGapConfigPattern flexran_get_meas_gap_config(mid_t mod_id, rnti_t rnti)
 {
   if (!rrc_is_present(mod_id)) return -1;
-
-  rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id);
   struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
-
   if (!ue_context_p) return -1;
   if (!ue_context_p->ue_context.measGapConfig) return -1;
   if (ue_context_p->ue_context.measGapConfig->present != LTE_MeasGapConfig_PR_setup) return -1;
@@ -756,13 +843,10 @@ Protocol__FlexMeasGapConfigPattern flexran_get_meas_gap_config(mid_t mod_id, mid
 }
 
 
-long flexran_get_meas_gap_config_offset(mid_t mod_id, mid_t ue_id)
+long flexran_get_meas_gap_config_offset(mid_t mod_id, rnti_t rnti)
 {
   if (!rrc_is_present(mod_id)) return -1;
-
-  rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id);
   struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
-
   if (!ue_context_p) return -1;
   if (!ue_context_p->ue_context.measGapConfig) return -1;
   if (ue_context_p->ue_context.measGapConfig->present != LTE_MeasGapConfig_PR_setup) return -1;
@@ -776,13 +860,10 @@ long flexran_get_meas_gap_config_offset(mid_t mod_id, mid_t ue_id)
   }
 }
 
-uint8_t flexran_get_rrc_status(mid_t mod_id, mid_t ue_id)
+uint8_t flexran_get_rrc_status(mid_t mod_id, rnti_t rnti)
 {
   if (!rrc_is_present(mod_id)) return 0;
-
-  rnti_t rnti = flexran_get_ue_crnti(mod_id, ue_id);
   struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
-
   if (!ue_context_p) return RRC_INACTIVE;
   return ue_context_p->ue_context.Status;
 }
@@ -799,13 +880,10 @@ uint64_t flexran_get_ue_aggregated_max_bitrate_ul(mid_t mod_id, mid_t ue_id)
   return RC.mac[mod_id]->UE_list.UE_sched_ctrl[ue_id].ue_AggregatedMaximumBitrateUL;
 }
 
-int flexran_get_half_duplex(mid_t mod_id, mid_t ue_id)
+int flexran_get_half_duplex(mid_t mod_id, rnti_t rnti)
 {
   if (!rrc_is_present(mod_id)) return -1;
-
-  rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id);
   struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
-
   if (!ue_context_p) return -1;
   if (!ue_context_p->ue_context.UE_Capability) return -1;
   LTE_SupportedBandListEUTRA_t *bands = &ue_context_p->ue_context.UE_Capability->rf_Parameters.supportedBandListEUTRA;
@@ -815,13 +893,10 @@ int flexran_get_half_duplex(mid_t mod_id, mid_t ue_id)
   return 0;
 }
 
-int flexran_get_intra_sf_hopping(mid_t mod_id, mid_t ue_id)
+int flexran_get_intra_sf_hopping(mid_t mod_id, rnti_t rnti)
 {
   if (!rrc_is_present(mod_id)) return -1;
-
-  rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id);
   struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
-
   if (!ue_context_p) return -1;
   if (!ue_context_p->ue_context.UE_Capability) return -1;
   if (!ue_context_p->ue_context.UE_Capability->featureGroupIndicators) return -1;
@@ -833,13 +908,10 @@ int flexran_get_intra_sf_hopping(mid_t mod_id, mid_t ue_id)
   return (buf >> 7) & 1;
 }
 
-int flexran_get_type2_sb_1(mid_t mod_id, mid_t ue_id)
+int flexran_get_type2_sb_1(mid_t mod_id, rnti_t rnti)
 {
   if (!rrc_is_present(mod_id)) return -1;
-
-  rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id);
   struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
-
   if (!ue_context_p) return -1;
   if (!ue_context_p->ue_context.UE_Capability) return -1;
   if (!ue_context_p->ue_context.UE_Capability->featureGroupIndicators) return -1;
@@ -852,25 +924,19 @@ int flexran_get_type2_sb_1(mid_t mod_id, mid_t ue_id)
   return (buf >> 3) & 1;
 }
 
-long flexran_get_ue_category(mid_t mod_id, mid_t ue_id)
+long flexran_get_ue_category(mid_t mod_id, rnti_t rnti)
 {
   if (!rrc_is_present(mod_id)) return -1;
-
-  rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id);
   struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
-
   if (!ue_context_p) return -1;
   if (!ue_context_p->ue_context.UE_Capability) return -1;
   return ue_context_p->ue_context.UE_Capability->ue_Category;
 }
 
-int flexran_get_res_alloc_type1(mid_t mod_id, mid_t ue_id)
+int flexran_get_res_alloc_type1(mid_t mod_id, rnti_t rnti)
 {
   if (!rrc_is_present(mod_id)) return -1;
-
-  rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id);
   struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
-
   if (!ue_context_p) return -1;
   if (!ue_context_p->ue_context.UE_Capability) return -1;
   if (!ue_context_p->ue_context.UE_Capability->featureGroupIndicators) return -1;
@@ -882,24 +948,19 @@ int flexran_get_res_alloc_type1(mid_t mod_id, mid_t ue_id)
   return (buf >> 6) & 1;
 }
 
-long flexran_get_ue_transmission_mode(mid_t mod_id, mid_t ue_id)
+long flexran_get_ue_transmission_mode(mid_t mod_id, rnti_t rnti)
 {
   if (!rrc_is_present(mod_id)) return -1;
-
-  rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id);
   struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
-
   if (!ue_context_p) return -1;
   if (!ue_context_p->ue_context.physicalConfigDedicated) return -1;
   if (!ue_context_p->ue_context.physicalConfigDedicated->antennaInfo) return -1;
   return ue_context_p->ue_context.physicalConfigDedicated->antennaInfo->choice.explicitValue.transmissionMode;
 }
 
-BOOLEAN_t flexran_get_tti_bundling(mid_t mod_id, mid_t ue_id)
+BOOLEAN_t flexran_get_tti_bundling(mid_t mod_id, rnti_t rnti)
 {
   if (!rrc_is_present(mod_id)) return -1;
-
-  rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id);
   struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
   if (!ue_context_p) return -1;
   if (!ue_context_p->ue_context.mac_MainConfig) return -1;
@@ -907,65 +968,50 @@ BOOLEAN_t flexran_get_tti_bundling(mid_t mod_id, mid_t ue_id)
   return ue_context_p->ue_context.mac_MainConfig->ul_SCH_Config->ttiBundling;
 }
 
-long flexran_get_maxHARQ_TX(mid_t mod_id, mid_t ue_id)
+long flexran_get_maxHARQ_TX(mid_t mod_id, rnti_t rnti)
 {
   if (!rrc_is_present(mod_id)) return -1;
-
-  rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id);
   struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
-
   if (!ue_context_p) return -1;
   if (!ue_context_p->ue_context.mac_MainConfig) return -1;
   if (!ue_context_p->ue_context.mac_MainConfig->ul_SCH_Config) return -1;
   return *(ue_context_p->ue_context.mac_MainConfig->ul_SCH_Config->maxHARQ_Tx);
 }
 
-long flexran_get_beta_offset_ack_index(mid_t mod_id, mid_t ue_id)
+long flexran_get_beta_offset_ack_index(mid_t mod_id, rnti_t rnti)
 {
   if (!rrc_is_present(mod_id)) return -1;
-
-  rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id);
   struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
-
   if (!ue_context_p) return -1;
   if (!ue_context_p->ue_context.physicalConfigDedicated) return -1;
   if (!ue_context_p->ue_context.physicalConfigDedicated->pusch_ConfigDedicated) return -1;
   return ue_context_p->ue_context.physicalConfigDedicated->pusch_ConfigDedicated->betaOffset_ACK_Index;
 }
 
-long flexran_get_beta_offset_ri_index(mid_t mod_id, mid_t ue_id)
+long flexran_get_beta_offset_ri_index(mid_t mod_id, rnti_t rnti)
 {
   if (!rrc_is_present(mod_id)) return -1;
-
-  rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id);
   struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
-
   if (!ue_context_p) return -1;
   if (!ue_context_p->ue_context.physicalConfigDedicated) return -1;
   if (!ue_context_p->ue_context.physicalConfigDedicated->pusch_ConfigDedicated) return -1;
   return ue_context_p->ue_context.physicalConfigDedicated->pusch_ConfigDedicated->betaOffset_RI_Index;
 }
 
-long flexran_get_beta_offset_cqi_index(mid_t mod_id, mid_t ue_id)
+long flexran_get_beta_offset_cqi_index(mid_t mod_id, rnti_t rnti)
 {
   if (!rrc_is_present(mod_id)) return -1;
-
-  rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id);
   struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
-
   if (!ue_context_p) return -1;
   if (!ue_context_p->ue_context.physicalConfigDedicated) return -1;
   if (!ue_context_p->ue_context.physicalConfigDedicated->pusch_ConfigDedicated) return -1;
   return ue_context_p->ue_context.physicalConfigDedicated->pusch_ConfigDedicated->betaOffset_CQI_Index;
 }
 
-BOOLEAN_t flexran_get_simultaneous_ack_nack_cqi(mid_t mod_id, mid_t ue_id)
+BOOLEAN_t flexran_get_simultaneous_ack_nack_cqi(mid_t mod_id, rnti_t rnti)
 {
   if (!rrc_is_present(mod_id)) return -1;
-
-  rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id);
   struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
-
   if (!ue_context_p) return -1;
   if (!ue_context_p->ue_context.physicalConfigDedicated) return -1;
   if (!ue_context_p->ue_context.physicalConfigDedicated->cqi_ReportConfig) return -1;
@@ -973,33 +1019,46 @@ BOOLEAN_t flexran_get_simultaneous_ack_nack_cqi(mid_t mod_id, mid_t ue_id)
   return ue_context_p->ue_context.physicalConfigDedicated->cqi_ReportConfig->cqi_ReportPeriodic->choice.setup.simultaneousAckNackAndCQI;
 }
 
-BOOLEAN_t flexran_get_ack_nack_simultaneous_trans(mid_t mod_id, mid_t ue_id, uint8_t cc_id)
+BOOLEAN_t flexran_get_ack_nack_simultaneous_trans(mid_t mod_id, uint8_t cc_id)
 {
   if (!rrc_is_present(mod_id)) return -1;
   if (!RC.rrc[mod_id]->carrier[cc_id].sib2) return -1;
   return RC.rrc[mod_id]->carrier[cc_id].sib2->radioResourceConfigCommon.soundingRS_UL_ConfigCommon.choice.setup.ackNackSRS_SimultaneousTransmission;
 }
 
-LTE_CQI_ReportModeAperiodic_t flexran_get_aperiodic_cqi_rep_mode(mid_t mod_id,mid_t ue_id)
+Protocol__FlexAperiodicCqiReportMode flexran_get_aperiodic_cqi_rep_mode(mid_t mod_id, rnti_t rnti)
 {
   if (!rrc_is_present(mod_id)) return -1;
-
-  rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id);
   struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
-
   if (!ue_context_p) return -1;
   if (!ue_context_p->ue_context.physicalConfigDedicated) return -1;
   if (!ue_context_p->ue_context.physicalConfigDedicated->cqi_ReportConfig) return -1;
-  return *ue_context_p->ue_context.physicalConfigDedicated->cqi_ReportConfig->cqi_ReportModeAperiodic;
+  switch (*ue_context_p->ue_context.physicalConfigDedicated->cqi_ReportConfig->cqi_ReportModeAperiodic) {
+  case LTE_CQI_ReportModeAperiodic_rm12:
+    return PROTOCOL__FLEX_APERIODIC_CQI_REPORT_MODE__FLACRM_RM12;
+  case LTE_CQI_ReportModeAperiodic_rm20:
+    return PROTOCOL__FLEX_APERIODIC_CQI_REPORT_MODE__FLACRM_RM20;
+  case LTE_CQI_ReportModeAperiodic_rm22:
+    return PROTOCOL__FLEX_APERIODIC_CQI_REPORT_MODE__FLACRM_RM22;
+  case LTE_CQI_ReportModeAperiodic_rm30:
+    return PROTOCOL__FLEX_APERIODIC_CQI_REPORT_MODE__FLACRM_RM30;
+  case LTE_CQI_ReportModeAperiodic_rm31:
+    return PROTOCOL__FLEX_APERIODIC_CQI_REPORT_MODE__FLACRM_RM31;
+  case LTE_CQI_ReportModeAperiodic_rm32_v1250:
+    return PROTOCOL__FLEX_APERIODIC_CQI_REPORT_MODE__FLACRM_RM32_v1250;
+  case LTE_CQI_ReportModeAperiodic_rm10_v1310:
+    return PROTOCOL__FLEX_APERIODIC_CQI_REPORT_MODE__FLACRM_RM10_v1310;
+  case LTE_CQI_ReportModeAperiodic_rm11_v1310:
+    return PROTOCOL__FLEX_APERIODIC_CQI_REPORT_MODE__FLACRM_RM11_v1310;
+  default:
+    return PROTOCOL__FLEX_APERIODIC_CQI_REPORT_MODE__FLACRM_NONE;
+  }
 }
 
-long flexran_get_tdd_ack_nack_feedback_mode(mid_t mod_id, mid_t ue_id)
+long flexran_get_tdd_ack_nack_feedback_mode(mid_t mod_id, rnti_t rnti)
 {
   if (!rrc_is_present(mod_id)) return -1;
-
-  rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id);
   struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
-
   if (!ue_context_p) return -1;
   if (!ue_context_p->ue_context.physicalConfigDedicated) return -1;
   if (!ue_context_p->ue_context.physicalConfigDedicated->pucch_ConfigDedicated) return -1;
@@ -1007,26 +1066,20 @@ long flexran_get_tdd_ack_nack_feedback_mode(mid_t mod_id, mid_t ue_id)
   return *(ue_context_p->ue_context.physicalConfigDedicated->pucch_ConfigDedicated->tdd_AckNackFeedbackMode);
 }
 
-long flexran_get_ack_nack_repetition_factor(mid_t mod_id, mid_t ue_id)
+long flexran_get_ack_nack_repetition_factor(mid_t mod_id, rnti_t rnti)
 {
   if (!rrc_is_present(mod_id)) return -1;
-
-  rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id);
   struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
-
   if (!ue_context_p) return -1;
   if (!ue_context_p->ue_context.physicalConfigDedicated) return -1;
   if (!ue_context_p->ue_context.physicalConfigDedicated->pucch_ConfigDedicated) return -1;
   return ue_context_p->ue_context.physicalConfigDedicated->pucch_ConfigDedicated->ackNackRepetition.choice.setup.repetitionFactor;
 }
 
-long flexran_get_extended_bsr_size(mid_t mod_id, mid_t ue_id)
+long flexran_get_extended_bsr_size(mid_t mod_id, rnti_t rnti)
 {
   if (!rrc_is_present(mod_id)) return -1;
-
-  rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id);
   struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
-
   if (!ue_context_p) return -1;
   if (!ue_context_p->ue_context.mac_MainConfig) return -1;
   if (!ue_context_p->ue_context.mac_MainConfig->ext2) return -1;
@@ -1034,13 +1087,10 @@ long flexran_get_extended_bsr_size(mid_t mod_id, mid_t ue_id)
   return *(ue_context_p->ue_context.mac_MainConfig->ext2->mac_MainConfig_v1020->extendedBSR_Sizes_r10);
 }
 
-int flexran_get_ue_transmission_antenna(mid_t mod_id, mid_t ue_id)
+int flexran_get_ue_transmission_antenna(mid_t mod_id, rnti_t rnti)
 {
   if (!rrc_is_present(mod_id)) return -1;
-
-  rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id);
   struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
-
   if (!ue_context_p) return -1;
   if (!ue_context_p->ue_context.physicalConfigDedicated) return -1;
   if (!ue_context_p->ue_context.physicalConfigDedicated->antennaInfo) return -1;
@@ -1054,16 +1104,12 @@ int flexran_get_ue_transmission_antenna(mid_t mod_id, mid_t ue_id)
   }
 }
 
-uint64_t flexran_get_ue_imsi(mid_t mod_id, mid_t ue_id)
+uint64_t flexran_get_ue_imsi(mid_t mod_id, rnti_t rnti)
 {
   uint64_t imsi;
   if (!rrc_is_present(mod_id)) return 0;
-
-  rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id);
   struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
-
   if (!ue_context_p) return 0;
-
   imsi  = ue_context_p->ue_context.imsi.digit15;
   imsi += ue_context_p->ue_context.imsi.digit14 * 10;              // pow(10, 1)
   imsi += ue_context_p->ue_context.imsi.digit13 * 100;             // pow(10, 2)
@@ -1212,16 +1258,12 @@ void flexran_agent_set_operating_frame_type(mid_t mod_id, uint8_t cc_id, lte_fra
 }
 
 /*********** PDCP  *************/
-/*PDCP super frame counter flexRAN*/
 
-/* TODO the following is a hack. all the functions below should instead already
- * receive the PDCP's uid and operate on it and the caller has the obligation
- * to get the ID for this layer.
- */
-static inline uint16_t flexran_get_pdcp_uid(mid_t mod_id, mid_t ue_id)
+uint16_t flexran_get_pdcp_uid_from_rnti(mid_t mod_id, rnti_t rnti)
 {
-  rnti_t rnti = flexran_get_ue_crnti(mod_id, ue_id);
   if (rnti == NOT_A_RNTI) return 0;
+  if (mod_id < 0 || mod_id >= RC.nb_inst)
+    return 0;
 
   for (uint16_t pdcp_uid = 0; pdcp_uid < MAX_MOBILES_PER_ENB; ++pdcp_uid) {
     if (pdcp_enb[mod_id].rnti[pdcp_uid] == rnti)
@@ -1230,189 +1272,201 @@ static inline uint16_t flexran_get_pdcp_uid(mid_t mod_id, mid_t ue_id)
   return 0;
 }
 
+/*PDCP super frame counter flexRAN*/
 uint32_t flexran_get_pdcp_sfn(mid_t mod_id)
 {
+  if (mod_id < 0 || mod_id >= RC.nb_inst)
+    return 0;
   return pdcp_enb[mod_id].sfn;
 }
 
 /*PDCP super frame counter flexRAN*/
-void flexran_set_pdcp_tx_stat_window(mid_t mod_id, mid_t ue_id, uint16_t obs_window)
+void flexran_set_pdcp_tx_stat_window(mid_t mod_id, uint16_t uid, uint16_t obs_window)
 {
-  uint16_t uid = flexran_get_pdcp_uid(mod_id, ue_id);
-  if (obs_window > 0 ){
-    Pdcp_stats_tx_window_ms[mod_id][uid]=obs_window;
-  }
-  else{
-    Pdcp_stats_tx_window_ms[mod_id][uid]=1000;
-  }
+  if (mod_id < 0 || mod_id >= RC.nb_inst || uid < 0
+      || uid >= MAX_MOBILES_PER_ENB)
+    return;
+  Pdcp_stats_tx_window_ms[mod_id][uid] = obs_window > 0 ? obs_window : 1000;
 }
 
 /*PDCP super frame counter flexRAN*/
-void flexran_set_pdcp_rx_stat_window(mid_t mod_id, mid_t ue_id, uint16_t obs_window)
+void flexran_set_pdcp_rx_stat_window(mid_t mod_id, uint16_t uid, uint16_t obs_window)
 {
-  uint16_t uid = flexran_get_pdcp_uid(mod_id, ue_id);
-  if (obs_window > 0 ){
-    Pdcp_stats_rx_window_ms[mod_id][uid]=obs_window;
-  }
-  else{
-    Pdcp_stats_rx_window_ms[mod_id][uid]=1000;
-  }
+  if (mod_id < 0 || mod_id >= RC.nb_inst || uid < 0
+      || uid >= MAX_MOBILES_PER_ENB)
+    return;
+  Pdcp_stats_rx_window_ms[mod_id][uid] = obs_window > 0 ? obs_window : 1000;
 }
 
 /*PDCP num tx pdu status flexRAN*/
-uint32_t flexran_get_pdcp_tx(mid_t mod_id, mid_t ue_id, lcid_t lcid)
+uint32_t flexran_get_pdcp_tx(mid_t mod_id, uint16_t uid, lcid_t lcid)
 {
-  if (mod_id < 0 || mod_id > MAX_NUM_CCs || ue_id < 0 || ue_id > MAX_MOBILES_PER_ENB
-      || lcid < 0 || lcid > NB_RB_MAX)
-    return -1;
-  uint16_t uid = flexran_get_pdcp_uid(mod_id, ue_id);
+  if (mod_id < 0 || mod_id >= RC.nb_inst || uid < 0
+      || uid >= MAX_MOBILES_PER_ENB || lcid < 0 || lcid >= NB_RB_MAX)
+    return 0;
   return Pdcp_stats_tx[mod_id][uid][lcid];
 }
 
 /*PDCP num tx bytes status flexRAN*/
-uint32_t flexran_get_pdcp_tx_bytes(mid_t mod_id, mid_t ue_id, lcid_t lcid)
+uint32_t flexran_get_pdcp_tx_bytes(mid_t mod_id, uint16_t uid, lcid_t lcid)
 {
-  uint16_t uid = flexran_get_pdcp_uid(mod_id, ue_id);
+  if (mod_id < 0 || mod_id >= RC.nb_inst || uid < 0
+      || uid >= MAX_MOBILES_PER_ENB || lcid < 0 || lcid >= NB_RB_MAX)
+    return 0;
   return Pdcp_stats_tx_bytes[mod_id][uid][lcid];
 }
 
 /*PDCP number of transmit packet / second status flexRAN*/
-uint32_t flexran_get_pdcp_tx_w(mid_t mod_id, mid_t ue_id, lcid_t lcid)
+uint32_t flexran_get_pdcp_tx_w(mid_t mod_id, uint16_t uid, lcid_t lcid)
 {
-  uint16_t uid = flexran_get_pdcp_uid(mod_id, ue_id);
+  if (mod_id < 0 || mod_id >= RC.nb_inst || uid < 0
+      || uid >= MAX_MOBILES_PER_ENB || lcid < 0 || lcid >= NB_RB_MAX)
+    return 0;
   return Pdcp_stats_tx_w[mod_id][uid][lcid];
 }
 
 /*PDCP throughput (bit/s) status flexRAN*/
-uint32_t flexran_get_pdcp_tx_bytes_w(mid_t mod_id, mid_t ue_id, lcid_t lcid)
+uint32_t flexran_get_pdcp_tx_bytes_w(mid_t mod_id, uint16_t uid, lcid_t lcid)
 {
-  uint16_t uid = flexran_get_pdcp_uid(mod_id, ue_id);
+  if (mod_id < 0 || mod_id >= RC.nb_inst || uid < 0
+      || uid >= MAX_MOBILES_PER_ENB || lcid < 0 || lcid >= NB_RB_MAX)
+    return 0;
   return Pdcp_stats_tx_bytes_w[mod_id][uid][lcid];
 }
 
 /*PDCP tx sequence number flexRAN*/
-uint32_t flexran_get_pdcp_tx_sn(mid_t mod_id, mid_t ue_id, lcid_t lcid)
+uint32_t flexran_get_pdcp_tx_sn(mid_t mod_id, uint16_t uid, lcid_t lcid)
 {
-  uint16_t uid = flexran_get_pdcp_uid(mod_id, ue_id);
+  if (mod_id < 0 || mod_id >= RC.nb_inst || uid < 0
+      || uid >= MAX_MOBILES_PER_ENB || lcid < 0 || lcid >= NB_RB_MAX)
+    return 0;
   return Pdcp_stats_tx_sn[mod_id][uid][lcid];
 }
 
 /*PDCP tx aggregated packet arrival  flexRAN*/
-uint32_t flexran_get_pdcp_tx_aiat(mid_t mod_id, mid_t ue_id, lcid_t lcid)
+uint32_t flexran_get_pdcp_tx_aiat(mid_t mod_id, uint16_t uid, lcid_t lcid)
 {
-  uint16_t uid = flexran_get_pdcp_uid(mod_id, ue_id);
+  if (mod_id < 0 || mod_id >= RC.nb_inst || uid < 0
+      || uid >= MAX_MOBILES_PER_ENB || lcid < 0 || lcid >= NB_RB_MAX)
+    return 0;
   return Pdcp_stats_tx_aiat[mod_id][uid][lcid];
 }
 
 /*PDCP tx aggregated packet arrival  flexRAN*/
-uint32_t flexran_get_pdcp_tx_aiat_w(mid_t mod_id, mid_t ue_id, lcid_t lcid)
+uint32_t flexran_get_pdcp_tx_aiat_w(mid_t mod_id, uint16_t uid, lcid_t lcid)
 {
-  uint16_t uid = flexran_get_pdcp_uid(mod_id, ue_id);
+  if (mod_id < 0 || mod_id >= RC.nb_inst || uid < 0
+      || uid >= MAX_MOBILES_PER_ENB || lcid < 0 || lcid >= NB_RB_MAX)
+    return 0;
   return Pdcp_stats_tx_aiat_w[mod_id][uid][lcid];
 }
 
 /*PDCP num rx pdu status flexRAN*/
-uint32_t flexran_get_pdcp_rx(mid_t mod_id, mid_t ue_id, lcid_t lcid)
+uint32_t flexran_get_pdcp_rx(mid_t mod_id, uint16_t uid, lcid_t lcid)
 {
-  uint16_t uid = flexran_get_pdcp_uid(mod_id, ue_id);
+  if (mod_id < 0 || mod_id >= RC.nb_inst || uid < 0
+      || uid >= MAX_MOBILES_PER_ENB || lcid < 0 || lcid >= NB_RB_MAX)
+    return 0;
   return Pdcp_stats_rx[mod_id][uid][lcid];
 }
 
 /*PDCP num rx bytes status flexRAN*/
-uint32_t flexran_get_pdcp_rx_bytes(mid_t mod_id, mid_t ue_id, lcid_t lcid)
+uint32_t flexran_get_pdcp_rx_bytes(mid_t mod_id, uint16_t uid, lcid_t lcid)
 {
-  uint16_t uid = flexran_get_pdcp_uid(mod_id, ue_id);
+  if (mod_id < 0 || mod_id >= RC.nb_inst || uid < 0
+      || uid >= MAX_MOBILES_PER_ENB || lcid < 0 || lcid >= NB_RB_MAX)
+    return 0;
   return Pdcp_stats_rx_bytes[mod_id][uid][lcid];
 }
 
 /*PDCP number of received packet / second  flexRAN*/
-uint32_t flexran_get_pdcp_rx_w(mid_t mod_id, mid_t ue_id, lcid_t lcid)
+uint32_t flexran_get_pdcp_rx_w(mid_t mod_id, uint16_t uid, lcid_t lcid)
 {
-  uint16_t uid = flexran_get_pdcp_uid(mod_id, ue_id);
+  if (mod_id < 0 || mod_id >= RC.nb_inst || uid < 0
+      || uid >= MAX_MOBILES_PER_ENB || lcid < 0 || lcid >= NB_RB_MAX)
+    return 0;
   return Pdcp_stats_rx_w[mod_id][uid][lcid];
 }
 
 /*PDCP gootput (bit/s) status flexRAN*/
-uint32_t flexran_get_pdcp_rx_bytes_w(mid_t mod_id, mid_t ue_id, lcid_t lcid)
+uint32_t flexran_get_pdcp_rx_bytes_w(mid_t mod_id, uint16_t uid, lcid_t lcid)
 {
-  uint16_t uid = flexran_get_pdcp_uid(mod_id, ue_id);
+  if (mod_id < 0 || mod_id >= RC.nb_inst || uid < 0
+      || uid >= MAX_MOBILES_PER_ENB || lcid < 0 || lcid >= NB_RB_MAX)
+    return 0;
   return Pdcp_stats_rx_bytes_w[mod_id][uid][lcid];
 }
 
 /*PDCP rx sequence number flexRAN*/
-uint32_t flexran_get_pdcp_rx_sn(mid_t mod_id, mid_t ue_id, lcid_t lcid)
+uint32_t flexran_get_pdcp_rx_sn(mid_t mod_id, uint16_t uid, lcid_t lcid)
 {
-  uint16_t uid = flexran_get_pdcp_uid(mod_id, ue_id);
+  if (mod_id < 0 || mod_id >= RC.nb_inst || uid < 0
+      || uid >= MAX_MOBILES_PER_ENB || lcid < 0 || lcid >= NB_RB_MAX)
+    return 0;
   return Pdcp_stats_rx_sn[mod_id][uid][lcid];
 }
 
 /*PDCP rx aggregated packet arrival  flexRAN*/
-uint32_t flexran_get_pdcp_rx_aiat(mid_t mod_id, mid_t ue_id, lcid_t lcid)
+uint32_t flexran_get_pdcp_rx_aiat(mid_t mod_id, uint16_t uid, lcid_t lcid)
 {
-  uint16_t uid = flexran_get_pdcp_uid(mod_id, ue_id);
+  if (mod_id < 0 || mod_id >= RC.nb_inst || uid < 0
+      || uid >= MAX_MOBILES_PER_ENB || lcid < 0 || lcid >= NB_RB_MAX)
+    return 0;
   return Pdcp_stats_rx_aiat[mod_id][uid][lcid];
 }
 
 /*PDCP rx aggregated packet arrival  flexRAN*/
-uint32_t flexran_get_pdcp_rx_aiat_w(mid_t mod_id, mid_t ue_id, lcid_t lcid)
+uint32_t flexran_get_pdcp_rx_aiat_w(mid_t mod_id, uint16_t uid, lcid_t lcid)
 {
-  uint16_t uid = flexran_get_pdcp_uid(mod_id, ue_id);
+  if (mod_id < 0 || mod_id >= RC.nb_inst || uid < 0
+      || uid >= MAX_MOBILES_PER_ENB || lcid < 0 || lcid >= NB_RB_MAX)
+    return 0;
   return Pdcp_stats_rx_aiat_w[mod_id][uid][lcid];
 }
 
 /*PDCP num of received outoforder pdu status flexRAN*/
-uint32_t flexran_get_pdcp_rx_oo(mid_t mod_id, mid_t ue_id, lcid_t lcid)
+uint32_t flexran_get_pdcp_rx_oo(mid_t mod_id, uint16_t uid, lcid_t lcid)
 {
-  uint16_t uid = flexran_get_pdcp_uid(mod_id, ue_id);
+  if (mod_id < 0 || mod_id >= RC.nb_inst || uid < 0
+      || uid >= MAX_MOBILES_PER_ENB || lcid < 0 || lcid >= NB_RB_MAX)
+    return 0;
   return Pdcp_stats_rx_outoforder[mod_id][uid][lcid];
 }
 
 /******************** RRC *****************************/
 
-LTE_MeasId_t flexran_get_rrc_pcell_measid(mid_t mod_id, mid_t ue_id)
+LTE_MeasId_t  flexran_get_rrc_pcell_measid(mid_t mod_id, rnti_t rnti)
 {
   if (!rrc_is_present(mod_id)) return -1;
-
-  rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id);
   struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
-
   if (!ue_context_p) return -1;
   if (!ue_context_p->ue_context.measResults) return -1;
   return ue_context_p->ue_context.measResults->measId;
 }
 
-float flexran_get_rrc_pcell_rsrp(mid_t mod_id, mid_t ue_id)
+float flexran_get_rrc_pcell_rsrp(mid_t mod_id, rnti_t rnti)
 {
   if (!rrc_is_present(mod_id)) return -1;
-
-  rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id);
   struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
-
   if (!ue_context_p) return -1;
   if (!ue_context_p->ue_context.measResults) return -1;
   return RSRP_meas_mapping[ue_context_p->ue_context.measResults->measResultPCell.rsrpResult];
 }
 
-float flexran_get_rrc_pcell_rsrq(mid_t mod_id, mid_t ue_id)
+float flexran_get_rrc_pcell_rsrq(mid_t mod_id, rnti_t rnti)
 {
   if (!rrc_is_present(mod_id)) return -1;
-
-  rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id);
   struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
-
   if (!ue_context_p) return -1;
   if (!ue_context_p->ue_context.measResults) return -1;
   return RSRQ_meas_mapping[ue_context_p->ue_context.measResults->measResultPCell.rsrqResult];
 }
 
 /*Number of neighbouring cells for specific UE*/
-int flexran_get_rrc_num_ncell(mid_t mod_id, mid_t ue_id)
+int flexran_get_rrc_num_ncell(mid_t mod_id, rnti_t rnti)
 {
   if (!rrc_is_present(mod_id)) return 0;
-
-  rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id);
   struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
-
   if (!ue_context_p) return 0;
   if (!ue_context_p->ue_context.measResults) return 0;
   if (!ue_context_p->ue_context.measResults->measResultNeighCells) return 0;
@@ -1420,13 +1474,10 @@ int flexran_get_rrc_num_ncell(mid_t mod_id, mid_t ue_id)
   return ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.count;
 }
 
-LTE_PhysCellId_t flexran_get_rrc_neigh_phy_cell_id(mid_t mod_id, mid_t ue_id, int cell_id)
+long flexran_get_rrc_neigh_phy_cell_id(mid_t mod_id, rnti_t rnti, long cell_id)
 {
   if (!rrc_is_present(mod_id)) return -1;
-
-  rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id);
   struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
-
   if (!ue_context_p) return -1;
   if (!ue_context_p->ue_context.measResults) return -1;
   if (!ue_context_p->ue_context.measResults->measResultNeighCells) return -1;
@@ -1435,13 +1486,10 @@ LTE_PhysCellId_t flexran_get_rrc_neigh_phy_cell_id(mid_t mod_id, mid_t ue_id, in
   return ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[cell_id]->physCellId;
 }
 
-float flexran_get_rrc_neigh_rsrp(mid_t mod_id, mid_t ue_id, int cell_id)
+float flexran_get_rrc_neigh_rsrp(mid_t mod_id, rnti_t rnti, long cell_id)
 {
   if (!rrc_is_present(mod_id)) return -1;
-
-  rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id);
   struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
-
   if (!ue_context_p) return -1;
   if (!ue_context_p->ue_context.measResults) return -1;
   if (!ue_context_p->ue_context.measResults->measResultNeighCells) return -1;
@@ -1451,13 +1499,10 @@ float flexran_get_rrc_neigh_rsrp(mid_t mod_id, mid_t ue_id, int cell_id)
   return RSRP_meas_mapping[*(ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[cell_id]->measResult.rsrpResult)];
 }
 
-float flexran_get_rrc_neigh_rsrq(mid_t mod_id, mid_t ue_id, int cell_id)
+float flexran_get_rrc_neigh_rsrq(mid_t mod_id, rnti_t rnti, long cell_id)
 {
   if (!rrc_is_present(mod_id)) return -1;
-
-  rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id);
   struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
-
   if (!ue_context_p) return -1;
   if (!ue_context_p->ue_context.measResults) return -1;
   if (!ue_context_p->ue_context.measResults->measResultNeighCells) return -1;
@@ -1466,6 +1511,31 @@ float flexran_get_rrc_neigh_rsrq(mid_t mod_id, mid_t ue_id, int cell_id)
   return RSRQ_meas_mapping[*(ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[cell_id]->measResult.rsrqResult)];
 }
 
+uint8_t flexran_get_rrc_num_plmn_ids(mid_t mod_id)
+{
+  if (!rrc_is_present(mod_id)) return 0;
+  return RC.rrc[mod_id]->configuration.num_plmn;
+}
+
+uint16_t flexran_get_rrc_mcc(mid_t mod_id, uint8_t index)
+{
+  if (!rrc_is_present(mod_id)) return 0;
+  return RC.rrc[mod_id]->configuration.mcc[index];
+}
+
+uint16_t flexran_get_rrc_mnc(mid_t mod_id, uint8_t index)
+{
+  if (!rrc_is_present(mod_id)) return 0;
+  return RC.rrc[mod_id]->configuration.mnc[index];
+}
+
+uint8_t flexran_get_rrc_mnc_digit_length(mid_t mod_id, uint8_t index)
+{
+  if (!rrc_is_present(mod_id)) return 0;
+  return RC.rrc[mod_id]->configuration.mnc_digit_length[index];
+}
+
+/**************************** SLICING ****************************/
 int flexran_get_ue_dl_slice_id(mid_t mod_id, mid_t ue_id)
 {
   if (!mac_is_present(mod_id)) return -1;
@@ -1478,7 +1548,7 @@ int flexran_get_ue_dl_slice_id(mid_t mod_id, mid_t ue_id)
 void flexran_set_ue_dl_slice_idx(mid_t mod_id, mid_t ue_id, int slice_idx)
 {
   if (!mac_is_present(mod_id)) return;
-  if (flexran_get_ue_crnti(mod_id, ue_id) == NOT_A_RNTI) return;
+  if (flexran_get_mac_ue_crnti(mod_id, ue_id) == NOT_A_RNTI) return;
   if (!flexran_dl_slice_exists(mod_id, slice_idx)) return;
   RC.mac[mod_id]->UE_list.assoc_dl_slice_idx[ue_id] = slice_idx;
 }
@@ -1495,7 +1565,7 @@ int flexran_get_ue_ul_slice_id(mid_t mod_id, mid_t ue_id)
 void flexran_set_ue_ul_slice_idx(mid_t mod_id, mid_t ue_id, int slice_idx)
 {
   if (!mac_is_present(mod_id)) return;
-  if (flexran_get_ue_crnti(mod_id, ue_id) == NOT_A_RNTI) return;
+  if (flexran_get_mac_ue_crnti(mod_id, ue_id) == NOT_A_RNTI) return;
   if (!flexran_ul_slice_exists(mod_id, slice_idx)) return;
   RC.mac[mod_id]->UE_list.assoc_ul_slice_idx[ue_id] = slice_idx;
 }
@@ -1881,3 +1951,95 @@ int flexran_set_ul_slice_scheduler(mid_t mod_id, int slice_idx, char *name)
   RC.mac[mod_id]->slice_info.ul[slice_idx].sched_cb = dlsym(NULL, name);
   return RC.mac[mod_id]->slice_info.ul[slice_idx].sched_cb != NULL;
 }
+
+/**************************** General BS info  ****************************/
+uint64_t flexran_get_bs_id(mid_t mod_id)
+{
+  if (!rrc_is_present(mod_id)) return 0;
+  return RC.rrc[mod_id]->nr_cellid;
+}
+
+size_t flexran_get_capabilities(mid_t mod_id, Protocol__FlexBsCapability **caps)
+{
+  if (!caps) return 0;
+  if (!rrc_is_present(mod_id)) return 0;
+  size_t n_caps = 0;
+  switch (RC.rrc[mod_id]->node_type) {
+  case ngran_eNB_CU:
+  case ngran_ng_eNB_CU:
+  case ngran_gNB_CU:
+    n_caps = 3;
+    *caps = calloc(n_caps, sizeof(Protocol__FlexBsCapability));
+    AssertFatal(*caps, "could not allocate %zu bytes for Protocol__FlexBsCapability array\n",
+                n_caps * sizeof(Protocol__FlexBsCapability));
+    (*caps)[0] = PROTOCOL__FLEX_BS_CAPABILITY__PDCP;
+    (*caps)[1] = PROTOCOL__FLEX_BS_CAPABILITY__SDAP;
+    (*caps)[2] = PROTOCOL__FLEX_BS_CAPABILITY__RRC;
+    break;
+  case ngran_eNB_DU:
+  case ngran_gNB_DU:
+    n_caps = 5;
+    *caps = calloc(n_caps, sizeof(Protocol__FlexBsCapability));
+    AssertFatal(*caps, "could not allocate %zu bytes for Protocol__FlexBsCapability array\n",
+                n_caps * sizeof(Protocol__FlexBsCapability));
+    (*caps)[0] = PROTOCOL__FLEX_BS_CAPABILITY__LOPHY;
+    (*caps)[1] = PROTOCOL__FLEX_BS_CAPABILITY__HIPHY;
+    (*caps)[2] = PROTOCOL__FLEX_BS_CAPABILITY__LOMAC;
+    (*caps)[3] = PROTOCOL__FLEX_BS_CAPABILITY__HIMAC;
+    (*caps)[4] = PROTOCOL__FLEX_BS_CAPABILITY__RLC;
+    break;
+  case ngran_eNB:
+  case ngran_ng_eNB:
+  case ngran_gNB:
+    n_caps = 8;
+    *caps = calloc(n_caps, sizeof(Protocol__FlexBsCapability));
+    AssertFatal(*caps, "could not allocate %zu bytes for Protocol__FlexBsCapability array\n",
+                n_caps * sizeof(Protocol__FlexBsCapability));
+    (*caps)[0] = PROTOCOL__FLEX_BS_CAPABILITY__LOPHY;
+    (*caps)[1] = PROTOCOL__FLEX_BS_CAPABILITY__HIPHY;
+    (*caps)[2] = PROTOCOL__FLEX_BS_CAPABILITY__LOMAC;
+    (*caps)[3] = PROTOCOL__FLEX_BS_CAPABILITY__HIMAC;
+    (*caps)[4] = PROTOCOL__FLEX_BS_CAPABILITY__RLC;
+    (*caps)[5] = PROTOCOL__FLEX_BS_CAPABILITY__PDCP;
+    (*caps)[6] = PROTOCOL__FLEX_BS_CAPABILITY__SDAP;
+    (*caps)[7] = PROTOCOL__FLEX_BS_CAPABILITY__RRC;
+    break;
+  }
+  return n_caps;
+}
+
+uint16_t flexran_get_capabilities_mask(mid_t mod_id)
+{
+  if (!rrc_is_present(mod_id)) return 0;
+  uint16_t mask = 0;
+  switch (RC.rrc[mod_id]->node_type) {
+  case ngran_eNB_CU:
+  case ngran_ng_eNB_CU:
+  case ngran_gNB_CU:
+    mask = (1 << PROTOCOL__FLEX_BS_CAPABILITY__PDCP)
+         | (1 << PROTOCOL__FLEX_BS_CAPABILITY__SDAP)
+         | (1 << PROTOCOL__FLEX_BS_CAPABILITY__RRC);
+    break;
+  case ngran_eNB_DU:
+  case ngran_gNB_DU:
+    mask = (1 << PROTOCOL__FLEX_BS_CAPABILITY__LOPHY)
+         | (1 << PROTOCOL__FLEX_BS_CAPABILITY__HIPHY)
+         | (1 << PROTOCOL__FLEX_BS_CAPABILITY__LOMAC)
+         | (1 << PROTOCOL__FLEX_BS_CAPABILITY__HIMAC)
+         | (1 << PROTOCOL__FLEX_BS_CAPABILITY__RLC);
+    break;
+  case ngran_eNB:
+  case ngran_ng_eNB:
+  case ngran_gNB:
+    mask = (1 << PROTOCOL__FLEX_BS_CAPABILITY__LOPHY)
+         | (1 << PROTOCOL__FLEX_BS_CAPABILITY__HIPHY)
+         | (1 << PROTOCOL__FLEX_BS_CAPABILITY__LOMAC)
+         | (1 << PROTOCOL__FLEX_BS_CAPABILITY__HIMAC)
+         | (1 << PROTOCOL__FLEX_BS_CAPABILITY__RLC)
+         | (1 << PROTOCOL__FLEX_BS_CAPABILITY__PDCP)
+         | (1 << PROTOCOL__FLEX_BS_CAPABILITY__SDAP)
+         | (1 << PROTOCOL__FLEX_BS_CAPABILITY__RRC);
+    break;
+  }
+  return mask;
+}
diff --git a/openair2/ENB_APP/flexran_agent_ran_api.h b/openair2/ENB_APP/flexran_agent_ran_api.h
index 4fa05fd2f6858e0758662d46f2edc6bb252bf3f9..a60cdeb994cb0f7c0f25af76b01d8b5d8a30178e 100644
--- a/openair2/ENB_APP/flexran_agent_ran_api.h
+++ b/openair2/ENB_APP/flexran_agent_ran_api.h
@@ -70,15 +70,21 @@ uint16_t flexran_get_sfn_sf(mid_t mod_id);
    rest for frame */
 uint16_t flexran_get_future_sfn_sf(mid_t mod_id, int ahead_of_time);
 
-/* Return the number of attached UEs */
-int flexran_get_num_ues(mid_t mod_id);
+/* Return the number of attached UEs for the MAC */
+int flexran_get_mac_num_ues(mid_t mod_id);
+
+/* Get the number of logical channels per UE. This function does not consider
+ * dedicated bearers yet */
+int flexran_get_num_ue_lcs(mid_t mod_id, mid_t ue_id);
+
+/* Get the rnti of a UE with id ue_id from MAC */
+rnti_t flexran_get_mac_ue_crnti(mid_t mod_id, mid_t ue_id);
+
+int flexran_get_mac_ue_id_rnti(mid_t mod_id, rnti_t rnti);
 
 /* Return the UE id of attached UE as opposed to the index [0,NUM UEs] (i.e.,
  * the i'th active UE). Returns 0 if the i'th active UE could not be found. */
-int flexran_get_ue_id(mid_t mod_id, int i);
-
-/* Get the rnti of a UE with id ue_id */
-rnti_t flexran_get_ue_crnti(mid_t mod_id, mid_t ue_id);
+int flexran_get_mac_ue_id(mid_t mod_id, int i);
 
 /* Get the RLC buffer status report in bytes of a ue for a designated
  * logical channel id */
@@ -210,10 +216,10 @@ uint8_t flexran_get_prach_FreqOffset(mid_t mod_id, uint8_t cc_id);
 uint8_t flexran_get_maxHARQ_Msg3Tx(mid_t mod_id, uint8_t cc_id);
 
 /* Get the length of the UL cyclic prefix */
-lte_prefix_type_t flexran_get_ul_cyclic_prefix_length(mid_t mod_id, uint8_t cc_id);
+Protocol__FlexUlCyclicPrefixLength flexran_get_ul_cyclic_prefix_length(mid_t mod_id, uint8_t cc_id);
 
 /* Get the length of the DL cyclic prefix */
-lte_prefix_type_t flexran_get_dl_cyclic_prefix_length(mid_t mod_id, uint8_t cc_id);
+Protocol__FlexDlCyclicPrefixLength flexran_get_dl_cyclic_prefix_length(mid_t mod_id, uint8_t cc_id);
 
 /* Get the physical cell id of a cell */
 uint16_t flexran_get_cell_id(mid_t mod_id, uint8_t cc_id);
@@ -287,34 +293,44 @@ int flexran_update_p0_pucch(mid_t mod_id, mid_t ue_id, uint8_t cc_id);
 
 uint8_t flexran_get_threequarter_fs(mid_t mod_id, uint8_t cc_id);
 
-PUSCH_HOPPING_t flexran_get_hopping_mode(mid_t mod_id, uint8_t cc_id);
+Protocol__FlexHoppingMode flexran_get_hopping_mode(mid_t mod_id, uint8_t cc_id);
 
 uint8_t flexran_get_hopping_offset(mid_t mod_id, uint8_t cc_id);
 
 uint8_t flexran_get_n_SB(mid_t mod_id, uint8_t cc_id);
 
-int flexran_get_phich_resource(mid_t mod_id, uint8_t cc_id);
+Protocol__FlexPhichResource flexran_get_phich_resource(mid_t mod_id, uint8_t cc_id);
 
-uint8_t flexran_get_enable64QAM(mid_t mod_id, uint8_t cc_id);
+Protocol__FlexQam flexran_get_enable64QAM(mid_t mod_id, uint8_t cc_id);
 
-PHICH_DURATION_t flexran_get_phich_duration(mid_t mod_id, uint8_t cc_id);
+Protocol__FlexPhichDuration flexran_get_phich_duration(mid_t mod_id, uint8_t cc_id);
 
 /*
  * ************************************
  * Get Messages for UE Configuration Reply
  * ************************************
  */
+/* Get the number of attached UEs for the RRC */
+int flexran_get_rrc_num_ues(mid_t mod_id);
+
+/* Get the RNTI of UE at index 'index' in RRC list */
+rnti_t flexran_get_rrc_rnti_nth_ue(mid_t mod_id, int index);
+
+/* Get the list of RNTIs of up to max_list entries.  When max_list >=
+ * flexran_get_rrc_num_ues(), gets a list of all UEs registered in the RRC. UE
+ * RNTIs are saved in list, returns number of saved RNTIs */
+int flexran_get_rrc_rnti_list(mid_t mod_id, rnti_t *list, int max_list);
 
 /* Get timer in subframes. Controls the synchronization
    status of the UE, not the actual timing 
    advance procedure. See TS 36.321 */
-LTE_TimeAlignmentTimer_t flexran_get_time_alignment_timer(mid_t mod_id, mid_t ue_id);
+LTE_TimeAlignmentTimer_t flexran_get_time_alignment_timer(mid_t mod_id, rnti_t rnti);
 
 /* Get measurement gap configuration. See TS 36.133 */
-Protocol__FlexMeasGapConfigPattern flexran_get_meas_gap_config(mid_t mod_id, mid_t ue_id);
+Protocol__FlexMeasGapConfigPattern flexran_get_meas_gap_config(mid_t mod_id, rnti_t rnti);
 
 /* Get measurement gap configuration offset if applicable */
-long flexran_get_meas_gap_config_offset(mid_t mod_id, mid_t ue_id);
+long flexran_get_meas_gap_config_offset(mid_t mod_id, rnti_t rnti);
 
 /* DL aggregated bit-rate of non-gbr bearer
    per UE. See TS 36.413 */
@@ -325,62 +341,62 @@ uint64_t flexran_get_ue_aggregated_max_bitrate_dl(mid_t mod_id, mid_t ue_id);
 uint64_t flexran_get_ue_aggregated_max_bitrate_ul(mid_t mod_id, mid_t ue_id);
 
 /* Only half-duplex support. FDD operation. Boolean value */
-int flexran_get_half_duplex(mid_t mod_id, mid_t ue_id);
+int flexran_get_half_duplex(mid_t mod_id, rnti_t rnti);
 
 /* Support of intra-subframe hopping.  Boolean value */
-int flexran_get_intra_sf_hopping(mid_t mod_id, mid_t ue_id);
+int flexran_get_intra_sf_hopping(mid_t mod_id, rnti_t rnti);
 
 /* UE support for type 2 hopping with n_sb>1 */
-int flexran_get_type2_sb_1(mid_t mod_id, mid_t ue_id);
+int flexran_get_type2_sb_1(mid_t mod_id, rnti_t rnti);
 
 /* Get the UE category */
-long flexran_get_ue_category(mid_t mod_id, mid_t ue_id);
+long flexran_get_ue_category(mid_t mod_id, rnti_t rnti);
 
 /* UE support for resource allocation type 1 */
-int flexran_get_res_alloc_type1(mid_t mod_id, mid_t ue_id);
+int flexran_get_res_alloc_type1(mid_t mod_id, rnti_t rnti);
 
 /* Get UE transmission mode */
-long flexran_get_ue_transmission_mode(mid_t mod_id, mid_t ue_id);
+long flexran_get_ue_transmission_mode(mid_t mod_id, rnti_t rnti);
 
 /* Boolean value. See TS 36.321 */
-BOOLEAN_t flexran_get_tti_bundling(mid_t mod_id, mid_t ue_id);
+BOOLEAN_t flexran_get_tti_bundling(mid_t mod_id, rnti_t rnti);
 
 /* The max HARQ retransmission for UL.
    See TS 36.321 */
-long flexran_get_maxHARQ_TX(mid_t mod_id, mid_t ue_id);
+long flexran_get_maxHARQ_TX(mid_t mod_id, rnti_t rnti);
 
 /* See TS 36.213 */
-long flexran_get_beta_offset_ack_index(mid_t mod_id, mid_t ue_id);
+long flexran_get_beta_offset_ack_index(mid_t mod_id, rnti_t rnti);
 
 /* See TS 36.213 */
-long flexran_get_beta_offset_ri_index(mid_t mod_id, mid_t ue_id);
+long flexran_get_beta_offset_ri_index(mid_t mod_id, rnti_t rnti);
 
 /* See TS 36.213 */
-long flexran_get_beta_offset_cqi_index(mid_t mod_id, mid_t ue_id);
+long flexran_get_beta_offset_cqi_index(mid_t mod_id, rnti_t rnti);
 
 /* Boolean. See TS36.213, Section 10.1 */
-BOOLEAN_t flexran_get_simultaneous_ack_nack_cqi(mid_t mod_id, mid_t ue_id);
+BOOLEAN_t flexran_get_simultaneous_ack_nack_cqi(mid_t mod_id, rnti_t rnti);
 
 /* Boolean. See TS 36.213, Section 8.2 */
-BOOLEAN_t flexran_get_ack_nack_simultaneous_trans(mid_t mod_id, mid_t ue_id, uint8_t cc_id);
+BOOLEAN_t flexran_get_ack_nack_simultaneous_trans(mid_t mod_id, uint8_t cc_id);
 
 /* Get aperiodic CQI report mode */
-LTE_CQI_ReportModeAperiodic_t flexran_get_aperiodic_cqi_rep_mode(mid_t mod_id,mid_t ue_id);
+Protocol__FlexAperiodicCqiReportMode flexran_get_aperiodic_cqi_rep_mode(mid_t mod_id, rnti_t rnti);
 
 /* Get ACK/NACK feedback mode. TDD only */
-long flexran_get_tdd_ack_nack_feedback_mode(mid_t mod_id, mid_t ue_id);
+long flexran_get_tdd_ack_nack_feedback_mode(mid_t mod_id, rnti_t rnti);
 
 /* See TS36.213, section 10.1 */
-long flexran_get_ack_nack_repetition_factor(mid_t mod_id, mid_t ue_id);
+long flexran_get_ack_nack_repetition_factor(mid_t mod_id, rnti_t rnti);
 
 /* Boolean. Extended buffer status report size */
-long flexran_get_extended_bsr_size(mid_t mod_id, mid_t ue_id);
+long flexran_get_extended_bsr_size(mid_t mod_id, rnti_t rnti);
 
 /* Get number of UE transmission antennas */
-int flexran_get_ue_transmission_antenna(mid_t mod_id, mid_t ue_id);
+int flexran_get_ue_transmission_antenna(mid_t mod_id, rnti_t rnti);
 
 /* Get the IMSI of UE */
-uint64_t flexran_get_ue_imsi(mid_t mod_id, mid_t ue_id);
+uint64_t flexran_get_ue_imsi(mid_t mod_id, rnti_t rnti);
 
 /* Get logical channel group of a channel with id lc_id */
 long flexran_get_lcg(mid_t mod_id, mid_t ue_id, mid_t lc_id);
@@ -419,96 +435,110 @@ void flexran_agent_set_operating_bandwidth(mid_t mod_id, uint8_t cc_id, uint8_t
 void flexran_agent_set_operating_frame_type(mid_t mod_id, uint8_t cc_id, lte_frame_type_t frame_type);
 
 /*RRC status flexRAN*/
-uint8_t flexran_get_rrc_status(mid_t mod_id, mid_t ue_id);
+uint8_t flexran_get_rrc_status(mid_t mod_id, rnti_t rnti);
 
 
 /***************************** PDCP ***********************/
+/* PDCP uid obtained through the RNTI */
+uint16_t flexran_get_pdcp_uid_from_rnti(mid_t mod_id, rnti_t rnti);
 
 /*PDCP superframe numberflexRAN*/
 uint32_t flexran_get_pdcp_sfn(mid_t mod_id);
 
 /*PDCP pdcp tx stats window*/
-void flexran_set_pdcp_tx_stat_window(mid_t mod_id, mid_t ue_id, uint16_t obs_window);
+void flexran_set_pdcp_tx_stat_window(mid_t mod_id, uint16_t uid, uint16_t obs_window);
 
 /*PDCP pdcp rx stats window*/
-void flexran_set_pdcp_rx_stat_window(mid_t mod_id, mid_t ue_id, uint16_t obs_window);
+void flexran_set_pdcp_rx_stat_window(mid_t mod_id, uint16_t uid, uint16_t obs_window);
 
 /*PDCP num tx pdu status flexRAN*/
-uint32_t flexran_get_pdcp_tx(mid_t mod_id, mid_t ue_id, lcid_t lcid);
+uint32_t flexran_get_pdcp_tx(mid_t mod_id, uint16_t uid, lcid_t lcid);
 
 /*PDCP num tx bytes status flexRAN*/
-uint32_t flexran_get_pdcp_tx_bytes(mid_t mod_id, mid_t ue_id, lcid_t lcid);
+uint32_t flexran_get_pdcp_tx_bytes(mid_t mod_id, uint16_t uid, lcid_t lcid);
 
 /*PDCP number of transmit packet / second status flexRAN*/
-uint32_t flexran_get_pdcp_tx_w(mid_t mod_id, mid_t ue_id, lcid_t lcid);
+uint32_t flexran_get_pdcp_tx_w(mid_t mod_id, uint16_t uid, lcid_t lcid);
 
 /*PDCP pdcp tx bytes in a given window flexRAN*/
-uint32_t flexran_get_pdcp_tx_bytes_w(mid_t mod_id, mid_t ue_id, lcid_t lcid);
+uint32_t flexran_get_pdcp_tx_bytes_w(mid_t mod_id, uint16_t uid, lcid_t lcid);
 
 /*PDCP tx sequence number flexRAN*/
-uint32_t flexran_get_pdcp_tx_sn(mid_t mod_id, mid_t ue_id, lcid_t lcid);
+uint32_t flexran_get_pdcp_tx_sn(mid_t mod_id, uint16_t uid, lcid_t lcid);
 
 /*PDCP tx aggregated packet arrival  flexRAN*/
-uint32_t flexran_get_pdcp_tx_aiat(mid_t mod_id, mid_t ue_id, lcid_t lcid);
+uint32_t flexran_get_pdcp_tx_aiat(mid_t mod_id, uint16_t uid, lcid_t lcid);
 
 /*PDCP tx aggregated packet arrival per second flexRAN*/
-uint32_t flexran_get_pdcp_tx_aiat_w(mid_t mod_id, mid_t ue_id, lcid_t lcid);
+uint32_t flexran_get_pdcp_tx_aiat_w(mid_t mod_id, uint16_t uid, lcid_t lcid);
 
 
 /*PDCP num rx pdu status flexRAN*/
-uint32_t flexran_get_pdcp_rx(mid_t mod_id, mid_t ue_id, lcid_t lcid);
+uint32_t flexran_get_pdcp_rx(mid_t mod_id, uint16_t uid, lcid_t lcid);
 
 /*PDCP num rx bytes status flexRAN*/
-uint32_t flexran_get_pdcp_rx_bytes(mid_t mod_id, mid_t ue_id, lcid_t lcid);
+uint32_t flexran_get_pdcp_rx_bytes(mid_t mod_id, uint16_t uid, lcid_t lcid);
 
 /*PDCP number of received packet / second  flexRAN*/
-uint32_t flexran_get_pdcp_rx_w(mid_t mod_id, mid_t ue_id, lcid_t lcid);
+uint32_t flexran_get_pdcp_rx_w(mid_t mod_id, uint16_t uid, lcid_t lcid);
 
 /*PDCP gootput (bit/s) status flexRAN*/
-uint32_t flexran_get_pdcp_rx_bytes_w(mid_t mod_id, mid_t ue_id, lcid_t lcid);
+uint32_t flexran_get_pdcp_rx_bytes_w(mid_t mod_id, uint16_t uid, lcid_t lcid);
 
 /*PDCP rx sequence number flexRAN*/
-uint32_t flexran_get_pdcp_rx_sn(mid_t mod_id, mid_t ue_id, lcid_t lcid);
+uint32_t flexran_get_pdcp_rx_sn(mid_t mod_id, uint16_t uid, lcid_t lcid);
 
 /*PDCP rx aggregated packet arrival  flexRAN*/
-uint32_t flexran_get_pdcp_rx_aiat(mid_t mod_id, mid_t ue_id, lcid_t lcid);
+uint32_t flexran_get_pdcp_rx_aiat(mid_t mod_id, uint16_t uid, lcid_t lcid);
 
 /*PDCP rx aggregated packet arrival per second flexRAN*/
-uint32_t flexran_get_pdcp_rx_aiat_w(mid_t mod_id, mid_t ue_id, lcid_t lcid);
+uint32_t flexran_get_pdcp_rx_aiat_w(mid_t mod_id, uint16_t uid, lcid_t lcid);
 
 /*PDCP num of received outoforder pdu status flexRAN*/
-uint32_t flexran_get_pdcp_rx_oo(mid_t mod_id, mid_t ue_id, lcid_t lcid);
+uint32_t flexran_get_pdcp_rx_oo(mid_t mod_id, uint16_t uid, lcid_t lcid);
 
 /*********************RRC**********************/
 /*Get primary cell measuremeant id flexRAN*/
-LTE_MeasId_t flexran_get_rrc_pcell_measid(mid_t mod_id, mid_t ue_id);
+LTE_MeasId_t flexran_get_rrc_pcell_measid(mid_t mod_id, rnti_t rnti);
 
 /*Get primary cell RSRP measurement flexRAN*/  
-float flexran_get_rrc_pcell_rsrp(mid_t mod_id, mid_t ue_id);
+float flexran_get_rrc_pcell_rsrp(mid_t mod_id, rnti_t rnti);
 
 /*Get primary cell RSRQ measurement flexRAN*/
-float flexran_get_rrc_pcell_rsrq(mid_t mod_id, mid_t ue_id);
+float flexran_get_rrc_pcell_rsrq(mid_t mod_id, rnti_t rnti);
 
 /* Get RRC neighbouring measurement */
-int flexran_get_rrc_num_ncell(mid_t mod_id, mid_t ue_id);
+int flexran_get_rrc_num_ncell(mid_t mod_id, rnti_t rnti);
 
-/*Get physical cell id*/
-LTE_PhysCellId_t flexran_get_rrc_neigh_phy_cell_id(mid_t mod_id, mid_t ue_id, int cell_id);
+/* Get physical cell id */
+long flexran_get_rrc_neigh_phy_cell_id(mid_t mod_id, rnti_t rnti, long cell_id);
 
-/*Get RSRP of neighbouring Cell*/
-float flexran_get_rrc_neigh_rsrp(mid_t mod_id, mid_t ue_id, int cell_id);
+/* Get RSRP of neighbouring Cell */
+float flexran_get_rrc_neigh_rsrp(mid_t mod_id, rnti_t rnti, long cell_id);
 
-/*Get RSRQ of neighbouring Cell*/
-float flexran_get_rrc_neigh_rsrq(mid_t mod_id, mid_t ue_id, int cell_id);
+/* Get RSRQ of neighbouring Cell */
+float flexran_get_rrc_neigh_rsrq(mid_t mod_id, rnti_t rnti, long cell_id);
 
 /*Get MCC PLMN identity neighbouring Cell*/
 /* currently not implemented
-int flexran_get_rrc_neigh_plmn_mcc(mid_t mod_id, mid_t ue_id, int cell_id); */
+int flexran_get_rrc_neigh_plmn_mcc(mid_t mod_id, rnti_t rnti, int cell_id); */
 
 /*Get MNC PLMN identity neighbouring Cell*/
 /* currently not implemented
 int flexran_get_rrc_neigh_plmn_mnc(mid_t mod_id, mid_t ue_id, int cell_id); */
 
+/* Get number of PLMNs that is broadcasted in SIB1 */
+uint8_t flexran_get_rrc_num_plmn_ids(mid_t mod_id);
+
+/* Get index'th MCC broadcasted in SIB1 */
+uint16_t flexran_get_rrc_mcc(mid_t mod_id, uint8_t index);
+
+/* Get index'th MNC broadcasted in SIB1 */
+uint16_t flexran_get_rrc_mnc(mid_t mod_id, uint8_t index);
+
+/* Get index'th MNC's digit length broadcasted in SIB1 */
+uint8_t flexran_get_rrc_mnc_digit_length(mid_t mod_id, uint8_t index);
+
 /************************** Slice configuration **************************/
 
 /* Get the DL slice ID for a UE */
@@ -660,3 +690,16 @@ void flexran_set_ul_slice_maxmcs(mid_t mod_id, int slice_idx, int maxmcs);
 char *flexran_get_ul_slice_scheduler(mid_t mod_id, int slice_idx);
 /* Set the scheduler name for a slice in UL */
 int flexran_set_ul_slice_scheduler(mid_t mod_id, int slice_idx, char *name);
+
+/********************* general information *****************/
+/* get an ID for this BS (or part of a BS) */
+uint64_t flexran_get_bs_id(mid_t mod_id);
+
+/* get the capabilities supported by the underlying network function,
+ * returns the number and stores list of this length in caps. If there are zero
+ * capabilities, *caps will be NULL */
+size_t flexran_get_capabilities(mid_t mod_id, Protocol__FlexBsCapability **caps);
+
+/* get the capabilities supported by the underlying network function as a bit
+ * mask. */
+uint16_t flexran_get_capabilities_mask(mid_t mod_id);
diff --git a/openair2/F1AP/MESSAGES/ASN1/R15.1.1/F1AP-CommonDataTypes.asn b/openair2/F1AP/MESSAGES/ASN1/R15.1.1/F1AP-CommonDataTypes.asn
new file mode 100644
index 0000000000000000000000000000000000000000..3e4e41784553864421420058f1bee9d5cb1ee53e
--- /dev/null
+++ b/openair2/F1AP/MESSAGES/ASN1/R15.1.1/F1AP-CommonDataTypes.asn
@@ -0,0 +1,32 @@
+-- **************************************************************
+--
+-- Common definitions
+--
+-- **************************************************************
+
+F1AP-CommonDataTypes {
+itu-t (0) identified-organization (4) etsi (0) mobileDomain (0) 
+ngran-access (22) modules (3) f1ap (3) version1 (1) f1ap-CommonDataTypes (3) }
+
+DEFINITIONS AUTOMATIC TAGS ::= 
+
+BEGIN
+
+Criticality		::= ENUMERATED { reject, ignore, notify }
+
+Presence		::= ENUMERATED { optional, conditional, mandatory }
+
+PrivateIE-ID	::= CHOICE {
+	local				INTEGER (0..65535),
+	global				OBJECT IDENTIFIER
+}
+
+ProcedureCode		::= INTEGER (0..255)
+
+ProtocolExtensionID	::= INTEGER (0..65535)
+
+ProtocolIE-ID		::= INTEGER (0..65535)
+
+TriggeringMessage	::= ENUMERATED { initiating-message, successful-outcome, unsuccessfull-outcome }
+
+END
\ No newline at end of file
diff --git a/openair2/F1AP/MESSAGES/ASN1/R15.1.1/F1AP-Constants.asn b/openair2/F1AP/MESSAGES/ASN1/R15.1.1/F1AP-Constants.asn
new file mode 100644
index 0000000000000000000000000000000000000000..6840b00bf42644b78c9a1644221436291c882738
--- /dev/null
+++ b/openair2/F1AP/MESSAGES/ASN1/R15.1.1/F1AP-Constants.asn
@@ -0,0 +1,179 @@
+-- **************************************************************
+--
+-- Constant definitions
+--
+-- **************************************************************
+
+F1AP-Constants { 
+itu-t (0) identified-organization (4) etsi (0) mobileDomain (0) 
+ngran-access (22) modules (3) f1ap (3) version1 (1) f1ap-Constants (4) } 
+
+DEFINITIONS AUTOMATIC TAGS ::= 
+
+BEGIN
+
+-- **************************************************************
+--
+-- IE parameter types from other modules.
+--
+-- **************************************************************
+
+IMPORTS
+	ProcedureCode,
+	ProtocolIE-ID
+
+FROM F1AP-CommonDataTypes;
+
+
+-- **************************************************************
+--
+-- Elementary Procedures
+--
+-- **************************************************************
+
+id-Reset									ProcedureCode ::= 0
+id-F1Setup									ProcedureCode ::= 1
+id-ErrorIndication							ProcedureCode ::= 2
+id-gNBDUConfigurationUpdate					ProcedureCode ::= 3
+id-gNBCUConfigurationUpdate					ProcedureCode ::= 4
+id-UEContextSetup							ProcedureCode ::= 5
+id-UEContextRelease							ProcedureCode ::= 6
+id-UEContextModification					ProcedureCode ::= 7
+id-UEContextModificationRequired			ProcedureCode ::= 8
+id-UEMobilityCommand						ProcedureCode ::= 9
+id-UEContextReleaseRequest					ProcedureCode ::= 10
+id-InitialULRRCMessageTransfer				ProcedureCode ::= 11
+id-DLRRCMessageTransfer						ProcedureCode ::= 12
+id-ULRRCMessageTransfer						ProcedureCode ::= 13
+id-privateMessage							ProcedureCode ::= 14
+
+-- **************************************************************
+--
+-- Extension constants
+--
+-- **************************************************************
+
+maxPrivateIEs							INTEGER ::= 65535
+maxProtocolExtensions					INTEGER ::= 65535
+maxProtocolIEs							INTEGER ::= 65535
+-- **************************************************************
+--
+-- Lists
+--
+-- **************************************************************
+
+maxNRARFCN								INTEGER ::= 3266667
+maxnoofErrors							INTEGER ::= 256
+maxnoofIndividualF1ConnectionsToReset	INTEGER ::= 65536
+maxCellingNBDU							INTEGER ::= 512
+maxnoofSCells							INTEGER ::= 64
+maxnoofSRBs								INTEGER ::= 8
+maxnoofDRBs								INTEGER ::= 64
+maxnoofULTunnels						INTEGER ::= 2
+maxnoofDLTunnels						INTEGER ::= 2
+maxnoofBPLMNs							INTEGER ::= 6
+maxnoofCandidateSpCells					INTEGER ::= 64
+maxnoofPotentialSpCells					INTEGER ::= 64
+
+-- **************************************************************
+--
+-- IEs
+--
+-- **************************************************************
+
+id-Cause											ProtocolIE-ID ::= 0
+id-Cells-Failed-to-be-Activated-List				ProtocolIE-ID ::= 1
+id-Cells-Failed-to-be-Activated-List-Item			ProtocolIE-ID ::= 2
+id-Cells-to-be-Activated-List						ProtocolIE-ID ::= 3
+id-Cells-to-be-Activated-List-Item					ProtocolIE-ID ::= 4
+id-Cells-to-be-Deactivated-List						ProtocolIE-ID ::= 5
+id-Cells-to-be-Deactivated-List-Item				ProtocolIE-ID ::= 6
+id-CriticalityDiagnostics							ProtocolIE-ID ::= 7
+id-CUtoDURRCInformation								ProtocolIE-ID ::= 9
+id-DRBs-FailedToBeModifiedConf-Item					ProtocolIE-ID ::= 10
+id-DRBs-FailedToBeModifiedConf-List					ProtocolIE-ID ::= 11
+id-DRBs-FailedToBeModified-Item						ProtocolIE-ID ::= 12
+id-DRBs-FailedToBeModified-List						ProtocolIE-ID ::= 13
+id-DRBs-FailedToBeSetup-Item						ProtocolIE-ID ::= 14
+id-DRBs-FailedToBeSetup-List						ProtocolIE-ID ::= 15
+id-DRBs-FailedToBeSetupMod-Item						ProtocolIE-ID ::= 16
+id-DRBs-FailedToBeSetupMod-List						ProtocolIE-ID ::= 17
+id-DRBs-ModifiedConf-Item							ProtocolIE-ID ::= 18
+id-DRBs-ModifiedConf-List							ProtocolIE-ID ::= 19
+id-DRBs-Modified-Item								ProtocolIE-ID ::= 20
+id-DRBs-Modified-List								ProtocolIE-ID ::= 21
+id-DRBs-Required-ToBeModified-Item					ProtocolIE-ID ::= 22
+id-DRBs-Required-ToBeModified-List					ProtocolIE-ID ::= 23
+id-DRBs-Required-ToBeReleased-Item					ProtocolIE-ID ::= 24
+id-DRBs-Required-ToBeReleased-List					ProtocolIE-ID ::= 25
+id-DRBs-Setup-Item									ProtocolIE-ID ::= 26
+id-DRBs-Setup-List									ProtocolIE-ID ::= 27
+id-DRBs-SetupMod-Item								ProtocolIE-ID ::= 28
+id-DRBs-SetupMod-List								ProtocolIE-ID ::= 29
+id-DRBs-ToBeModified-Item							ProtocolIE-ID ::= 30
+id-DRBs-ToBeModified-List							ProtocolIE-ID ::= 31
+id-DRBs-ToBeReleased-Item							ProtocolIE-ID ::= 32
+id-DRBs-ToBeReleased-List							ProtocolIE-ID ::= 33
+id-DRBs-ToBeSetup-Item								ProtocolIE-ID ::= 34
+id-DRBs-ToBeSetup-List								ProtocolIE-ID ::= 35
+id-DRBs-ToBeSetupMod-Item							ProtocolIE-ID ::= 36
+id-DRBs-ToBeSetupMod-List							ProtocolIE-ID ::= 37
+id-DRXCycle											ProtocolIE-ID ::= 38
+id-DUtoCURRCInformation								ProtocolIE-ID ::= 39
+id-gNB-CU-UE-F1AP-ID								ProtocolIE-ID ::= 40
+id-gNB-DU-UE-F1AP-ID								ProtocolIE-ID ::= 41
+id-gNB-DU-ID										ProtocolIE-ID ::= 42
+id-GNB-DU-Served-Cells-Item							ProtocolIE-ID ::= 43
+id-gNB-DU-Served-Cells-List							ProtocolIE-ID ::= 44
+id-gNB-DU-Name										ProtocolIE-ID ::= 45
+id-NRCellID											ProtocolIE-ID ::= 46
+id-oldgNB-DU-UE-F1AP-ID								ProtocolIE-ID ::= 47
+id-ResetType										ProtocolIE-ID ::= 48
+id-ResourceCoordinationTransferContainer			ProtocolIE-ID ::= 49
+id-RRCContainer										ProtocolIE-ID ::= 50
+id-SCell-ToBeRemoved-Item							ProtocolIE-ID ::= 51
+id-SCell-ToBeRemoved-List							ProtocolIE-ID ::= 52
+id-SCell-ToBeSetup-Item								ProtocolIE-ID ::= 53
+id-SCell-ToBeSetup-List								ProtocolIE-ID ::= 54
+id-SCell-ToBeSetupMod-Item							ProtocolIE-ID ::= 55
+id-SCell-ToBeSetupMod-List							ProtocolIE-ID ::= 56
+id-Served-Cells-To-Add-Item							ProtocolIE-ID ::= 57
+id-Served-Cells-To-Add-List							ProtocolIE-ID ::= 58
+id-Served-Cells-To-Delete-Item						ProtocolIE-ID ::= 59
+id-Served-Cells-To-Delete-List						ProtocolIE-ID ::= 60
+id-Served-Cells-To-Modify-Item						ProtocolIE-ID ::= 61
+id-Served-Cells-To-Modify-List						ProtocolIE-ID ::= 62
+id-SpCell-ID										ProtocolIE-ID ::= 63
+id-SRBID											ProtocolIE-ID ::= 64
+id-SRBs-FailedToBeSetup-Item						ProtocolIE-ID ::= 65
+id-SRBs-FailedToBeSetup-List						ProtocolIE-ID ::= 66
+id-SRBs-FailedToBeSetupMod-Item						ProtocolIE-ID ::= 67
+id-SRBs-FailedToBeSetupMod-List						ProtocolIE-ID ::= 68
+id-SRBs-Required-ToBeReleased-Item					ProtocolIE-ID ::= 69
+id-SRBs-Required-ToBeReleased-List					ProtocolIE-ID ::= 70
+id-SRBs-ToBeReleased-Item							ProtocolIE-ID ::= 71
+id-SRBs-ToBeReleased-List							ProtocolIE-ID ::= 72
+id-SRBs-ToBeSetup-Item								ProtocolIE-ID ::= 73
+id-SRBs-ToBeSetup-List								ProtocolIE-ID ::= 74
+id-SRBs-ToBeSetupMod-Item							ProtocolIE-ID ::= 75
+id-SRBs-ToBeSetupMod-List							ProtocolIE-ID ::= 76
+id-TimeToWait										ProtocolIE-ID ::= 77
+id-TransactionID									ProtocolIE-ID ::= 78
+id-TransmissionStopIndicator						ProtocolIE-ID ::= 79
+id-UE-associatedLogicalF1-ConnectionItem 			ProtocolIE-ID ::= 80
+id-UE-associatedLogicalF1-ConnectionListResAck		ProtocolIE-ID ::= 81
+id-gNB-CU-Name										ProtocolIE-ID ::= 82
+id-SCell-FailedtoSetup-List							ProtocolIE-ID ::= 83
+id-SCell-FailedtoSetup-Item							ProtocolIE-ID ::= 84
+id-SCell-FailedtoSetupMod-List						ProtocolIE-ID ::= 85
+id-SCell-FailedtoSetupMod-Item						ProtocolIE-ID ::= 86
+id-RRCRconfigurationCompleteIndicator 				ProtocolIE-ID ::= 87
+id-Active-Cells-Item								ProtocolIE-ID ::= 88
+id-Active-Cells-List								ProtocolIE-ID ::= 89
+id-Candidate-SpCell-List							ProtocolIE-ID ::= 90
+id-Candidate-SpCell-Item							ProtocolIE-ID ::= 91
+id-Potential-SpCell-List							ProtocolIE-ID ::= 92
+id-Potential-SpCell-Item							ProtocolIE-ID ::= 93
+
+
+END
\ No newline at end of file
diff --git a/openair2/F1AP/MESSAGES/ASN1/R15.1.1/F1AP-Containers.asn b/openair2/F1AP/MESSAGES/ASN1/R15.1.1/F1AP-Containers.asn
new file mode 100644
index 0000000000000000000000000000000000000000..52c09d156ac108fb4b9ffc8bf033a884296bdc2a
--- /dev/null
+++ b/openair2/F1AP/MESSAGES/ASN1/R15.1.1/F1AP-Containers.asn
@@ -0,0 +1,184 @@
+-- **************************************************************
+--
+-- Container definitions
+--
+-- **************************************************************
+
+F1AP-Containers {
+itu-t (0) identified-organization (4) etsi (0) mobileDomain (0) 
+ngran-access (22) modules (3) f1ap (3) version1 (1) f1ap-Containers (5) }
+
+DEFINITIONS AUTOMATIC TAGS ::= 
+
+BEGIN
+
+-- **************************************************************
+--
+-- IE parameter types from other modules.
+--
+-- **************************************************************
+
+IMPORTS
+	Criticality,
+	Presence,
+	PrivateIE-ID,
+	ProtocolExtensionID,
+	ProtocolIE-ID
+
+FROM F1AP-CommonDataTypes
+	maxPrivateIEs,
+	maxProtocolExtensions,
+	maxProtocolIEs
+
+FROM F1AP-Constants;
+
+-- **************************************************************
+--
+-- Class Definition for Protocol IEs
+--
+-- **************************************************************
+
+F1AP-PROTOCOL-IES ::= CLASS {
+	&id				ProtocolIE-ID 					UNIQUE,
+	&criticality	Criticality,
+	&Value,
+	&presence		Presence
+}
+WITH SYNTAX {
+	ID				&id
+	CRITICALITY		&criticality
+	TYPE			&Value
+	PRESENCE		&presence
+}
+
+-- **************************************************************
+--
+-- Class Definition for Protocol IEs
+--
+-- **************************************************************
+
+F1AP-PROTOCOL-IES-PAIR ::= CLASS {
+	&id					ProtocolIE-ID 				UNIQUE,
+	&firstCriticality	Criticality,
+	&FirstValue,
+	&secondCriticality	Criticality,
+	&SecondValue,
+	&presence			Presence
+}
+WITH SYNTAX {
+	ID				&id
+	FIRST CRITICALITY		&firstCriticality
+	FIRST TYPE				&FirstValue
+	SECOND CRITICALITY		&secondCriticality
+	SECOND TYPE				&SecondValue
+	PRESENCE				&presence
+}
+
+-- **************************************************************
+--
+-- Class Definition for Protocol Extensions
+--
+-- **************************************************************
+
+F1AP-PROTOCOL-EXTENSION ::= CLASS {
+	&id				ProtocolExtensionID			UNIQUE,
+	&criticality	Criticality,
+	&Extension,
+	&presence		Presence
+}
+WITH SYNTAX {
+	ID				&id
+	CRITICALITY		&criticality
+	EXTENSION		&Extension
+	PRESENCE		&presence
+}
+
+-- **************************************************************
+--
+-- Class Definition for Private IEs
+--
+-- **************************************************************
+
+F1AP-PRIVATE-IES ::= CLASS {
+	&id				PrivateIE-ID,
+	&criticality	Criticality,
+	&Value,
+	&presence		Presence
+}
+WITH SYNTAX {
+	ID				&id
+	CRITICALITY		&criticality
+	TYPE			&Value
+	PRESENCE		&presence
+}
+
+-- **************************************************************
+--
+-- Container for Protocol IEs
+--
+-- **************************************************************
+
+ProtocolIE-Container {F1AP-PROTOCOL-IES : IEsSetParam} ::= 
+	SEQUENCE (SIZE (0..maxProtocolIEs)) OF
+	ProtocolIE-Field {{IEsSetParam}}
+
+ProtocolIE-SingleContainer {F1AP-PROTOCOL-IES : IEsSetParam} ::= 
+	ProtocolIE-Field {{IEsSetParam}}
+
+ProtocolIE-Field {F1AP-PROTOCOL-IES : IEsSetParam} ::= SEQUENCE {
+	id				F1AP-PROTOCOL-IES.&id				({IEsSetParam}),
+	criticality		F1AP-PROTOCOL-IES.&criticality		({IEsSetParam}{@id}),
+	value			F1AP-PROTOCOL-IES.&Value			({IEsSetParam}{@id})
+}
+
+-- **************************************************************
+--
+-- Container for Protocol IE Pairs
+--
+-- **************************************************************
+
+ProtocolIE-ContainerPair {F1AP-PROTOCOL-IES-PAIR : IEsSetParam} ::= 
+	SEQUENCE (SIZE (0..maxProtocolIEs)) OF
+	ProtocolIE-FieldPair {{IEsSetParam}}
+
+ProtocolIE-FieldPair {F1AP-PROTOCOL-IES-PAIR : IEsSetParam} ::= SEQUENCE {
+	id					F1AP-PROTOCOL-IES-PAIR.&id					({IEsSetParam}),
+	firstCriticality	F1AP-PROTOCOL-IES-PAIR.&firstCriticality	({IEsSetParam}{@id}),
+	firstValue			F1AP-PROTOCOL-IES-PAIR.&FirstValue			({IEsSetParam}{@id}),
+	secondCriticality	F1AP-PROTOCOL-IES-PAIR.&secondCriticality	({IEsSetParam}{@id}),
+	secondValue			F1AP-PROTOCOL-IES-PAIR.&SecondValue			({IEsSetParam}{@id})
+}
+
+-- **************************************************************
+--
+-- Container for Protocol Extensions
+--
+-- **************************************************************
+
+ProtocolExtensionContainer {F1AP-PROTOCOL-EXTENSION : ExtensionSetParam} ::= 
+	SEQUENCE (SIZE (1..maxProtocolExtensions)) OF
+	ProtocolExtensionField {{ExtensionSetParam}}
+
+ProtocolExtensionField {F1AP-PROTOCOL-EXTENSION : ExtensionSetParam} ::= SEQUENCE {
+	id					F1AP-PROTOCOL-EXTENSION.&id				({ExtensionSetParam}),
+	criticality			F1AP-PROTOCOL-EXTENSION.&criticality	({ExtensionSetParam}{@id}),
+	extensionValue		F1AP-PROTOCOL-EXTENSION.&Extension		({ExtensionSetParam}{@id})
+}
+
+-- **************************************************************
+--
+-- Container for Private IEs
+--
+-- **************************************************************
+
+PrivateIE-Container {F1AP-PRIVATE-IES : IEsSetParam } ::= 
+	SEQUENCE (SIZE (1.. maxPrivateIEs)) OF
+	PrivateIE-Field {{IEsSetParam}}
+
+PrivateIE-Field {F1AP-PRIVATE-IES : IEsSetParam} ::= SEQUENCE {
+	id					F1AP-PRIVATE-IES.&id				({IEsSetParam}),
+	criticality			F1AP-PRIVATE-IES.&criticality		({IEsSetParam}{@id}),
+	value				F1AP-PRIVATE-IES.&Value				({IEsSetParam}{@id})
+}
+
+END
\ No newline at end of file
diff --git a/openair2/F1AP/MESSAGES/ASN1/R15.1.1/F1AP-IEs.asn b/openair2/F1AP/MESSAGES/ASN1/R15.1.1/F1AP-IEs.asn
new file mode 100644
index 0000000000000000000000000000000000000000..4a0d2abdffd1e9b6f4b5dfe14a3259989d875a01
--- /dev/null
+++ b/openair2/F1AP/MESSAGES/ASN1/R15.1.1/F1AP-IEs.asn
@@ -0,0 +1,870 @@
+-- **************************************************************
+--
+-- Information Element Definitions
+--
+-- **************************************************************
+
+F1AP-IEs {
+itu-t (0) identified-organization (4) etsi (0) mobileDomain (0) 
+ngran-access (22) modules (3) f1ap (3) version1 (1) f1ap-IEs (2) }
+
+DEFINITIONS AUTOMATIC TAGS ::= 
+
+BEGIN
+
+IMPORTS
+	maxNRARFCN,
+	maxnoofErrors,
+	maxnoofBPLMNs,
+	maxnoofDLTunnels,
+	maxnoofULTunnels
+
+FROM F1AP-Constants
+
+	Criticality,
+	ProcedureCode,
+	ProtocolIE-ID,
+	TriggeringMessage
+
+FROM F1AP-CommonDataTypes
+
+	ProtocolExtensionContainer{},
+	F1AP-PROTOCOL-EXTENSION,
+	ProtocolIE-SingleContainer{},
+	F1AP-PROTOCOL-IES
+
+FROM F1AP-Containers;
+
+-- A
+
+Active-Cells-Item ::= SEQUENCE {
+	nRCGI		NRCGI	,
+	iE-Extensions				ProtocolExtensionContainer { { Active-Cells-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+Active-Cells-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+
+AllocationAndRetentionPriority ::= SEQUENCE {
+	priorityLevel				PriorityLevel,
+	pre-emptionCapability		Pre-emptionCapability,
+	pre-emptionVulnerability	Pre-emptionVulnerability,
+	iE-Extensions				ProtocolExtensionContainer { {AllocationAndRetentionPriority-ExtIEs} } OPTIONAL,
+	...
+}
+
+AllocationAndRetentionPriority-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+-- B
+
+BitRate ::= INTEGER (0..4000000000000,...)
+
+BroadcastPLMNs-Item ::= SEQUENCE (SIZE(1..maxnoofBPLMNs)) OF PLMN-Identity
+
+-- C
+
+Candidate-SpCell-Item ::= SEQUENCE {
+	candidate-SpCell-ID			NRCGI	,
+	iE-Extensions	ProtocolExtensionContainer { { Candidate-SpCell-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+Candidate-SpCell-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+Cause ::= CHOICE {
+	radioNetwork		CauseRadioNetwork,
+	transport			CauseTransport,
+	protocol			CauseProtocol,
+	misc				CauseMisc,
+	...
+}
+
+CauseMisc ::= ENUMERATED {
+	control-processing-overload,
+	not-enough-user-plane-processing-resources,
+	hardware-failure,
+	om-intervention,
+	unspecified,
+...
+}
+
+CauseProtocol ::= ENUMERATED {
+	transfer-syntax-error,
+	abstract-syntax-error-reject,
+	abstract-syntax-error-ignore-and-notify,
+	message-not-compatible-with-receiver-state,
+	semantic-error,
+	abstract-syntax-error-falsely-constructed-message,
+	unspecified,
+	...
+}
+
+CauseRadioNetwork ::= ENUMERATED {
+	unspecified,
+	rlc-failure,
+	unknown-or-already-allocated-gnb-cu-ue-f1ap-id,
+	unknown-or-already-allocated-gnd-du-ue-f1ap-id,
+	unknown-or-inconsistent-pair-of-ue-f1ap-id,
+	interaction-with-other-procedure,
+	not-supported-qci-Value,
+	action-desirable-for-radio-reasons,
+	no-radio-resources-available,
+	procedure-cancelled,
+	normal-release,
+	...
+}
+
+CauseTransport ::= ENUMERATED {
+	unspecified,
+	transport-resource-unavailable,
+	...
+}
+
+
+
+CellGroupConfig ::= OCTET STRING
+
+Cells-Failed-to-be-Activated-List-Item ::= SEQUENCE {
+	nRCGI				NRCGI,
+	cause				Cause,
+	iE-Extensions		ProtocolExtensionContainer { { Cells-Failed-to-be-Activated-List-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+Cells-Failed-to-be-Activated-List-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+Cells-to-be-Activated-List-Item ::= SEQUENCE {
+	nRCGI		NRCGI,
+	nRPCI		NRPCI		OPTIONAL,
+	iE-Extensions				ProtocolExtensionContainer { { Cells-to-be-Activated-List-ItemExtIEs} }	OPTIONAL,
+	...
+}
+
+Cells-to-be-Activated-List-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+Cells-to-be-Deactivated-List-Item ::= SEQUENCE {
+	nRCGI			NRCGI	,
+	iE-Extensions				ProtocolExtensionContainer { { Cells-to-be-Deactivated-List-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+Cells-to-be-Deactivated-List-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+CriticalityDiagnostics ::= SEQUENCE {
+	procedureCode					ProcedureCode														OPTIONAL,
+	triggeringMessage				TriggeringMessage													OPTIONAL,
+	procedureCriticality			Criticality															OPTIONAL,
+	transactionID					TransactionID														OPTIONAL,
+	iEsCriticalityDiagnostics		CriticalityDiagnostics-IE-List										OPTIONAL,
+	iE-Extensions					ProtocolExtensionContainer {{CriticalityDiagnostics-ExtIEs}}		OPTIONAL,
+	...
+}
+
+CriticalityDiagnostics-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+CriticalityDiagnostics-IE-List ::= SEQUENCE (SIZE (1.. maxnoofErrors)) OF CriticalityDiagnostics-IE-Item
+
+CriticalityDiagnostics-IE-Item ::= SEQUENCE {
+	iECriticality			Criticality,
+	iE-ID					ProtocolIE-ID,
+	typeOfError 			TypeOfError,
+	iE-Extensions			ProtocolExtensionContainer {{CriticalityDiagnostics-IE-Item-ExtIEs}}	OPTIONAL,
+	...
+}
+
+CriticalityDiagnostics-IE-Item-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+CUtoDURRCInformation ::= SEQUENCE {
+	cG-ConfigInfo						CG-ConfigInfo						OPTIONAL,
+	uE-CapabilityRAT-ContainerList		UE-CapabilityRAT-ContainerList		OPTIONAL,
+	iE-Extensions				ProtocolExtensionContainer { { CUtoDURRCInformation-ExtIEs} } OPTIONAL,
+	...
+}
+
+CUtoDURRCInformation-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+-- D
+
+DLTunnels-ToBeSetup-List ::= SEQUENCE (SIZE(1..maxnoofDLTunnels)) OF DLTunnels-ToBeSetup-Item
+
+DLTunnels-ToBeSetup-Item ::= SEQUENCE {
+	dL-GTP-Tunnel-EndPoint	GTPTunnelEndpoint	,
+	iE-Extensions	ProtocolExtensionContainer { { DLTunnels-ToBeSetup-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+DLTunnels-ToBeSetup-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+DRBID ::= INTEGER (1..32, ...)
+
+DRBs-FailedToBeModified-Item	::= SEQUENCE {
+	dRBID		DRBID		,
+	cause		Cause		OPTIONAL,
+	iE-Extensions	ProtocolExtensionContainer { { DRBs-FailedToBeModified-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+DRBs-FailedToBeModified-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+DRBs-FailedToBeModifiedConf-Item	 	::= SEQUENCE {
+	dRBID		DRBID		,
+	cause		Cause		OPTIONAL,
+	iE-Extensions	ProtocolExtensionContainer { { DRBs-FailedToBeModifiedConf-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+DRBs-FailedToBeModifiedConf-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+DRBs-FailedToBeSetup-Item	::= SEQUENCE {
+	dRBID	DRBID,
+	cause	Cause	OPTIONAL,
+	iE-Extensions	ProtocolExtensionContainer { { DRBs-FailedToBeSetup-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+DRBs-FailedToBeSetup-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+
+DRBs-FailedToBeSetupMod-Item	::= SEQUENCE {
+	dRBID		DRBID	,
+	cause		Cause			OPTIONAL ,
+	iE-Extensions	ProtocolExtensionContainer { { DRBs-FailedToBeSetupMod-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+DRBs-FailedToBeSetupMod-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+DRBs-Modified-Item	::= SEQUENCE {
+	dRBID							DRBID,
+	dLTunnels-ToBeSetup-List		DLTunnels-ToBeSetup-List,
+	iE-Extensions	ProtocolExtensionContainer { { DRBs-Modified-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+DRBs-Modified-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+DRBs-ModifiedConf-Item	::= SEQUENCE {
+	dRBID							DRBID,
+	uLTunnels-ToBeSetup-List		ULTunnels-ToBeSetup-List	,
+	iE-Extensions	ProtocolExtensionContainer { { DRBs-ModifiedConf-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+DRBs-ModifiedConf-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+DRBs-Required-ToBeModified-Item	::= SEQUENCE {
+	dRBID							DRBID,
+	dLTunnels-ToBeSetup-List		DLTunnels-ToBeSetup-List	,
+	iE-Extensions	ProtocolExtensionContainer { { DRBs-Required-ToBeModified-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+DRBs-Required-ToBeModified-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+DRBs-Required-ToBeReleased-Item	::= SEQUENCE {
+	dRBID		DRBID,
+	iE-Extensions	ProtocolExtensionContainer { { DRBs-Required-ToBeReleased-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+DRBs-Required-ToBeReleased-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+DRBs-Setup-Item ::= SEQUENCE {
+	dRBID							DRBID,
+	dLTunnels-ToBeSetup-List		DLTunnels-ToBeSetup-List	, 
+	iE-Extensions	ProtocolExtensionContainer { { DRBs-Setup-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+DRBs-Setup-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+DRBs-SetupMod-Item	::= SEQUENCE {
+	dRBID							DRBID,
+	dLTunnels-ToBeSetup-List		DLTunnels-ToBeSetup-List	,
+	iE-Extensions	ProtocolExtensionContainer { { DRBs-SetupMod-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+DRBs-SetupMod-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+
+DRBs-ToBeModified-Item	::= SEQUENCE {
+	dRBID						DRBID,
+	eUTRANQoS					EUTRANQoS		OPTIONAL,
+	uLTunnels-ToBeSetup-List	ULTunnels-ToBeSetup-List	, 
+	uLConfiguration				ULConfiguration	OPTIONAL,
+	iE-Extensions	ProtocolExtensionContainer { { DRBs-ToBeModified-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+DRBs-ToBeModified-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+DRBs-ToBeReleased-Item	::= SEQUENCE {
+	dRBID	DRBID,
+	iE-Extensions	ProtocolExtensionContainer { { DRBs-ToBeReleased-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+DRBs-ToBeReleased-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+DRBs-ToBeSetup-Item ::= SEQUENCE	{
+	dRBID						DRBID,
+	eUTRANQoS					EUTRANQoS			OPTIONAL,
+	uLTunnels-ToBeSetup-List	ULTunnels-ToBeSetup-List	, 
+	rLCMode						RLCMode, 
+	uLConfiguration				ULConfiguration	OPTIONAL,
+	iE-Extensions	ProtocolExtensionContainer { { DRBs-ToBeSetup-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+DRBs-ToBeSetup-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+
+DRBs-ToBeSetupMod-Item	::= SEQUENCE {
+	dRBID						DRBID,
+	eUTRANQoS					EUTRANQoS		OPTIONAL,
+	rLCMode						RLCMode, 
+	uLConfiguration				ULConfiguration	OPTIONAL,
+	uLTunnels-ToBeSetup-List		ULTunnels-ToBeSetup-List,
+	iE-Extensions	ProtocolExtensionContainer { { DRBs-ToBeSetupMod-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+DRBs-ToBeSetupMod-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+DRXCycle	::= SEQUENCE {
+	longDRXCycleLength	LongDRXCycleLength,
+	shortDRXCycleLength		ShortDRXCycleLength	OPTIONAL,
+	shortDRXCycleTimer	ShortDRXCycleTimer OPTIONAL,
+	iE-Extensions		ProtocolExtensionContainer { { DRXCycle-ExtIEs} } OPTIONAL,
+	...
+}
+
+DRXCycle-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+DUtoCURRCInformation ::= SEQUENCE {
+	cellGroupConfig		CellGroupConfig,
+	gapOffset			GapOffset	OPTIONAL,
+	iE-Extensions				ProtocolExtensionContainer { { DUtoCURRCInformation-ExtIEs} } OPTIONAL,
+	...
+}
+
+DUtoCURRCInformation-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+-- E
+
+EUTRANQoS	::= SEQUENCE {
+	qCI								QCI,
+	allocationAndRetentionPriority	AllocationAndRetentionPriority,
+	gbrQosInformation				GBR-QosInformation									OPTIONAL,
+	iE-Extensions					ProtocolExtensionContainer { { EUTRANQoS-ExtIEs} }	OPTIONAL,
+	...
+}
+
+EUTRANQoS-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+Extended-TAC ::= OCTET STRING (SIZE(3))
+
+-- F
+
+FDD-Info ::= SEQUENCE {
+	uL-NRARFCN						NRARFCN,
+	dL-NRARFCN						NRARFCN,
+	uL-Transmission-Bandwidth		Transmission-Bandwidth,
+	dL-Transmission-Bandwidth		Transmission-Bandwidth,
+	iE-Extensions					ProtocolExtensionContainer { {FDD-Info-ExtIEs} } OPTIONAL,
+	...
+}
+
+FDD-Info-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+-- G
+
+GapOffset ::= OCTET STRING
+
+GBR-QosInformation ::= SEQUENCE {
+	e-RAB-MaximumBitrateDL			BitRate,
+	e-RAB-MaximumBitrateUL			BitRate,
+	e-RAB-GuaranteedBitrateDL		BitRate,
+	e-RAB-GuaranteedBitrateUL		BitRate,
+	iE-Extensions					ProtocolExtensionContainer { { GBR-QosInformation-ExtIEs} } OPTIONAL,
+	...
+}
+
+GBR-QosInformation-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+
+
+
+GNB-CU-UE-F1AP-ID		::= INTEGER (0..4294967295)
+
+GNB-DU-UE-F1AP-ID		::= INTEGER (0..4294967295)
+
+GNB-DU-ID			::= INTEGER (0..68719476735)
+
+GNB-CU-Name ::= PrintableString(SIZE(1..150,...))
+
+GNB-DU-Name ::= PrintableString(SIZE(1..150,...))
+
+GNB-DU-Served-Cells-Item ::= SEQUENCE {
+	served-Cell-Information		Served-Cell-Information,
+	gNB-DU-System-Information	GNB-DU-System-Information	OPTIONAL,
+	iE-Extensions				ProtocolExtensionContainer { { GNB-DU-Served-Cells-ItemExtIEs} }	OPTIONAL,
+	...
+}
+
+GNB-DU-Served-Cells-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+GNB-DU-System-Information ::= SEQUENCE {
+	mIB-message		MIB-message,
+	sIB1-message		SIB1-message,
+	iE-Extensions					ProtocolExtensionContainer { { GNB-DU-System-Information-ExtIEs } } OPTIONAL,
+	...
+}
+
+GNB-DU-System-Information-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+GTP-TEID				::= OCTET STRING (SIZE (4))
+
+GTPTunnelEndpoint ::= SEQUENCE {
+	transportLayerAddress				TransportLayerAddress,
+	gTP-TEID							GTP-TEID,
+	iE-Extensions						ProtocolExtensionContainer { { GTPTunnelEndpoint-ExtIEs} }	OPTIONAL,
+	...
+}
+
+
+GTPTunnelEndpoint-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+-- H
+
+-- I
+
+-- J
+
+-- K
+
+-- L
+
+LongDRXCycleLength ::= 	ENUMERATED
+{ms10, ms20, ms32, ms40, ms60, ms64, ms70, ms80, ms128, ms160, ms256, ms320, ms512, ms640, ms1024, ms1280, ms2048, ms2560, ms5120, ms10240, ...}
+
+-- M
+
+MIB-message ::= OCTET STRING
+
+-- N
+
+NRARFCN ::= INTEGER (0..maxNRARFCN)
+
+NRCGI ::= SEQUENCE {
+	pLMN-Identity			PLMN-Identity,
+	nRCellIdentity			NRCellIdentity,
+	iE-Extensions			ProtocolExtensionContainer { {NRCGI-ExtIEs} } OPTIONAL,
+	...
+}
+
+NRCGI-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+NR-Mode-Info ::= CHOICE {
+	fDD		FDD-Info,
+	tDD		TDD-Info,
+	...
+}
+
+NRCellIdentity ::= BIT STRING (SIZE(36))
+
+NRNRB ::= ENUMERATED { nrb11, nrb18, nrb24, nrb25, nrb31, nrb32, nrb38, nrb51, nrb52, nrb65, nrb66, nrb78, nrb79, nrb93, nrb106, nrb107, nrb121, nrb132, nrb133, nrb135, nrb160, nrb162, nrb189, nrb216, nrb217, nrb245, nrb264, nrb270, nrb273, ...}
+
+NRPCI ::= INTEGER(0..1007)
+
+NRSCS ::= ENUMERATED { scs15, scs30, scs60, scs120, ...}
+
+-- O
+
+-- P
+
+PLMN-Identity ::= OCTET STRING (SIZE(3))
+
+Pre-emptionCapability ::= ENUMERATED {
+	shall-not-trigger-pre-emption,
+	may-trigger-pre-emption
+}
+
+Pre-emptionVulnerability ::= ENUMERATED {
+	not-pre-emptable,
+	pre-emptable
+}
+
+PriorityLevel	::= INTEGER { spare (0), highest (1), lowest (14), no-priority (15) } (0..15)
+
+Potential-SpCell-Item ::= SEQUENCE {
+	potential-SpCell-ID			NRCGI	,
+	iE-Extensions	ProtocolExtensionContainer { { Potential-SpCell-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+Potential-SpCell-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+-- Q
+
+QCI ::= INTEGER (0..255)
+
+-- R
+
+ResourceCoordinationTransferContainer ::= OCTET STRING
+
+RLCMode ::= ENUMERATED {
+	rlc-am,
+	rlc-um
+}
+
+RRCContainer ::= OCTET STRING
+
+RRCRconfigurationCompleteIndicator	::= ENUMERATED {true, ...}
+
+-- S
+
+SCell-FailedtoSetup-Item	::= SEQUENCE {
+	sCell-ID			NRCGI	, 
+    cause		Cause			OPTIONAL ,
+	iE-Extensions	ProtocolExtensionContainer { { SCell-FailedtoSetup-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+SCell-FailedtoSetup-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+SCell-FailedtoSetupMod-Item	::= SEQUENCE {
+	sCell-ID			NRCGI	, 
+    cause		Cause			OPTIONAL ,
+	iE-Extensions	ProtocolExtensionContainer { { SCell-FailedtoSetupMod-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+SCell-FailedtoSetupMod-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+SCell-ToBeRemoved-Item	::= SEQUENCE {
+	sCell-ID			NRCGI	, 
+	iE-Extensions	ProtocolExtensionContainer { { SCell-ToBeRemoved-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+SCell-ToBeRemoved-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+SCell-ToBeSetup-Item ::= SEQUENCE {
+	sCell-ID			NRCGI	,
+	sCellIndex			SCellIndex,
+	iE-Extensions	ProtocolExtensionContainer { { SCell-ToBeSetup-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+SCell-ToBeSetup-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+SCell-ToBeSetupMod-Item	::= SEQUENCE {
+	sCell-ID			NRCGI	, 
+	sCellIndex			SCellIndex,
+	iE-Extensions	ProtocolExtensionContainer { { SCell-ToBeSetupMod-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+SCell-ToBeSetupMod-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+SCellIndex ::=INTEGER (0..31, ...)
+
+CG-ConfigInfo ::= OCTET STRING
+
+Served-Cell-Information ::= SEQUENCE {
+	nRCGI							NRCGI,
+	nRPCI							NRPCI,
+	extended-TAC					Extended-TAC,
+	broadcastPLMNs					BroadcastPLMNs-Item,
+	nR-Mode-Info					NR-Mode-Info, 
+	sUL-Information					SUL-Information 	OPTIONAL, 
+	measurementTimingConfiguration	OCTET STRING,
+	iE-Extensions		ProtocolExtensionContainer { {Served-Cell-Information-ExtIEs} } OPTIONAL,
+	...
+}
+
+Served-Cell-Information-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+Served-Cells-To-Add-Item ::= SEQUENCE {
+	served-Cell-Information		Served-Cell-Information,
+	gNB-DU-System-Information	GNB-DU-System-Information	 OPTIONAL, 
+	iE-Extensions				ProtocolExtensionContainer { { Served-Cells-To-Add-ItemExtIEs} }	OPTIONAL,
+	...
+}
+
+Served-Cells-To-Add-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+Served-Cells-To-Delete-Item ::= SEQUENCE {
+	oldNRCGI					NRCGI	,
+	iE-Extensions				ProtocolExtensionContainer { { Served-Cells-To-Delete-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+Served-Cells-To-Delete-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+Served-Cells-To-Modify-Item ::= SEQUENCE {
+	oldNRCGI					NRCGI							,
+	served-Cell-Information		Served-Cell-Information		,
+	gNB-DU-System-Information	GNB-DU-System-Information 	OPTIONAL	,
+	iE-Extensions				ProtocolExtensionContainer { { Served-Cells-To-Modify-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+Served-Cells-To-Modify-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+ShortDRXCycleLength ::=  ENUMERATED {ms2, ms3, ms4, ms5, ms6, ms7, ms8, ms10, ms14, ms16, ms20, ms30, ms32, ms35, ms40, ms64, ms80, ms128, ms160, ms256, ms320, ms512, ms640, ...}
+
+ShortDRXCycleTimer ::= INTEGER (1..16)
+
+SIB1-message ::= OCTET STRING
+
+SRBID ::= INTEGER (1..3, ...)
+
+SRBs-FailedToBeSetup-Item	::= SEQUENCE {
+	sRBID		SRBID	,
+	cause		Cause	OPTIONAL,
+	iE-Extensions	ProtocolExtensionContainer { { SRBs-FailedToBeSetup-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+SRBs-FailedToBeSetup-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+SRBs-FailedToBeSetupMod-Item	::= SEQUENCE {
+	sRBID		SRBID		,
+	cause		Cause		OPTIONAL,
+	iE-Extensions	ProtocolExtensionContainer { { SRBs-FailedToBeSetupMod-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+SRBs-FailedToBeSetupMod-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+
+SRBs-Required-ToBeReleased-Item	::= SEQUENCE {
+	sRBID	SRBID,
+	iE-Extensions	ProtocolExtensionContainer { { SRBs-Required-ToBeReleased-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+SRBs-Required-ToBeReleased-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+SRBs-ToBeReleased-Item	::= SEQUENCE {
+	sRBID		SRBID,
+	iE-Extensions	ProtocolExtensionContainer { { SRBs-ToBeReleased-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+SRBs-ToBeReleased-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+SRBs-ToBeSetup-Item ::= SEQUENCE {
+	sRBID	 SRBID	, 
+	iE-Extensions	ProtocolExtensionContainer { { SRBs-ToBeSetup-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+SRBs-ToBeSetup-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+SRBs-ToBeSetupMod-Item	::= SEQUENCE {
+	sRBID	SRBID,
+	iE-Extensions	ProtocolExtensionContainer { { SRBs-ToBeSetupMod-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+SRBs-ToBeSetupMod-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+SUL-Information ::= SEQUENCE {
+	sUL-NRARFCN							NRARFCN,
+	sUL-transmission-Bandwidth			Transmission-Bandwidth,
+	iE-Extensions				ProtocolExtensionContainer { { SUL-InformationExtIEs} } OPTIONAL,
+	...
+}
+
+SUL-InformationExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+-- T
+
+TDD-Info ::= SEQUENCE {
+	nRARFCN							NRARFCN,
+	transmission-Bandwidth			Transmission-Bandwidth,
+	iE-Extensions				ProtocolExtensionContainer { {TDD-Info-ExtIEs} } OPTIONAL,
+	...
+}
+
+TDD-Info-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+TimeToWait ::= ENUMERATED {v1s, v2s, v5s, v10s, v20s, v60s, ...}
+
+TransportLayerAddress		::= BIT STRING (SIZE(1..160, ...))
+
+TransactionID				::= INTEGER (0..255, ...)
+
+Transmission-Bandwidth ::= SEQUENCE {
+	nRSCS	NRSCS,
+	nRNRB	NRNRB,
+	iE-Extensions				ProtocolExtensionContainer { { Transmission-Bandwidth-ExtIEs} } OPTIONAL,
+	...
+}
+
+Transmission-Bandwidth-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+TransmissionStopIndicator ::= ENUMERATED {true, ...}
+
+TypeOfError ::= ENUMERATED {
+	not-understood,
+	missing,
+	...
+}
+
+-- U
+
+UE-associatedLogicalF1-ConnectionItem ::= SEQUENCE {
+	gNB-CU-UE-F1AP-ID		GNB-CU-UE-F1AP-ID	 OPTIONAL,
+	gNB-DU-UE-F1AP-ID		GNB-DU-UE-F1AP-ID	 OPTIONAL,
+	iE-Extensions		ProtocolExtensionContainer { { UE-associatedLogicalF1-ConnectionItemExtIEs} } OPTIONAL,
+	...
+}
+
+UE-associatedLogicalF1-ConnectionItemExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+UE-CapabilityRAT-ContainerList::= OCTET STRING
+
+ULConfiguration ::= SEQUENCE	{
+	uLUEConfiguration		ULUEConfiguration,
+	iE-Extensions	ProtocolExtensionContainer { { ULConfigurationExtIEs } }	OPTIONAL,
+	...
+}
+ULConfigurationExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+ULUEConfiguration ::= ENUMERATED {no-data, shared, only, ...}
+
+
+ULTunnels-ToBeSetup-List ::= SEQUENCE (SIZE(1..maxnoofULTunnels)) OF ULTunnels-ToBeSetup-Item
+
+ULTunnels-ToBeSetup-Item ::=SEQUENCE {
+	uL-GTP-Tunnel-EndPoint	GTPTunnelEndpoint, 
+	iE-Extensions	ProtocolExtensionContainer { { ULTunnels-ToBeSetup-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+ULTunnels-ToBeSetup-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+-- V
+
+-- W
+
+-- X
+
+-- Y
+
+-- Z
+
+END
\ No newline at end of file
diff --git a/openair2/F1AP/MESSAGES/ASN1/R15.1.1/F1AP-PDU-Contents.asn b/openair2/F1AP/MESSAGES/ASN1/R15.1.1/F1AP-PDU-Contents.asn
new file mode 100644
index 0000000000000000000000000000000000000000..813c79ac544ebe67c515ae5f833d9aa4072cae40
--- /dev/null
+++ b/openair2/F1AP/MESSAGES/ASN1/R15.1.1/F1AP-PDU-Contents.asn
@@ -0,0 +1,1076 @@
+-- **************************************************************
+--
+-- PDU definitions for F1AP.
+--
+-- **************************************************************
+
+F1AP-PDU-Contents { 
+itu-t (0) identified-organization (4) etsi (0) mobileDomain (0) 
+ngran-access (22) modules (3) f1ap (3) version1 (1) f1ap-PDU-Contents (1) }
+
+DEFINITIONS AUTOMATIC TAGS ::= 
+
+BEGIN
+
+-- **************************************************************
+--
+-- IE parameter types from other modules.
+--
+-- **************************************************************
+
+IMPORTS
+	Active-Cells-Item,
+	Candidate-SpCell-Item,
+	Cause,
+	Cells-Failed-to-be-Activated-List-Item,
+	Cells-to-be-Activated-List-Item,
+	Cells-to-be-Deactivated-List-Item,
+	CriticalityDiagnostics,
+	CUtoDURRCInformation,
+	DRBID,
+	DRBs-FailedToBeModifiedConf-Item,
+	DRBs-FailedToBeModified-Item,
+	DRBs-FailedToBeSetup-Item,
+	DRBs-FailedToBeSetupMod-Item,
+	DRBs-ModifiedConf-Item,
+	DRBs-Modified-Item,
+	DRBs-Required-ToBeModified-Item,
+	DRBs-Required-ToBeReleased-Item,
+	DRBs-Setup-Item,
+	DRBs-SetupMod-Item,
+	DRBs-ToBeModified-Item,
+	DRBs-ToBeReleased-Item,
+	DRBs-ToBeSetup-Item,
+	DRBs-ToBeSetupMod-Item,
+	DRXCycle,
+	DUtoCURRCInformation,
+	EUTRANQoS,
+	GNB-CU-UE-F1AP-ID,
+	GNB-DU-UE-F1AP-ID,
+	GNB-DU-ID,
+	GNB-DU-Served-Cells-Item,
+	GNB-DU-System-Information, 
+	GNB-CU-Name,
+	GNB-DU-Name,
+	GTPTunnelEndpoint,
+	NRCGI,
+	NRPCI,
+	Potential-SpCell-Item,
+	ResourceCoordinationTransferContainer,
+	RRCContainer,
+	RRCRconfigurationCompleteIndicator,
+	SCellIndex,
+	SCell-ToBeRemoved-Item,
+	SCell-ToBeSetup-Item,
+	SCell-ToBeSetupMod-Item,
+	SCell-FailedtoSetup-Item,
+	SCell-FailedtoSetupMod-Item,
+	Served-Cell-Information,
+	Served-Cells-To-Add-Item,
+	Served-Cells-To-Delete-Item,
+	Served-Cells-To-Modify-Item,
+	SRBID,
+	SRBs-FailedToBeSetup-Item,
+	SRBs-FailedToBeSetupMod-Item,
+	SRBs-Required-ToBeReleased-Item,
+	SRBs-ToBeReleased-Item,
+	SRBs-ToBeSetup-Item,
+	SRBs-ToBeSetupMod-Item,
+	TimeToWait,
+	TransactionID,
+	TransmissionStopIndicator,
+	UE-associatedLogicalF1-ConnectionItem,
+	ULTunnels-ToBeSetup-Item
+
+FROM F1AP-IEs
+
+	PrivateIE-Container{},
+	ProtocolExtensionContainer{},
+	ProtocolIE-Container{},
+	ProtocolIE-ContainerPair{},
+	ProtocolIE-SingleContainer{},
+	F1AP-PRIVATE-IES,
+	F1AP-PROTOCOL-EXTENSION,
+	F1AP-PROTOCOL-IES,
+	F1AP-PROTOCOL-IES-PAIR
+
+FROM F1AP-Containers
+
+	id-Active-Cells-Item,
+	id-Active-Cells-List,
+	id-Candidate-SpCell-Item,
+	id-Candidate-SpCell-List,
+	id-Cause,
+	id-Cells-Failed-to-be-Activated-List,
+	id-Cells-Failed-to-be-Activated-List-Item,
+	id-Cells-to-be-Activated-List,
+	id-Cells-to-be-Activated-List-Item,
+	id-Cells-to-be-Deactivated-List,
+	id-Cells-to-be-Deactivated-List-Item,
+	id-CriticalityDiagnostics,
+	id-CUtoDURRCInformation,
+	id-DRBs-FailedToBeModifiedConf-Item,
+	id-DRBs-FailedToBeModifiedConf-List,
+	id-DRBs-FailedToBeModified-Item,
+	id-DRBs-FailedToBeModified-List,
+	id-DRBs-FailedToBeSetup-Item,
+	id-DRBs-FailedToBeSetup-List,
+	id-DRBs-FailedToBeSetupMod-Item,
+	id-DRBs-FailedToBeSetupMod-List,
+	id-DRBs-ModifiedConf-Item,
+	id-DRBs-ModifiedConf-List,
+	id-DRBs-Modified-Item,
+	id-DRBs-Modified-List,
+	id-DRBs-Required-ToBeModified-Item,
+	id-DRBs-Required-ToBeModified-List,
+	id-DRBs-Required-ToBeReleased-Item,
+	id-DRBs-Required-ToBeReleased-List,
+	id-DRBs-Setup-Item,
+	id-DRBs-Setup-List,
+	id-DRBs-SetupMod-Item,
+	id-DRBs-SetupMod-List,
+	id-DRBs-ToBeModified-Item,
+	id-DRBs-ToBeModified-List,
+	id-DRBs-ToBeReleased-Item,
+	id-DRBs-ToBeReleased-List,
+	id-DRBs-ToBeSetup-Item,
+	id-DRBs-ToBeSetup-List,
+	id-DRBs-ToBeSetupMod-Item,
+	id-DRBs-ToBeSetupMod-List,
+	id-DRXCycle,
+	id-DUtoCURRCInformation,
+	id-gNB-CU-UE-F1AP-ID, 
+	id-gNB-DU-UE-F1AP-ID,
+	id-gNB-DU-ID,
+	id-GNB-DU-Served-Cells-Item,
+	id-gNB-DU-Served-Cells-List, 
+	id-gNB-CU-Name,
+	id-gNB-DU-Name,
+	id-oldgNB-DU-UE-F1AP-ID,
+	id-Potential-SpCell-Item,
+	id-Potential-SpCell-List,
+	id-ResetType,
+	id-ResourceCoordinationTransferContainer,
+	id-RRCContainer,
+	id-RRCRconfigurationCompleteIndicator,
+	id-SCell-FailedtoSetup-List,
+	id-SCell-FailedtoSetup-Item,
+	id-SCell-FailedtoSetupMod-List,
+	id-SCell-FailedtoSetupMod-Item,
+	id-SCell-ToBeRemoved-Item,
+	id-SCell-ToBeRemoved-List,
+	id-SCell-ToBeSetup-Item,
+	id-SCell-ToBeSetup-List,
+	id-SCell-ToBeSetupMod-Item,
+	id-SCell-ToBeSetupMod-List,
+	id-Served-Cells-To-Add-Item,
+	id-Served-Cells-To-Add-List,
+	id-Served-Cells-To-Delete-Item,
+	id-Served-Cells-To-Delete-List,
+	id-Served-Cells-To-Modify-Item,
+	id-Served-Cells-To-Modify-List,
+	id-SpCell-ID,
+	id-SRBID,
+	id-SRBs-FailedToBeSetup-Item,
+	id-SRBs-FailedToBeSetup-List,
+	id-SRBs-FailedToBeSetupMod-Item,
+	id-SRBs-FailedToBeSetupMod-List,
+	id-SRBs-Required-ToBeReleased-Item,
+	id-SRBs-Required-ToBeReleased-List,
+	id-SRBs-ToBeReleased-Item,
+	id-SRBs-ToBeReleased-List, 
+	id-SRBs-ToBeSetup-Item,
+	id-SRBs-ToBeSetup-List,
+	id-SRBs-ToBeSetupMod-Item,
+	id-SRBs-ToBeSetupMod-List,
+	id-TimeToWait,
+	id-TransactionID,
+	id-TransmissionStopIndicator,
+	id-UE-associatedLogicalF1-ConnectionItem,
+	id-UE-associatedLogicalF1-ConnectionListResAck,
+	maxCellingNBDU,
+	maxnoofCandidateSpCells,
+	maxnoofDRBs,
+	maxnoofErrors,
+	maxnoofIndividualF1ConnectionsToReset,
+	maxnoofPotentialSpCells,
+	maxnoofSCells,
+	maxnoofSRBs
+
+FROM F1AP-Constants;
+
+
+-- **************************************************************
+--
+-- RESET ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- Reset
+--
+-- **************************************************************
+
+Reset ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       { {ResetIEs} },
+	...
+}
+
+ResetIEs F1AP-PROTOCOL-IES ::= { 
+	{ ID id-TransactionID				CRITICALITY reject	TYPE TransactionID				PRESENCE mandatory	}|
+	{ ID id-Cause						CRITICALITY ignore	TYPE Cause						PRESENCE mandatory	}|
+	{ ID id-ResetType					CRITICALITY reject	TYPE ResetType					PRESENCE mandatory	},
+	...
+}
+
+ResetType ::= CHOICE {
+	f1-Interface					ResetAll,
+	partOfF1-Interface				UE-associatedLogicalF1-ConnectionListRes,
+	...
+}
+
+
+ResetAll ::= ENUMERATED {
+	reset-all,
+	...
+}
+
+UE-associatedLogicalF1-ConnectionListRes ::= SEQUENCE (SIZE(1.. maxnoofIndividualF1ConnectionsToReset)) OF ProtocolIE-SingleContainer { { UE-associatedLogicalF1-ConnectionItemRes } }
+
+UE-associatedLogicalF1-ConnectionItemRes F1AP-PROTOCOL-IES ::= {
+	{ ID id-UE-associatedLogicalF1-ConnectionItem	CRITICALITY reject	TYPE UE-associatedLogicalF1-ConnectionItem	PRESENCE mandatory},
+	...
+}
+
+
+
+
+-- **************************************************************
+--
+-- Reset Acknowledge
+--
+-- **************************************************************
+
+ResetAcknowledge ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       { {ResetAcknowledgeIEs} },
+	...
+}
+
+ResetAcknowledgeIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-TransactionID									CRITICALITY reject	TYPE TransactionID													PRESENCE mandatory	}|
+	{ ID id-UE-associatedLogicalF1-ConnectionListResAck		CRITICALITY ignore	TYPE UE-associatedLogicalF1-ConnectionListResAck			PRESENCE optional	}|
+	{ ID id-CriticalityDiagnostics		CRITICALITY ignore	TYPE CriticalityDiagnostics			PRESENCE optional	},
+	...
+}
+
+UE-associatedLogicalF1-ConnectionListResAck ::= SEQUENCE (SIZE(1.. maxnoofIndividualF1ConnectionsToReset)) OF ProtocolIE-SingleContainer { { UE-associatedLogicalF1-ConnectionItemResAck } }
+
+UE-associatedLogicalF1-ConnectionItemResAck 	F1AP-PROTOCOL-IES ::= {
+	{ ID id-UE-associatedLogicalF1-ConnectionItem	 CRITICALITY ignore 	TYPE UE-associatedLogicalF1-ConnectionItem  	PRESENCE mandatory },
+	...
+}
+
+-- **************************************************************
+--
+-- ERROR INDICATION ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- Error Indication
+--
+-- **************************************************************
+
+ErrorIndication ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       {{ErrorIndicationIEs}},
+	...
+}
+
+ErrorIndicationIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-TransactionID				CRITICALITY reject	TYPE TransactionID				PRESENCE mandatory}|
+	{ ID id-gNB-CU-UE-F1AP-ID			CRITICALITY ignore	TYPE GNB-CU-UE-F1AP-ID			PRESENCE optional	}|
+	{ ID id-gNB-DU-UE-F1AP-ID			CRITICALITY ignore	TYPE GNB-DU-UE-F1AP-ID			PRESENCE optional	}|
+	{ ID id-Cause						CRITICALITY ignore	TYPE Cause						PRESENCE optional	}|
+	{ ID id-CriticalityDiagnostics		CRITICALITY ignore	TYPE CriticalityDiagnostics		PRESENCE optional	},
+	...
+}
+
+-- **************************************************************
+--
+-- F1 SETUP ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- F1 Setup Request
+--
+-- **************************************************************
+
+F1SetupRequest ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       { {F1SetupRequestIEs} },
+	...
+}
+
+F1SetupRequestIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-TransactionID					CRITICALITY reject	TYPE TransactionID				PRESENCE mandatory	}|
+	{ ID id-gNB-DU-ID						CRITICALITY reject	TYPE GNB-DU-ID					PRESENCE mandatory	}|
+	{ ID id-gNB-DU-Name						CRITICALITY ignore	TYPE GNB-DU-Name				PRESENCE optional	}|
+	{ ID id-gNB-DU-Served-Cells-List		CRITICALITY reject	TYPE GNB-DU-Served-Cells-List	PRESENCE mandatory	},
+	...
+} 
+
+
+GNB-DU-Served-Cells-List 	::= SEQUENCE (SIZE(1.. maxCellingNBDU)) OF ProtocolIE-SingleContainer { { GNB-DU-Served-Cells-ItemIEs } }
+
+GNB-DU-Served-Cells-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-GNB-DU-Served-Cells-Item		CRITICALITY reject	TYPE		GNB-DU-Served-Cells-Item	PRESENCE mandatory	},
+	...
+}
+
+
+-- **************************************************************
+--
+-- F1 Setup Response
+--
+-- **************************************************************
+
+F1SetupResponse ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       { {F1SetupResponseIEs} },
+	...
+}
+
+
+F1SetupResponseIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-TransactionID				CRITICALITY reject	TYPE TransactionID					PRESENCE mandatory	}|
+	{ ID id-gNB-CU-Name					CRITICALITY ignore	TYPE GNB-CU-Name					PRESENCE optional	}|
+	{ ID id-Cells-to-be-Activated-List	CRITICALITY reject	TYPE Cells-to-be-Activated-List		PRESENCE optional	},
+	...
+}
+
+
+Cells-to-be-Activated-List	::= SEQUENCE (SIZE(1.. maxCellingNBDU))	OF ProtocolIE-SingleContainer { { Cells-to-be-Activated-List-ItemIEs } }
+
+Cells-to-be-Activated-List-ItemIEs	F1AP-PROTOCOL-IES::= {
+	{ ID id-Cells-to-be-Activated-List-Item				CRITICALITY reject	TYPE Cells-to-be-Activated-List-Item						PRESENCE mandatory},
+	...
+}
+
+
+
+-- **************************************************************
+--
+-- F1 Setup Failure
+--
+-- **************************************************************
+
+F1SetupFailure ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       { {F1SetupFailureIEs} },
+	...
+}
+
+F1SetupFailureIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-TransactionID				CRITICALITY reject	TYPE TransactionID				PRESENCE mandatory	}|
+	{ ID id-Cause						CRITICALITY ignore	TYPE Cause						PRESENCE mandatory	}|
+	{ ID id-TimeToWait					CRITICALITY ignore	TYPE TimeToWait					PRESENCE optional	}|
+	{ ID id-CriticalityDiagnostics		CRITICALITY ignore	TYPE CriticalityDiagnostics		PRESENCE optional	},
+	...
+}
+
+
+-- **************************************************************
+--
+-- GNB-DU CONFIGURATION UPDATE ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- GNB-DU CONFIGURATION UPDATE
+--
+-- **************************************************************
+
+GNBDUConfigurationUpdate::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       { {GNBDUConfigurationUpdateIEs} },
+	...
+}
+
+GNBDUConfigurationUpdateIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-TransactionID					CRITICALITY reject	TYPE TransactionID									PRESENCE mandatory	}|
+	{ ID id-Served-Cells-To-Add-List		CRITICALITY reject	TYPE Served-Cells-To-Add-List						PRESENCE optional	}|
+	{ ID id-Served-Cells-To-Modify-List		CRITICALITY reject	TYPE Served-Cells-To-Modify-List					PRESENCE optional	}|
+	{ ID id-Served-Cells-To-Delete-List		CRITICALITY reject	TYPE Served-Cells-To-Delete-List					PRESENCE optional	}|
+	{ ID id-Active-Cells-List				CRITICALITY reject	TYPE	 Active-Cells-List							PRESENCE optional	},
+	...
+} 
+Served-Cells-To-Add-List		::= SEQUENCE (SIZE(1.. maxCellingNBDU))	OF ProtocolIE-SingleContainer { { Served-Cells-To-Add-ItemIEs } }
+Served-Cells-To-Modify-List	::= SEQUENCE (SIZE(1.. maxCellingNBDU))	OF ProtocolIE-SingleContainer { { Served-Cells-To-Modify-ItemIEs } }
+Served-Cells-To-Delete-List	::= SEQUENCE (SIZE(1.. maxCellingNBDU))	OF ProtocolIE-SingleContainer { { Served-Cells-To-Delete-ItemIEs } }
+Active-Cells-List	::= SEQUENCE (SIZE(1.. maxCellingNBDU))	OF ProtocolIE-SingleContainer { { Active-Cells-ItemIEs } }
+
+Served-Cells-To-Add-ItemIEs F1AP-PROTOCOL-IES	::= {
+	{ ID id-Served-Cells-To-Add-Item		CRITICALITY reject	TYPE	Served-Cells-To-Add-Item				PRESENCE mandatory	},
+	...
+}
+
+Served-Cells-To-Modify-ItemIEs F1AP-PROTOCOL-IES	::= {
+	{ ID id-Served-Cells-To-Modify-Item			CRITICALITY reject	TYPE		Served-Cells-To-Modify-Item							PRESENCE mandatory	},
+	...
+}
+
+Served-Cells-To-Delete-ItemIEs F1AP-PROTOCOL-IES	::= {
+	{ ID id-Served-Cells-To-Delete-Item				CRITICALITY reject	TYPE		Served-Cells-To-Delete-Item					PRESENCE mandatory	},
+...
+}
+
+Active-Cells-ItemIEs F1AP-PROTOCOL-IES	::= {
+	{ ID id-Active-Cells-Item				CRITICALITY reject	TYPE		Active-Cells-Item					PRESENCE mandatory	},
+	...
+}
+
+
+-- **************************************************************
+--
+-- GNB-DU CONFIGURATION UPDATE ACKNOWLEDGE
+--
+-- **************************************************************
+
+GNBDUConfigurationUpdateAcknowledge ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       { {GNBDUConfigurationUpdateAcknowledgeIEs} },
+	...
+}
+
+
+GNBDUConfigurationUpdateAcknowledgeIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-TransactionID					CRITICALITY reject	TYPE TransactionID						PRESENCE mandatory	}|
+	{ ID id-Cells-to-be-Activated-List		CRITICALITY reject	TYPE Cells-to-be-Activated-List			PRESENCE optional	}|
+	{ ID id-CriticalityDiagnostics			CRITICALITY ignore	TYPE CriticalityDiagnostics				PRESENCE optional	},
+	...
+}
+
+-- **************************************************************
+--
+-- GNB-DU CONFIGURATION UPDATE FAILURE
+--
+-- **************************************************************
+
+GNBDUConfigurationUpdateFailure ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       { {GNBDUConfigurationUpdateFailureIEs} },
+	...
+}
+
+GNBDUConfigurationUpdateFailureIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-TransactionID				CRITICALITY reject	TYPE TransactionID				PRESENCE mandatory	}|
+	{ ID id-Cause						CRITICALITY ignore	TYPE Cause						PRESENCE mandatory	}|
+	{ ID id-TimeToWait					CRITICALITY ignore	TYPE TimeToWait					PRESENCE optional	}|
+	{ ID id-CriticalityDiagnostics		CRITICALITY ignore	TYPE CriticalityDiagnostics		PRESENCE optional	},
+	...
+}
+
+-- **************************************************************
+--
+-- GNB-CU CONFIGURATION UPDATE ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- GNB-CU CONFIGURATION UPDATE
+--
+-- **************************************************************
+
+GNBCUConfigurationUpdate ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       { { GNBCUConfigurationUpdateIEs} },
+	...
+}
+
+GNBCUConfigurationUpdateIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-TransactionID					CRITICALITY reject	TYPE TransactionID									PRESENCE mandatory	}|
+	{ ID id-Cells-to-be-Activated-List		CRITICALITY reject	TYPE	 Cells-to-be-Activated-List				PRESENCE optional	}|
+	{ ID id-Cells-to-be-Deactivated-List	CRITICALITY reject	TYPE	 Cells-to-be-Deactivated-List			PRESENCE optional	},
+	...
+} 
+
+Cells-to-be-Deactivated-List	::= SEQUENCE (SIZE(1.. maxCellingNBDU))	OF ProtocolIE-SingleContainer { { Cells-to-be-Deactivated-List-ItemIEs } }
+
+Cells-to-be-Deactivated-List-ItemIEs F1AP-PROTOCOL-IES	::= {
+	{ ID id-Cells-to-be-Deactivated-List-Item						CRITICALITY reject	TYPE	Cells-to-be-Deactivated-List-Item					PRESENCE mandatory	},
+...}
+
+
+-- **************************************************************
+--
+-- GNB-CU CONFIGURATION UPDATE ACKNOWLEDGE
+--
+-- **************************************************************
+
+GNBCUConfigurationUpdateAcknowledge ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       { { GNBCUConfigurationUpdateAcknowledgeIEs} },
+	...
+}
+
+
+GNBCUConfigurationUpdateAcknowledgeIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-TransactionID						CRITICALITY reject	TYPE TransactionID									PRESENCE mandatory	}|
+	{ ID id-Cells-Failed-to-be-Activated-List	CRITICALITY reject	TYPE Cells-Failed-to-be-Activated-List			PRESENCE optional}|
+	{ ID id-CriticalityDiagnostics				CRITICALITY ignore	TYPE CriticalityDiagnostics							PRESENCE optional	},
+	...
+}
+
+Cells-Failed-to-be-Activated-List	::= SEQUENCE (SIZE(1.. maxCellingNBDU))	OF ProtocolIE-SingleContainer { { Cells-Failed-to-be-Activated-List-ItemIEs } }
+
+Cells-Failed-to-be-Activated-List-ItemIEs F1AP-PROTOCOL-IES		::= {
+	{ ID id-Cells-Failed-to-be-Activated-List-Item		CRITICALITY reject	TYPE Cells-Failed-to-be-Activated-List-Item		PRESENCE mandatory	},
+	...
+}
+
+
+-- **************************************************************
+--
+-- GNB-CU CONFIGURATION UPDATE FAILURE
+--
+-- **************************************************************
+
+GNBCUConfigurationUpdateFailure ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       { { GNBCUConfigurationUpdateFailureIEs} },
+	...
+}
+
+GNBCUConfigurationUpdateFailureIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-TransactionID				CRITICALITY reject	TYPE TransactionID				PRESENCE mandatory	}|
+	{ ID id-Cause						CRITICALITY ignore	TYPE Cause						PRESENCE mandatory	}|
+	{ ID id-TimeToWait					CRITICALITY ignore	TYPE TimeToWait					PRESENCE optional	}|
+	{ ID id-CriticalityDiagnostics		CRITICALITY ignore	TYPE CriticalityDiagnostics		PRESENCE optional	},
+	...
+}
+
+-- **************************************************************
+--
+-- UE Context Setup ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- UE CONTEXT SETUP REQUEST
+--
+-- **************************************************************
+
+UEContextSetupRequest ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       { { UEContextSetupRequestIEs} },
+	...
+}
+
+UEContextSetupRequestIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-gNB-CU-UE-F1AP-ID						CRITICALITY reject	TYPE GNB-CU-UE-F1AP-ID								PRESENCE mandatory	}|
+	{ ID id-gNB-DU-UE-F1AP-ID						CRITICALITY ignore	TYPE GNB-DU-UE-F1AP-ID								PRESENCE optional 	}|
+	{ ID id-SpCell-ID								CRITICALITY reject	TYPE NRCGI											PRESENCE mandatory	}|
+	{ ID id-CUtoDURRCInformation					CRITICALITY reject	TYPE CUtoDURRCInformation							PRESENCE mandatory}|
+	{ ID id-Candidate-SpCell-List					CRITICALITY ignore	TYPE Candidate-SpCell-List						PRESENCE optional	}|
+	{ ID id-DRXCycle								CRITICALITY ignore	TYPE DRXCycle										PRESENCE optional	}|
+	{ ID id-ResourceCoordinationTransferContainer	CRITICALITY ignore	TYPE ResourceCoordinationTransferContainer	PRESENCE optional	}|
+	{ ID id-SCell-ToBeSetup-List					CRITICALITY ignore	TYPE SCell-ToBeSetup-List							PRESENCE optional	}|
+	{ ID id-SRBs-ToBeSetup-List						CRITICALITY reject	TYPE SRBs-ToBeSetup-List							PRESENCE optional	}|
+	{ ID id-DRBs-ToBeSetup-List						CRITICALITY reject	TYPE DRBs-ToBeSetup-List							PRESENCE mandatory	},
+	...
+} 
+
+Candidate-SpCell-List::= SEQUENCE (SIZE(1..maxnoofCandidateSpCells)) OF ProtocolIE-SingleContainer { { Candidate-SpCell-ItemIEs} }
+SCell-ToBeSetup-List::= SEQUENCE (SIZE(1..maxnoofSCells)) OF ProtocolIE-SingleContainer { { SCell-ToBeSetup-ItemIEs} }
+SRBs-ToBeSetup-List ::= SEQUENCE (SIZE(1..maxnoofSRBs)) OF ProtocolIE-SingleContainer { { SRBs-ToBeSetup-ItemIEs} }
+DRBs-ToBeSetup-List ::= SEQUENCE (SIZE(1..maxnoofDRBs)) OF ProtocolIE-SingleContainer { { DRBs-ToBeSetup-ItemIEs} }
+
+
+Candidate-SpCell-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-Candidate-SpCell-Item					CRITICALITY ignore	TYPE Candidate-SpCell-Item						PRESENCE mandatory	},
+	...
+}
+
+
+SCell-ToBeSetup-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-SCell-ToBeSetup-Item						CRITICALITY ignore	TYPE SCell-ToBeSetup-Item					PRESENCE mandatory	},
+	...
+}
+
+SRBs-ToBeSetup-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-SRBs-ToBeSetup-Item		CRITICALITY reject		TYPE SRBs-ToBeSetup-Item		PRESENCE mandatory},
+	...
+}
+
+DRBs-ToBeSetup-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-DRBs-ToBeSetup-Item					CRITICALITY reject	TYPE DRBs-ToBeSetup-Item					PRESENCE mandatory},
+	...
+}
+
+
+
+-- **************************************************************
+--
+-- UE CONTEXT SETUP RESPONSE
+--
+-- **************************************************************
+
+UEContextSetupResponse ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       { { UEContextSetupResponseIEs} },
+	...
+}
+
+
+UEContextSetupResponseIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-gNB-CU-UE-F1AP-ID						CRITICALITY reject	TYPE GNB-CU-UE-F1AP-ID								PRESENCE mandatory	}|
+	{ ID id-gNB-DU-UE-F1AP-ID						CRITICALITY reject	TYPE GNB-DU-UE-F1AP-ID								PRESENCE mandatory	}|
+	{ ID id-DUtoCURRCInformation					CRITICALITY reject	TYPE DUtoCURRCInformation							PRESENCE mandatory }|
+	{ ID id-ResourceCoordinationTransferContainer	CRITICALITY ignore	TYPE ResourceCoordinationTransferContainer	PRESENCE optional	}|
+	{ ID id-DRBs-Setup-List							CRITICALITY ignore	TYPE DRBs-Setup-List								PRESENCE mandatory}|
+	{ ID id-SRBs-FailedToBeSetup-List				CRITICALITY ignore	TYPE SRBs-FailedToBeSetup-List					PRESENCE optional	}|
+	{ ID id-DRBs-FailedToBeSetup-List				CRITICALITY ignore	TYPE DRBs-FailedToBeSetup-List					PRESENCE optional	}|
+	{ ID id-SCell-FailedtoSetup-List				CRITICALITY ignore	TYPE SCell-FailedtoSetup-List					PRESENCE optional	}|
+	{ ID id-CriticalityDiagnostics					CRITICALITY ignore	TYPE CriticalityDiagnostics						PRESENCE optional	},
+	...
+}
+
+DRBs-Setup-List ::= SEQUENCE (SIZE(1..maxnoofDRBs)) OF ProtocolIE-SingleContainer { { DRBs-Setup-ItemIEs} }
+SRBs-FailedToBeSetup-List ::= SEQUENCE (SIZE(1..maxnoofSRBs)) OF ProtocolIE-SingleContainer { { SRBs-FailedToBeSetup-ItemIEs} }
+DRBs-FailedToBeSetup-List ::= SEQUENCE (SIZE(1..maxnoofDRBs)) OF ProtocolIE-SingleContainer { { DRBs-FailedToBeSetup-ItemIEs} }
+SCell-FailedtoSetup-List ::= SEQUENCE (SIZE(1..maxnoofSCells)) OF ProtocolIE-SingleContainer { { SCell-FailedtoSetup-ItemIEs} }
+
+DRBs-Setup-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-DRBs-Setup-Item						CRITICALITY ignore	TYPE DRBs-Setup-Item						PRESENCE mandatory},
+	...
+}
+
+SRBs-FailedToBeSetup-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-SRBs-FailedToBeSetup-Item		CRITICALITY ignore		TYPE SRBs-FailedToBeSetup-Item		PRESENCE mandatory},
+	...
+}
+
+
+DRBs-FailedToBeSetup-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-DRBs-FailedToBeSetup-Item		CRITICALITY ignore	TYPE DRBs-FailedToBeSetup-Item			PRESENCE mandatory},
+	...
+}
+
+SCell-FailedtoSetup-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-SCell-FailedtoSetup-Item			CRITICALITY ignore	TYPE SCell-FailedtoSetup-Item			PRESENCE mandatory},
+	...
+}
+
+-- **************************************************************
+--
+-- UE CONTEXT SETUP FAILURE
+--
+-- **************************************************************
+
+UEContextSetupFailure ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       { { UEContextSetupFailureIEs} },
+	...
+}
+
+UEContextSetupFailureIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-gNB-CU-UE-F1AP-ID			CRITICALITY reject	TYPE GNB-CU-UE-F1AP-ID			PRESENCE mandatory	}|
+	{ ID id-gNB-DU-UE-F1AP-ID			CRITICALITY ignore	TYPE GNB-DU-UE-F1AP-ID			PRESENCE optional	}|
+	{ ID id-Cause						CRITICALITY ignore	TYPE Cause						PRESENCE mandatory	}|
+	{ ID id-CriticalityDiagnostics		CRITICALITY ignore	TYPE CriticalityDiagnostics		PRESENCE optional	}|
+	{ ID id-Potential-SpCell-List		CRITICALITY ignore	TYPE Potential-SpCell-List		PRESENCE optional	},
+	...
+}
+
+Potential-SpCell-List::= SEQUENCE (SIZE(0..maxnoofPotentialSpCells)) OF ProtocolIE-SingleContainer { { Potential-SpCell-ItemIEs} }
+
+Potential-SpCell-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-Potential-SpCell-Item				CRITICALITY ignore	TYPE Potential-SpCell-Item					PRESENCE mandatory	},
+	...
+}
+
+-- **************************************************************
+--
+-- UE Context Release Request ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- UE Context Release Request
+--
+-- **************************************************************
+
+UEContextReleaseRequest ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       {{ UEContextReleaseRequestIEs}},
+	...
+}
+
+UEContextReleaseRequestIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-gNB-CU-UE-F1AP-ID				CRITICALITY reject	TYPE GNB-CU-UE-F1AP-ID				PRESENCE mandatory	}|
+	{ ID id-gNB-DU-UE-F1AP-ID				CRITICALITY reject	TYPE GNB-DU-UE-F1AP-ID				PRESENCE mandatory	}|
+	{ ID id-Cause							CRITICALITY ignore	TYPE Cause							PRESENCE mandatory	},
+	...
+}
+
+
+-- **************************************************************
+--
+-- UE Context Release (gNB-CU initiated) ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- UE CONTEXT RELEASE COMMAND 
+--
+-- **************************************************************
+
+UEContextReleaseCommand ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       { { UEContextReleaseCommandIEs} },
+	...
+}
+
+UEContextReleaseCommandIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-gNB-CU-UE-F1AP-ID				CRITICALITY reject	TYPE GNB-CU-UE-F1AP-ID				PRESENCE mandatory	}|
+	{ ID id-gNB-DU-UE-F1AP-ID				CRITICALITY reject	TYPE GNB-DU-UE-F1AP-ID				PRESENCE mandatory	}|
+	{ ID id-Cause							CRITICALITY ignore	TYPE Cause							PRESENCE mandatory	},
+	...
+} 
+
+-- **************************************************************
+--
+-- UE CONTEXT RELEASE COMPLETE
+--
+-- **************************************************************
+
+UEContextReleaseComplete ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       { { UEContextReleaseCompleteIEs} },
+	...
+}
+
+
+UEContextReleaseCompleteIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-gNB-CU-UE-F1AP-ID			CRITICALITY reject	TYPE GNB-CU-UE-F1AP-ID			PRESENCE mandatory	}|
+	{ ID id-gNB-DU-UE-F1AP-ID			CRITICALITY reject	TYPE GNB-DU-UE-F1AP-ID			PRESENCE mandatory	}|
+	{ ID id-CriticalityDiagnostics		CRITICALITY ignore	TYPE CriticalityDiagnostics		PRESENCE optional	},	...
+}
+
+-- **************************************************************
+--
+-- UE Context Modification ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- UE CONTEXT MODIFICATION REQUEST
+--
+-- **************************************************************
+
+UEContextModificationRequest ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       { { UEContextModificationRequestIEs} },
+	...
+}
+
+UEContextModificationRequestIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-gNB-CU-UE-F1AP-ID						CRITICALITY reject	TYPE GNB-CU-UE-F1AP-ID								PRESENCE mandatory	}|
+	{ ID id-gNB-DU-UE-F1AP-ID						CRITICALITY reject	TYPE GNB-DU-UE-F1AP-ID								PRESENCE mandatory	}|
+	{ ID id-SpCell-ID								CRITICALITY ignore	TYPE NRCGI											PRESENCE optional	}|
+	{ ID id-DRXCycle								CRITICALITY ignore	TYPE DRXCycle										PRESENCE optional	}|
+	{ ID id-CUtoDURRCInformation					CRITICALITY reject	TYPE CUtoDURRCInformation							PRESENCE optional	}|
+	{ ID id-TransmissionStopIndicator				CRITICALITY ignore	TYPE TransmissionStopIndicator					PRESENCE optional	}|
+	{ ID id-ResourceCoordinationTransferContainer	CRITICALITY ignore	TYPE ResourceCoordinationTransferContainer	PRESENCE optional	}|
+	{ ID id-RRCRconfigurationCompleteIndicator		CRITICALITY ignore	TYPE RRCRconfigurationCompleteIndicator		PRESENCE optional	}|
+	{ ID id-RRCContainer							CRITICALITY reject	TYPE RRCContainer									PRESENCE optional	}|
+	{ ID id-SCell-ToBeSetupMod-List					CRITICALITY ignore	TYPE SCell-ToBeSetupMod-List						PRESENCE optional	}|
+	{ ID id-SCell-ToBeRemoved-List					CRITICALITY ignore	TYPE SCell-ToBeRemoved-List 						PRESENCE optional }|
+	{ ID id-SRBs-ToBeSetupMod-List					CRITICALITY reject	TYPE SRBs-ToBeSetupMod-List						PRESENCE optional	}|
+	{ ID id-DRBs-ToBeSetupMod-List					CRITICALITY reject	TYPE DRBs-ToBeSetupMod-List						PRESENCE optional	}|
+	{ ID id-DRBs-ToBeModified-List					CRITICALITY reject	TYPE DRBs-ToBeModified-List						PRESENCE optional	}|
+	{ ID id-SRBs-ToBeReleased-List					CRITICALITY reject	TYPE SRBs-ToBeReleased-List						PRESENCE optional	}|
+	{ ID id-DRBs-ToBeReleased-List					CRITICALITY reject	TYPE DRBs-ToBeReleased-List						PRESENCE optional	},
+	...
+} 
+
+SCell-ToBeSetupMod-List::= SEQUENCE (SIZE(1..maxnoofSCells)) OF ProtocolIE-SingleContainer { { SCell-ToBeSetupMod-ItemIEs} }
+SCell-ToBeRemoved-List::= SEQUENCE (SIZE(1..maxnoofSCells)) OF ProtocolIE-SingleContainer { { SCell-ToBeRemoved-ItemIEs} }
+SRBs-ToBeSetupMod-List ::= SEQUENCE (SIZE(1..maxnoofSRBs)) OF ProtocolIE-SingleContainer { { SRBs-ToBeSetupMod-ItemIEs} }
+DRBs-ToBeSetupMod-List ::= SEQUENCE (SIZE(1..maxnoofDRBs)) OF ProtocolIE-SingleContainer { { DRBs-ToBeSetupMod-ItemIEs} }
+
+DRBs-ToBeModified-List ::= SEQUENCE (SIZE(1..maxnoofDRBs)) OF ProtocolIE-SingleContainer { { DRBs-ToBeModified-ItemIEs} }
+SRBs-ToBeReleased-List ::= SEQUENCE (SIZE(1..maxnoofSRBs)) OF ProtocolIE-SingleContainer { { SRBs-ToBeReleased-ItemIEs} }
+DRBs-ToBeReleased-List ::= SEQUENCE (SIZE(1..maxnoofDRBs)) OF ProtocolIE-SingleContainer { { DRBs-ToBeReleased-ItemIEs} }
+
+SCell-ToBeSetupMod-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-SCell-ToBeSetupMod-Item			CRITICALITY ignore	TYPE SCell-ToBeSetupMod-Item			PRESENCE mandatory	},
+	...
+}
+
+SCell-ToBeRemoved-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-SCell-ToBeRemoved-Item			CRITICALITY ignore	TYPE SCell-ToBeRemoved-Item			PRESENCE mandatory	},
+	...
+}
+
+
+SRBs-ToBeSetupMod-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-SRBs-ToBeSetupMod-Item		CRITICALITY reject	TYPE SRBs-ToBeSetupMod-Item		PRESENCE mandatory},
+	...
+}
+
+
+DRBs-ToBeSetupMod-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-DRBs-ToBeSetupMod-Item		CRITICALITY reject	TYPE DRBs-ToBeSetupMod-Item		PRESENCE mandatory},
+	...
+}
+
+DRBs-ToBeModified-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-DRBs-ToBeModified-Item		CRITICALITY reject	TYPE DRBs-ToBeModified-Item			PRESENCE mandatory},
+	...
+}
+
+
+SRBs-ToBeReleased-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-SRBs-ToBeReleased-Item	CRITICALITY reject	TYPE SRBs-ToBeReleased-Item		PRESENCE mandatory},
+	...
+}
+
+DRBs-ToBeReleased-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-DRBs-ToBeReleased-Item		CRITICALITY reject	TYPE DRBs-ToBeReleased-Item		PRESENCE mandatory},
+	...
+}
+
+-- **************************************************************
+--
+-- UE CONTEXT MODIFICATION RESPONSE
+--
+-- **************************************************************
+
+UEContextModificationResponse ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       { { UEContextModificationResponseIEs} },
+	...
+}
+
+
+UEContextModificationResponseIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-gNB-CU-UE-F1AP-ID						CRITICALITY reject	TYPE GNB-CU-UE-F1AP-ID								PRESENCE mandatory	}|
+	{ ID id-gNB-DU-UE-F1AP-ID						CRITICALITY reject	TYPE GNB-DU-UE-F1AP-ID								PRESENCE mandatory	}|
+	{ ID id-ResourceCoordinationTransferContainer	CRITICALITY ignore	TYPE ResourceCoordinationTransferContainer	PRESENCE optional	}|
+	{ ID id-DUtoCURRCInformation					CRITICALITY reject	TYPE DUtoCURRCInformation							PRESENCE optional}|
+	{ ID id-DRBs-SetupMod-List						CRITICALITY ignore	TYPE DRBs-SetupMod-List								PRESENCE optional}|
+	{ ID id-DRBs-Modified-List						CRITICALITY ignore	TYPE DRBs-Modified-List								PRESENCE optional}|
+	{ ID id-SRBs-FailedToBeSetupMod-List			CRITICALITY ignore	TYPE SRBs-FailedToBeSetupMod-List				PRESENCE optional	}|
+	{ ID id-DRBs-FailedToBeSetupMod-List			CRITICALITY ignore	TYPE DRBs-FailedToBeSetupMod-List				PRESENCE optional	}|
+	{ ID id-SCell-FailedtoSetupMod-List				CRITICALITY ignore	TYPE SCell-FailedtoSetupMod-List				PRESENCE optional	}|
+	{ ID id-DRBs-FailedToBeModified-List			CRITICALITY ignore	TYPE DRBs-FailedToBeModified-List				PRESENCE optional	}|
+	{ ID id-CriticalityDiagnostics					CRITICALITY ignore	TYPE CriticalityDiagnostics						PRESENCE optional	},
+	...
+}
+
+
+DRBs-SetupMod-List ::= SEQUENCE (SIZE(1..maxnoofDRBs)) OF ProtocolIE-SingleContainer { { DRBs-SetupMod-ItemIEs} }
+DRBs-Modified-List::= SEQUENCE (SIZE(1..maxnoofDRBs)) OF ProtocolIE-SingleContainer { { DRBs-Modified-ItemIEs } }
+DRBs-FailedToBeModified-List ::= SEQUENCE (SIZE(1..maxnoofDRBs)) OF ProtocolIE-SingleContainer { { DRBs-FailedToBeModified-ItemIEs} }
+SRBs-FailedToBeSetupMod-List ::= SEQUENCE (SIZE(1..maxnoofSRBs)) OF ProtocolIE-SingleContainer { { SRBs-FailedToBeSetupMod-ItemIEs} }
+DRBs-FailedToBeSetupMod-List ::= SEQUENCE (SIZE(1..maxnoofDRBs)) OF ProtocolIE-SingleContainer { { DRBs-FailedToBeSetupMod-ItemIEs} }
+SCell-FailedtoSetupMod-List ::= SEQUENCE (SIZE(1..maxnoofSCells)) OF ProtocolIE-SingleContainer { { SCell-FailedtoSetupMod-ItemIEs} }
+
+DRBs-SetupMod-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-DRBs-SetupMod-Item		CRITICALITY ignore		TYPE DRBs-SetupMod-Item		PRESENCE mandatory},
+	...
+}
+
+
+DRBs-Modified-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-DRBs-Modified-Item			CRITICALITY ignore	TYPE DRBs-Modified-Item		PRESENCE mandatory},
+	...
+}
+
+SRBs-FailedToBeSetupMod-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-SRBs-FailedToBeSetupMod-Item		CRITICALITY ignore	TYPE SRBs-FailedToBeSetupMod-Item		PRESENCE mandatory},
+	...
+}
+
+
+
+DRBs-FailedToBeSetupMod-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-DRBs-FailedToBeSetupMod-Item		CRITICALITY ignore	TYPE DRBs-FailedToBeSetupMod-Item		PRESENCE mandatory},
+	...
+}
+
+
+DRBs-FailedToBeModified-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-DRBs-FailedToBeModified-Item		CRITICALITY ignore	TYPE DRBs-FailedToBeModified-Item		PRESENCE mandatory},
+	...
+}
+
+SCell-FailedtoSetupMod-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-SCell-FailedtoSetupMod-Item			CRITICALITY ignore	TYPE SCell-FailedtoSetupMod-Item			PRESENCE mandatory},
+	...
+}
+
+-- **************************************************************
+--
+-- UE CONTEXT MODIFICATION FAILURE
+--
+-- **************************************************************
+
+UEContextModificationFailure ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       { { UEContextModificationFailureIEs} },
+	...
+}
+
+UEContextModificationFailureIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-gNB-CU-UE-F1AP-ID				CRITICALITY reject	TYPE GNB-CU-UE-F1AP-ID				PRESENCE mandatory	}|
+	{ ID id-gNB-DU-UE-F1AP-ID				CRITICALITY reject	TYPE GNB-DU-UE-F1AP-ID				PRESENCE mandatory	}|
+	{ ID id-Cause							CRITICALITY ignore	TYPE Cause							PRESENCE mandatory	}|
+	{ ID id-CriticalityDiagnostics			CRITICALITY ignore	TYPE CriticalityDiagnostics			PRESENCE optional	},
+	...
+}
+
+
+-- **************************************************************
+--
+-- UE Context Modification Required (gNB-DU initiated) ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- UE CONTEXT MODIFICATION REQUIRED
+--
+-- **************************************************************
+
+UEContextModificationRequired ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       { { UEContextModificationRequiredIEs} },
+	...
+}
+
+UEContextModificationRequiredIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-gNB-CU-UE-F1AP-ID							CRITICALITY reject	TYPE GNB-CU-UE-F1AP-ID								PRESENCE mandatory	}|
+	{ ID id-gNB-DU-UE-F1AP-ID							CRITICALITY reject	TYPE GNB-DU-UE-F1AP-ID								PRESENCE mandatory	}|
+	{ ID id-ResourceCoordinationTransferContainer		CRITICALITY ignore	TYPE ResourceCoordinationTransferContainer		PRESENCE optional	}|
+	{ ID id-DUtoCURRCInformation						CRITICALITY reject	TYPE DUtoCURRCInformation							PRESENCE optional}|
+	{ ID id-DRBs-Required-ToBeModified-List				CRITICALITY reject	TYPE DRBs-Required-ToBeModified-List				PRESENCE optional}|
+	{ ID id-SRBs-Required-ToBeReleased-List				CRITICALITY reject	TYPE SRBs-Required-ToBeReleased-List				PRESENCE optional}|
+	{ ID id-DRBs-Required-ToBeReleased-List				CRITICALITY reject	TYPE DRBs-Required-ToBeReleased-List				PRESENCE optional}|
+	{ ID id-Cause										CRITICALITY ignore	TYPE Cause												PRESENCE mandatory	},
+	...
+} 
+
+DRBs-Required-ToBeModified-List::= SEQUENCE (SIZE(1..maxnoofDRBs)) OF ProtocolIE-SingleContainer { { DRBs-Required-ToBeModified-ItemIEs } }
+DRBs-Required-ToBeReleased-List::= SEQUENCE (SIZE(1..maxnoofDRBs)) OF ProtocolIE-SingleContainer { { DRBs-Required-ToBeReleased-ItemIEs } }
+
+SRBs-Required-ToBeReleased-List::= SEQUENCE (SIZE(1..maxnoofSRBs)) OF ProtocolIE-SingleContainer { { SRBs-Required-ToBeReleased-ItemIEs } }
+
+DRBs-Required-ToBeModified-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-DRBs-Required-ToBeModified-Item			CRITICALITY reject	TYPE DRBs-Required-ToBeModified-Item		PRESENCE mandatory},
+	...
+}
+
+DRBs-Required-ToBeReleased-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-DRBs-Required-ToBeReleased-Item			CRITICALITY reject	TYPE DRBs-Required-ToBeReleased-Item		PRESENCE mandatory},
+	...
+}
+
+SRBs-Required-ToBeReleased-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-SRBs-Required-ToBeReleased-Item			CRITICALITY reject	TYPE SRBs-Required-ToBeReleased-Item			PRESENCE mandatory},
+	...
+}
+
+-- **************************************************************
+--
+-- UE CONTEXT MODIFICATION CONFIRM
+--
+-- **************************************************************
+
+UEContextModificationConfirm::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       { { UEContextModificationConfirmIEs} },
+	...
+}
+
+
+UEContextModificationConfirmIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-gNB-CU-UE-F1AP-ID							CRITICALITY reject	TYPE GNB-CU-UE-F1AP-ID								PRESENCE mandatory	}|
+	{ ID id-gNB-DU-UE-F1AP-ID							CRITICALITY reject	TYPE GNB-DU-UE-F1AP-ID								PRESENCE mandatory	}|
+	{ ID id-ResourceCoordinationTransferContainer		CRITICALITY ignore	TYPE ResourceCoordinationTransferContainer		PRESENCE optional	}|
+	{ ID id-DRBs-ModifiedConf-List						CRITICALITY ignore	TYPE DRBs-ModifiedConf-List							PRESENCE optional}|
+	{ ID id-DRBs-FailedToBeModifiedConf-List			CRITICALITY ignore	TYPE DRBs-FailedToBeModifiedConf-List			PRESENCE optional	}|
+	{ ID id-CriticalityDiagnostics						CRITICALITY ignore	TYPE CriticalityDiagnostics							PRESENCE optional	},
+	...
+}
+
+DRBs-ModifiedConf-List::= SEQUENCE (SIZE(1..maxnoofDRBs)) OF ProtocolIE-SingleContainer { { DRBs-ModifiedConf-ItemIEs } }
+DRBs-FailedToBeModifiedConf-List ::= SEQUENCE (SIZE(1..maxnoofDRBs)) OF ProtocolIE-SingleContainer { { DRBs-FailedToBeModifiedConf-ItemIEs} }
+
+DRBs-ModifiedConf-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-DRBs-ModifiedConf-Item		CRITICALITY ignore	TYPE DRBs-ModifiedConf-Item			PRESENCE mandatory},
+	...
+}
+
+DRBs-FailedToBeModifiedConf-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-DRBs-FailedToBeModifiedConf-Item		CRITICALITY ignore		TYPE DRBs-FailedToBeModifiedConf-Item		PRESENCE mandatory},
+	...
+}
+
+-- **************************************************************
+--
+-- DL RRC Message Transfer ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- DL RRC Message Transfer
+--
+-- **************************************************************
+
+DLRRCMessageTransfer ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       {{ DLRRCMessageTransferIEs}},
+	...
+}
+
+DLRRCMessageTransferIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-gNB-CU-UE-F1AP-ID							CRITICALITY reject	TYPE GNB-CU-UE-F1AP-ID							PRESENCE mandatory	}|
+	{ ID id-gNB-DU-UE-F1AP-ID							CRITICALITY reject	TYPE GNB-DU-UE-F1AP-ID							PRESENCE mandatory	}|
+	{ ID id-oldgNB-DU-UE-F1AP-ID						CRITICALITY reject	TYPE GNB-DU-UE-F1AP-ID							PRESENCE optional	}|
+	{ ID id-SRBID										CRITICALITY reject	TYPE SRBID											PRESENCE mandatory	}|
+	{ ID id-RRCContainer								CRITICALITY reject	TYPE RRCContainer									PRESENCE mandatory	},
+	...
+}
+-- **************************************************************
+--
+-- UL RRC Message Transfer ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- UL RRC Message Transfer
+--
+-- **************************************************************
+
+ULRRCMessageTransfer ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       {{ ULRRCMessageTransferIEs}},
+	...
+}
+
+ULRRCMessageTransferIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-gNB-CU-UE-F1AP-ID				CRITICALITY reject	TYPE GNB-CU-UE-F1AP-ID				PRESENCE mandatory	}|
+	{ ID id-gNB-DU-UE-F1AP-ID				CRITICALITY reject	TYPE GNB-DU-UE-F1AP-ID				PRESENCE mandatory	}|
+	{ ID id-SRBID							CRITICALITY reject	TYPE SRBID							PRESENCE mandatory	}|
+	{ ID id-RRCContainer					CRITICALITY reject	TYPE RRCContainer					PRESENCE mandatory	},
+	...
+}
+
+-- **************************************************************
+--
+-- PRIVATE MESSAGE
+--
+-- **************************************************************
+
+PrivateMessage ::= SEQUENCE {
+	privateIEs		PrivateIE-Container	{{PrivateMessage-IEs}},
+	...
+}
+
+PrivateMessage-IEs F1AP-PRIVATE-IES ::= {
+	...
+}
+
+END
diff --git a/openair2/F1AP/MESSAGES/ASN1/R15.1.1/F1AP-PDU-Descriptions.asn b/openair2/F1AP/MESSAGES/ASN1/R15.1.1/F1AP-PDU-Descriptions.asn
new file mode 100644
index 0000000000000000000000000000000000000000..99a67d89da1b76d2a821eac502e7c71b399184f0
--- /dev/null
+++ b/openair2/F1AP/MESSAGES/ASN1/R15.1.1/F1AP-PDU-Descriptions.asn
@@ -0,0 +1,258 @@
+-- **************************************************************
+--
+-- Elementary Procedure definitions
+--
+-- **************************************************************
+
+F1AP-PDU-Descriptions  { 
+itu-t (0) identified-organization (4) etsi (0) mobileDomain (0) 
+ngran-access (22) modules (3) f1ap (3) version1 (1) f1ap-PDU-Descriptions (0)}
+
+DEFINITIONS AUTOMATIC TAGS ::= 
+
+BEGIN
+
+-- **************************************************************
+--
+-- IE parameter types from other modules.
+--
+-- **************************************************************
+
+IMPORTS
+	Criticality,
+	ProcedureCode
+
+FROM F1AP-CommonDataTypes
+	Reset,
+	ResetAcknowledge,
+	F1SetupRequest,
+	F1SetupResponse,
+	F1SetupFailure, 
+	GNBDUConfigurationUpdate,
+	GNBDUConfigurationUpdateAcknowledge,
+	GNBDUConfigurationUpdateFailure,
+	GNBCUConfigurationUpdate,
+	GNBCUConfigurationUpdateAcknowledge,
+	GNBCUConfigurationUpdateFailure,
+	UEContextSetupRequest,
+	UEContextSetupResponse,
+	UEContextSetupFailure,
+	UEContextReleaseCommand,
+	UEContextReleaseComplete,
+	UEContextModificationRequest,
+	UEContextModificationResponse,
+	UEContextModificationFailure,
+	UEContextModificationRequired,
+	UEContextModificationConfirm,
+	ErrorIndication,
+	UEContextReleaseRequest,
+	DLRRCMessageTransfer,
+	ULRRCMessageTransfer,
+	PrivateMessage
+
+FROM F1AP-PDU-Contents
+	id-Reset,
+	id-F1Setup,
+	id-gNBDUConfigurationUpdate,
+	id-gNBCUConfigurationUpdate,
+	id-UEContextSetup,
+	id-UEContextRelease,
+	id-UEContextModification,
+	id-UEContextModificationRequired,
+	id-ErrorIndication, 
+	id-UEContextReleaseRequest,
+	id-DLRRCMessageTransfer,
+	id-ULRRCMessageTransfer,
+	id-privateMessage
+
+
+FROM F1AP-Constants;
+
+
+-- **************************************************************
+--
+-- Interface Elementary Procedure Class
+--
+-- **************************************************************
+
+F1AP-ELEMENTARY-PROCEDURE ::= CLASS {
+	&InitiatingMessage				,
+	&SuccessfulOutcome							OPTIONAL,
+	&UnsuccessfulOutcome						OPTIONAL,
+	&procedureCode				ProcedureCode 	UNIQUE,
+	&criticality				Criticality 	DEFAULT ignore
+}
+WITH SYNTAX {
+	INITIATING MESSAGE			&InitiatingMessage
+	[SUCCESSFUL OUTCOME			&SuccessfulOutcome]
+	[UNSUCCESSFUL OUTCOME		&UnsuccessfulOutcome]
+	PROCEDURE CODE				&procedureCode
+	[CRITICALITY				&criticality]
+}
+
+-- **************************************************************
+--
+-- Interface PDU Definition
+--
+-- **************************************************************
+
+F1AP-PDU ::= CHOICE {
+	initiatingMessage	InitiatingMessage,
+	successfulOutcome	SuccessfulOutcome,
+	unsuccessfulOutcome	UnsuccessfulOutcome,
+	...
+}
+
+InitiatingMessage ::= SEQUENCE {
+	procedureCode	F1AP-ELEMENTARY-PROCEDURE.&procedureCode		({F1AP-ELEMENTARY-PROCEDURES}),
+	criticality		F1AP-ELEMENTARY-PROCEDURE.&criticality			({F1AP-ELEMENTARY-PROCEDURES}{@procedureCode}),
+	value			F1AP-ELEMENTARY-PROCEDURE.&InitiatingMessage	({F1AP-ELEMENTARY-PROCEDURES}{@procedureCode})
+}
+
+SuccessfulOutcome ::= SEQUENCE {
+	procedureCode	F1AP-ELEMENTARY-PROCEDURE.&procedureCode		({F1AP-ELEMENTARY-PROCEDURES}),
+	criticality		F1AP-ELEMENTARY-PROCEDURE.&criticality			({F1AP-ELEMENTARY-PROCEDURES}{@procedureCode}),
+	value			F1AP-ELEMENTARY-PROCEDURE.&SuccessfulOutcome	({F1AP-ELEMENTARY-PROCEDURES}{@procedureCode})
+}
+
+UnsuccessfulOutcome ::= SEQUENCE {
+	procedureCode	F1AP-ELEMENTARY-PROCEDURE.&procedureCode		({F1AP-ELEMENTARY-PROCEDURES}),
+	criticality		F1AP-ELEMENTARY-PROCEDURE.&criticality			({F1AP-ELEMENTARY-PROCEDURES}{@procedureCode}),
+	value			F1AP-ELEMENTARY-PROCEDURE.&UnsuccessfulOutcome	({F1AP-ELEMENTARY-PROCEDURES}{@procedureCode})
+}
+
+-- **************************************************************
+--
+-- Interface Elementary Procedure List
+--
+-- **************************************************************
+
+F1AP-ELEMENTARY-PROCEDURES F1AP-ELEMENTARY-PROCEDURE ::= {
+	F1AP-ELEMENTARY-PROCEDURES-CLASS-1			|
+	F1AP-ELEMENTARY-PROCEDURES-CLASS-2,	
+	...
+}
+
+
+F1AP-ELEMENTARY-PROCEDURES-CLASS-1 F1AP-ELEMENTARY-PROCEDURE ::= {
+	reset							|
+	f1Setup							|
+	gNBDUConfigurationUpdate		|
+	gNBCUConfigurationUpdate		|
+	uEContextSetup					|
+	uEContextRelease				|
+	uEContextModification			|
+	uEContextModificationRequired	,
+	...}
+
+ F1AP-ELEMENTARY-PROCEDURES-CLASS-2 F1AP-ELEMENTARY-PROCEDURE ::= {	
+	errorIndication					|
+	uEContextReleaseRequest			|
+	dLRRCMessageTransfer			|
+	uLRRCMessageTransfer			|
+	privateMessage					,
+	...
+}
+-- **************************************************************
+--
+-- Interface Elementary Procedures
+--
+-- **************************************************************
+
+reset F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		Reset
+	SUCCESSFUL OUTCOME		ResetAcknowledge
+	PROCEDURE CODE			id-Reset
+	CRITICALITY				reject
+}
+
+f1Setup F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		F1SetupRequest
+	SUCCESSFUL OUTCOME		F1SetupResponse
+	UNSUCCESSFUL 			OUTCOME	F1SetupFailure
+	PROCEDURE CODE			id-F1Setup
+	CRITICALITY				reject
+}
+
+gNBDUConfigurationUpdate F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		GNBDUConfigurationUpdate
+	SUCCESSFUL OUTCOME		GNBDUConfigurationUpdateAcknowledge
+	UNSUCCESSFUL OUTCOME		GNBDUConfigurationUpdateFailure
+	PROCEDURE CODE			id-gNBDUConfigurationUpdate
+	CRITICALITY				reject
+}
+
+gNBCUConfigurationUpdate F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		GNBCUConfigurationUpdate
+	SUCCESSFUL OUTCOME		GNBCUConfigurationUpdateAcknowledge
+	UNSUCCESSFUL OUTCOME		GNBCUConfigurationUpdateFailure
+	PROCEDURE CODE			id-gNBCUConfigurationUpdate
+	CRITICALITY				reject
+}
+
+uEContextSetup F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		UEContextSetupRequest
+	SUCCESSFUL OUTCOME		UEContextSetupResponse
+	UNSUCCESSFUL OUTCOME		UEContextSetupFailure
+	PROCEDURE CODE			id-UEContextSetup
+	CRITICALITY				reject
+}
+
+uEContextRelease F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		UEContextReleaseCommand
+	SUCCESSFUL OUTCOME		UEContextReleaseComplete
+	PROCEDURE CODE			id-UEContextRelease
+	CRITICALITY				reject
+}
+
+uEContextModification F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		UEContextModificationRequest
+	SUCCESSFUL OUTCOME		UEContextModificationResponse
+	UNSUCCESSFUL OUTCOME		UEContextModificationFailure
+	PROCEDURE CODE			id-UEContextModification
+	CRITICALITY				reject
+}
+
+uEContextModificationRequired F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		UEContextModificationRequired
+	SUCCESSFUL OUTCOME		UEContextModificationConfirm
+	PROCEDURE CODE			id-UEContextModificationRequired
+	CRITICALITY				reject
+}
+
+
+errorIndication F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		ErrorIndication
+	PROCEDURE CODE			id-ErrorIndication
+	CRITICALITY				ignore
+}
+
+uEContextReleaseRequest F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		UEContextReleaseRequest
+	PROCEDURE CODE			id-UEContextReleaseRequest
+	CRITICALITY				ignore
+}
+
+
+dLRRCMessageTransfer F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		DLRRCMessageTransfer
+	PROCEDURE CODE			id-DLRRCMessageTransfer
+	CRITICALITY				ignore
+}
+
+uLRRCMessageTransfer F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		ULRRCMessageTransfer
+	PROCEDURE CODE			id-ULRRCMessageTransfer
+	CRITICALITY				ignore
+}
+
+
+privateMessage F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		PrivateMessage
+	PROCEDURE CODE			id-privateMessage
+	CRITICALITY				ignore
+}
+
+
+
+END
diff --git a/openair2/F1AP/MESSAGES/ASN1/R15.1.1/asn1_constants.h b/openair2/F1AP/MESSAGES/ASN1/R15.1.1/asn1_constants.h
new file mode 100644
index 0000000000000000000000000000000000000000..5f7897148d7a783dc113250c345db9df0e23133a
--- /dev/null
+++ b/openair2/F1AP/MESSAGES/ASN1/R15.1.1/asn1_constants.h
@@ -0,0 +1,3 @@
+#ifndef __ASN1_CONSTANTS_H__
+#define __ASN1_CONSTANTS_H__
+#endif 
diff --git a/openair2/F1AP/MESSAGES/ASN1/R15.2.1/F1AP-CommonDataTypes.asn b/openair2/F1AP/MESSAGES/ASN1/R15.2.1/F1AP-CommonDataTypes.asn
new file mode 100644
index 0000000000000000000000000000000000000000..12dfbd12ff74eee6487a20abbc140b991e180e8a
--- /dev/null
+++ b/openair2/F1AP/MESSAGES/ASN1/R15.2.1/F1AP-CommonDataTypes.asn
@@ -0,0 +1,32 @@
+-- **************************************************************
+--
+-- Common definitions
+--
+-- **************************************************************
+
+F1AP-CommonDataTypes {
+itu-t (0) identified-organization (4) etsi (0) mobileDomain (0) 
+ngran-access (22) modules (3) f1ap (3) version1 (1) f1ap-CommonDataTypes (3) }
+
+DEFINITIONS AUTOMATIC TAGS ::= 
+
+BEGIN
+
+Criticality		::= ENUMERATED { reject, ignore, notify }
+
+Presence		::= ENUMERATED { optional, conditional, mandatory }
+
+PrivateIE-ID	::= CHOICE {
+	local				INTEGER (0..65535),
+	global				OBJECT IDENTIFIER
+}
+
+ProcedureCode		::= INTEGER (0..255)
+
+ProtocolExtensionID	::= INTEGER (0..65535)
+
+ProtocolIE-ID		::= INTEGER (0..65535)
+
+TriggeringMessage	::= ENUMERATED { initiating-message, successful-outcome, unsuccessfull-outcome }
+
+END
diff --git a/openair2/F1AP/MESSAGES/ASN1/R15.2.1/F1AP-Constants.asn b/openair2/F1AP/MESSAGES/ASN1/R15.2.1/F1AP-Constants.asn
new file mode 100644
index 0000000000000000000000000000000000000000..de34aa8f43778b1afccd92e428fd2fd29bb96ad5
--- /dev/null
+++ b/openair2/F1AP/MESSAGES/ASN1/R15.2.1/F1AP-Constants.asn
@@ -0,0 +1,256 @@
+-- **************************************************************
+--
+-- Constant definitions
+--
+-- **************************************************************
+
+F1AP-Constants { 
+itu-t (0) identified-organization (4) etsi (0) mobileDomain (0) 
+ngran-access (22) modules (3) f1ap (3) version1 (1) f1ap-Constants (4) } 
+
+DEFINITIONS AUTOMATIC TAGS ::= 
+
+BEGIN
+
+-- **************************************************************
+--
+-- IE parameter types from other modules.
+--
+-- **************************************************************
+
+IMPORTS
+	ProcedureCode,
+	ProtocolIE-ID
+
+FROM F1AP-CommonDataTypes;
+
+
+-- **************************************************************
+--
+-- Elementary Procedures
+--
+-- **************************************************************
+
+id-Reset									ProcedureCode ::= 0
+id-F1Setup									ProcedureCode ::= 1
+id-ErrorIndication							ProcedureCode ::= 2
+id-gNBDUConfigurationUpdate					ProcedureCode ::= 3
+id-gNBCUConfigurationUpdate					ProcedureCode ::= 4
+id-UEContextSetup							ProcedureCode ::= 5
+id-UEContextRelease							ProcedureCode ::= 6
+id-UEContextModification					ProcedureCode ::= 7
+id-UEContextModificationRequired			ProcedureCode ::= 8
+id-UEMobilityCommand						ProcedureCode ::= 9
+id-UEContextReleaseRequest					ProcedureCode ::= 10
+id-InitialULRRCMessageTransfer				ProcedureCode ::= 11
+id-DLRRCMessageTransfer						ProcedureCode ::= 12
+id-ULRRCMessageTransfer						ProcedureCode ::= 13
+id-privateMessage							ProcedureCode ::= 14
+id-UEInactivityNotification					ProcedureCode ::= 15
+id-GNBDUResourceCoordination				ProcedureCode ::= 16
+id-SystemInformationDeliveryCommand			ProcedureCode ::= 17
+id-Paging									ProcedureCode ::= 18
+id-Notify									ProcedureCode ::= 19
+id-WriteReplaceWarning						ProcedureCode ::= 20
+id-PWSCancel									ProcedureCode ::= 21
+id-PWSRestartIndication						ProcedureCode ::= 22
+id-PWSFailureIndication						ProcedureCode ::= 23
+
+-- **************************************************************
+--
+-- Extension constants
+--
+-- **************************************************************
+
+maxPrivateIEs							INTEGER ::= 65535
+maxProtocolExtensions					INTEGER ::= 65535
+maxProtocolIEs							INTEGER ::= 65535
+-- **************************************************************
+--
+-- Lists
+--
+-- **************************************************************
+
+maxNRARFCN								INTEGER ::= 3279165
+maxnoofErrors							INTEGER ::= 256
+maxnoofIndividualF1ConnectionsToReset	INTEGER ::= 65536
+maxCellingNBDU							INTEGER ::= 512
+maxnoofSCells							INTEGER ::= 32
+maxnoofSRBs								INTEGER ::= 8
+maxnoofDRBs								INTEGER ::= 64
+maxnoofULUPTNLInformation				INTEGER ::= 2
+maxnoofDLUPTNLInformation				INTEGER ::= 2
+maxnoofBPLMNs							INTEGER ::= 6
+maxnoofCandidateSpCells					INTEGER ::= 64
+maxnoofPotentialSpCells					INTEGER ::= 64
+maxnoofNrCellBands						INTEGER ::= 32
+maxnoofSIBTypes							INTEGER ::= 16
+maxnoofPagingCells						INTEGER ::= 512
+maxnoofTNLAssociations					INTEGER ::= 32
+maxnoofQoSFlows							INTEGER ::= 64
+maxnoofSliceItems						INTEGER ::= 1024
+maxCellineNB								INTEGER ::= 256
+
+
+-- **************************************************************
+--
+-- IEs
+--
+-- **************************************************************
+
+id-Cause											ProtocolIE-ID ::= 0
+id-Cells-Failed-to-be-Activated-List				ProtocolIE-ID ::= 1
+id-Cells-Failed-to-be-Activated-List-Item			ProtocolIE-ID ::= 2
+id-Cells-to-be-Activated-List						ProtocolIE-ID ::= 3
+id-Cells-to-be-Activated-List-Item					ProtocolIE-ID ::= 4
+id-Cells-to-be-Deactivated-List						ProtocolIE-ID ::= 5
+id-Cells-to-be-Deactivated-List-Item				ProtocolIE-ID ::= 6
+id-CriticalityDiagnostics							ProtocolIE-ID ::= 7
+id-CUtoDURRCInformation								ProtocolIE-ID ::= 9
+id-DRBs-FailedToBeModified-Item						ProtocolIE-ID ::= 12
+id-DRBs-FailedToBeModified-List						ProtocolIE-ID ::= 13
+id-DRBs-FailedToBeSetup-Item						ProtocolIE-ID ::= 14
+id-DRBs-FailedToBeSetup-List						ProtocolIE-ID ::= 15
+id-DRBs-FailedToBeSetupMod-Item						ProtocolIE-ID ::= 16
+id-DRBs-FailedToBeSetupMod-List						ProtocolIE-ID ::= 17
+id-DRBs-ModifiedConf-Item							ProtocolIE-ID ::= 18
+id-DRBs-ModifiedConf-List							ProtocolIE-ID ::= 19
+id-DRBs-Modified-Item								ProtocolIE-ID ::= 20
+id-DRBs-Modified-List								ProtocolIE-ID ::= 21
+id-DRBs-Required-ToBeModified-Item					ProtocolIE-ID ::= 22
+id-DRBs-Required-ToBeModified-List					ProtocolIE-ID ::= 23
+id-DRBs-Required-ToBeReleased-Item					ProtocolIE-ID ::= 24
+id-DRBs-Required-ToBeReleased-List					ProtocolIE-ID ::= 25
+id-DRBs-Setup-Item									ProtocolIE-ID ::= 26
+id-DRBs-Setup-List									ProtocolIE-ID ::= 27
+id-DRBs-SetupMod-Item								ProtocolIE-ID ::= 28
+id-DRBs-SetupMod-List								ProtocolIE-ID ::= 29
+id-DRBs-ToBeModified-Item							ProtocolIE-ID ::= 30
+id-DRBs-ToBeModified-List							ProtocolIE-ID ::= 31
+id-DRBs-ToBeReleased-Item							ProtocolIE-ID ::= 32
+id-DRBs-ToBeReleased-List							ProtocolIE-ID ::= 33
+id-DRBs-ToBeSetup-Item								ProtocolIE-ID ::= 34
+id-DRBs-ToBeSetup-List								ProtocolIE-ID ::= 35
+id-DRBs-ToBeSetupMod-Item							ProtocolIE-ID ::= 36
+id-DRBs-ToBeSetupMod-List							ProtocolIE-ID ::= 37
+id-DRXCycle											ProtocolIE-ID ::= 38
+id-DUtoCURRCInformation								ProtocolIE-ID ::= 39
+id-gNB-CU-UE-F1AP-ID								ProtocolIE-ID ::= 40
+id-gNB-DU-UE-F1AP-ID								ProtocolIE-ID ::= 41
+id-gNB-DU-ID										ProtocolIE-ID ::= 42
+id-GNB-DU-Served-Cells-Item							ProtocolIE-ID ::= 43
+id-gNB-DU-Served-Cells-List							ProtocolIE-ID ::= 44
+id-gNB-DU-Name										ProtocolIE-ID ::= 45
+id-NRCellID											ProtocolIE-ID ::= 46
+id-oldgNB-DU-UE-F1AP-ID								ProtocolIE-ID ::= 47
+id-ResetType										ProtocolIE-ID ::= 48
+id-ResourceCoordinationTransferContainer			ProtocolIE-ID ::= 49
+id-RRCContainer										ProtocolIE-ID ::= 50
+id-SCell-ToBeRemoved-Item							ProtocolIE-ID ::= 51
+id-SCell-ToBeRemoved-List							ProtocolIE-ID ::= 52
+id-SCell-ToBeSetup-Item								ProtocolIE-ID ::= 53
+id-SCell-ToBeSetup-List								ProtocolIE-ID ::= 54
+id-SCell-ToBeSetupMod-Item							ProtocolIE-ID ::= 55
+id-SCell-ToBeSetupMod-List							ProtocolIE-ID ::= 56
+id-Served-Cells-To-Add-Item							ProtocolIE-ID ::= 57
+id-Served-Cells-To-Add-List							ProtocolIE-ID ::= 58
+id-Served-Cells-To-Delete-Item						ProtocolIE-ID ::= 59
+id-Served-Cells-To-Delete-List						ProtocolIE-ID ::= 60
+id-Served-Cells-To-Modify-Item						ProtocolIE-ID ::= 61
+id-Served-Cells-To-Modify-List						ProtocolIE-ID ::= 62
+id-SpCell-ID										ProtocolIE-ID ::= 63
+id-SRBID											ProtocolIE-ID ::= 64
+id-SRBs-FailedToBeSetup-Item						ProtocolIE-ID ::= 65
+id-SRBs-FailedToBeSetup-List						ProtocolIE-ID ::= 66
+id-SRBs-FailedToBeSetupMod-Item						ProtocolIE-ID ::= 67
+id-SRBs-FailedToBeSetupMod-List						ProtocolIE-ID ::= 68
+id-SRBs-Required-ToBeReleased-Item					ProtocolIE-ID ::= 69
+id-SRBs-Required-ToBeReleased-List					ProtocolIE-ID ::= 70
+id-SRBs-ToBeReleased-Item							ProtocolIE-ID ::= 71
+id-SRBs-ToBeReleased-List							ProtocolIE-ID ::= 72
+id-SRBs-ToBeSetup-Item								ProtocolIE-ID ::= 73
+id-SRBs-ToBeSetup-List								ProtocolIE-ID ::= 74
+id-SRBs-ToBeSetupMod-Item							ProtocolIE-ID ::= 75
+id-SRBs-ToBeSetupMod-List							ProtocolIE-ID ::= 76
+id-TimeToWait										ProtocolIE-ID ::= 77
+id-TransactionID									ProtocolIE-ID ::= 78
+id-TransmissionStopIndicator						ProtocolIE-ID ::= 79
+id-UE-associatedLogicalF1-ConnectionItem 			ProtocolIE-ID ::= 80
+id-UE-associatedLogicalF1-ConnectionListResAck		ProtocolIE-ID ::= 81
+id-gNB-CU-Name										ProtocolIE-ID ::= 82
+id-SCell-FailedtoSetup-List							ProtocolIE-ID ::= 83
+id-SCell-FailedtoSetup-Item							ProtocolIE-ID ::= 84
+id-SCell-FailedtoSetupMod-List						ProtocolIE-ID ::= 85
+id-SCell-FailedtoSetupMod-Item						ProtocolIE-ID ::= 86
+id-RRCRconfigurationCompleteIndicator 				ProtocolIE-ID ::= 87
+id-Active-Cells-Item								ProtocolIE-ID ::= 88
+id-Active-Cells-List								ProtocolIE-ID ::= 89
+id-Candidate-SpCell-List							ProtocolIE-ID ::= 90
+id-Candidate-SpCell-Item							ProtocolIE-ID ::= 91
+id-Potential-SpCell-List							ProtocolIE-ID ::= 92
+id-Potential-SpCell-Item							ProtocolIE-ID ::= 93
+id-FullConfiguration								ProtocolIE-ID ::= 94
+id-C-RNTI										ProtocolIE-ID ::= 95
+id-SpCellULConfigured							ProtocolIE-ID ::= 96
+id-InactivityMonitoringRequest					ProtocolIE-ID ::= 97
+id-InactivityMonitoringResponse					ProtocolIE-ID ::= 98
+id-DRB-Activity-Item							ProtocolIE-ID ::= 99
+id-DRB-Activity-List							ProtocolIE-ID ::= 100
+id-EUTRA-NR-CellResourceCoordinationReq-Container 		ProtocolIE-ID ::= 101
+id-EUTRA-NR-CellResourceCoordinationReqAck-Container 	ProtocolIE-ID ::= 102
+id-SpectrumSharingGroupID								ProtocolIE-ID ::= 103
+id-ListofEUTRACellsinGNBDUCoordination					ProtocolIE-ID ::= 104
+id-Protected-EUTRA-Resources-List						ProtocolIE-ID ::= 105
+id-RequestType 											ProtocolIE-ID ::= 106
+id-ServCellndex									ProtocolIE-ID ::= 107 
+id-RAT-FrequencyPriorityInformation				ProtocolIE-ID ::= 108
+id-ExecuteDuplication							ProtocolIE-ID ::= 109
+id-NRCGI											ProtocolIE-ID ::= 111
+id-PagingCell-Item								ProtocolIE-ID ::= 112
+id-PagingCell-List								ProtocolIE-ID ::= 113
+id-PagingDRX										ProtocolIE-ID ::= 114
+id-PagingPriority 								ProtocolIE-ID ::= 115
+id-SIBtype-List									ProtocolIE-ID ::= 116
+id-UEIdentityIndexValue							ProtocolIE-ID ::= 117
+id-gNB-CUSystemInformation						ProtocolIE-ID ::= 118
+id-HandoverPreparationInformation				ProtocolIE-ID ::= 119
+id-GNB-CU-TNL-Association-To-Add-Item			ProtocolIE-ID ::= 120
+id-GNB-CU-TNL-Association-To-Add-List			ProtocolIE-ID ::= 121
+id-GNB-CU-TNL-Association-To-Remove-Item			ProtocolIE-ID ::= 122
+id-GNB-CU-TNL-Association-To-Remove-List			ProtocolIE-ID ::= 123
+id-GNB-CU-TNL-Association-To-Update-Item			ProtocolIE-ID ::= 124
+id-GNB-CU-TNL-Association-To-Update-List			ProtocolIE-ID ::= 125
+id-MaskedIMEISV									ProtocolIE-ID ::= 126
+id-PagingIdentity								ProtocolIE-ID ::= 127
+id-DUtoCURRCContainer							ProtocolIE-ID ::= 128
+id-Cells-to-be-Barred-List						ProtocolIE-ID ::= 129
+id-Cells-to-be-Barred-Item						ProtocolIE-ID ::= 130
+id-TAISliceSupportList							ProtocolIE-ID ::= 131
+id-GNB-CU-TNL-Association-Setup-List				ProtocolIE-ID ::= 132
+id-GNB-CU-TNL-Association-Setup-Item				ProtocolIE-ID ::= 133
+id-GNB-CU-TNL-Association-Failed-To-Setup-List	ProtocolIE-ID ::= 134
+id-GNB-CU-TNL-Association-Failed-To-Setup-Item	ProtocolIE-ID ::= 135
+id-DRB-Notify-Item								ProtocolIE-ID ::= 136
+id-DRB-Notify-List								ProtocolIE-ID ::= 137
+id-NotficationControl							ProtocolIE-ID ::= 138
+id-RANAC											ProtocolIE-ID ::= 139
+id-PWSSystemInformation							ProtocolIE-ID ::= 140
+id-RepetitionPeriod								ProtocolIE-ID ::= 141
+id-NumberofBroadcastRequest						ProtocolIE-ID ::= 142
+id-ConcurrentWarningMessageIndicator				ProtocolIE-ID ::= 143
+id-Cells-To-Be-Broadcast-List					ProtocolIE-ID ::= 144
+id-Cells-To-Be-Broadcast-Item					ProtocolIE-ID ::= 145
+id-Cells-Broadcast-Completed-List 				ProtocolIE-ID ::= 146
+id-Cells-Broadcast-Completed-Item 				ProtocolIE-ID ::= 147
+id-Broadcast-To-Be-Cancelled-List 				ProtocolIE-ID ::= 148
+id-Broadcast-To-Be-Cancelled-Item 				ProtocolIE-ID ::= 149
+id-Cells-Broadcast-Cancelled-List 				ProtocolIE-ID ::= 150
+id-Cells-Broadcast-Cancelled-Item 				ProtocolIE-ID ::= 151
+id-NR-CGI-List-For-Restart-List 					ProtocolIE-ID ::= 152
+id-NR-CGI-List-For-Restart-Item 					ProtocolIE-ID ::= 153
+id-PWS-Failed-NR-CGI-List 						ProtocolIE-ID ::= 154
+id-PWS-Failed-NR-CGI-Item 						ProtocolIE-ID ::= 155
+id-ConfirmedUEID								ProtocolIE-ID ::= 156
+id-Cancel-all-Warning-Messages-Indicator		ProtocolIE-ID ::= 157
+
+END
diff --git a/openair2/F1AP/MESSAGES/ASN1/R15.2.1/F1AP-Containers.asn b/openair2/F1AP/MESSAGES/ASN1/R15.2.1/F1AP-Containers.asn
new file mode 100644
index 0000000000000000000000000000000000000000..ed5dfba961e1bd315fc373d633babfdd1c4d4acb
--- /dev/null
+++ b/openair2/F1AP/MESSAGES/ASN1/R15.2.1/F1AP-Containers.asn
@@ -0,0 +1,184 @@
+-- **************************************************************
+--
+-- Container definitions
+--
+-- **************************************************************
+
+F1AP-Containers {
+itu-t (0) identified-organization (4) etsi (0) mobileDomain (0) 
+ngran-access (22) modules (3) f1ap (3) version1 (1) f1ap-Containers (5) }
+
+DEFINITIONS AUTOMATIC TAGS ::= 
+
+BEGIN
+
+-- **************************************************************
+--
+-- IE parameter types from other modules.
+--
+-- **************************************************************
+
+IMPORTS
+	Criticality,
+	Presence,
+	PrivateIE-ID,
+	ProtocolExtensionID,
+	ProtocolIE-ID
+
+FROM F1AP-CommonDataTypes
+	maxPrivateIEs,
+	maxProtocolExtensions,
+	maxProtocolIEs
+
+FROM F1AP-Constants;
+
+-- **************************************************************
+--
+-- Class Definition for Protocol IEs
+--
+-- **************************************************************
+
+F1AP-PROTOCOL-IES ::= CLASS {
+	&id				ProtocolIE-ID 					UNIQUE,
+	&criticality	Criticality,
+	&Value,
+	&presence		Presence
+}
+WITH SYNTAX {
+	ID				&id
+	CRITICALITY		&criticality
+	TYPE			&Value
+	PRESENCE		&presence
+}
+
+-- **************************************************************
+--
+-- Class Definition for Protocol IEs
+--
+-- **************************************************************
+
+F1AP-PROTOCOL-IES-PAIR ::= CLASS {
+	&id					ProtocolIE-ID 				UNIQUE,
+	&firstCriticality	Criticality,
+	&FirstValue,
+	&secondCriticality	Criticality,
+	&SecondValue,
+	&presence			Presence
+}
+WITH SYNTAX {
+	ID				&id
+	FIRST CRITICALITY		&firstCriticality
+	FIRST TYPE				&FirstValue
+	SECOND CRITICALITY		&secondCriticality
+	SECOND TYPE				&SecondValue
+	PRESENCE				&presence
+}
+
+-- **************************************************************
+--
+-- Class Definition for Protocol Extensions
+--
+-- **************************************************************
+
+F1AP-PROTOCOL-EXTENSION ::= CLASS {
+	&id				ProtocolExtensionID			UNIQUE,
+	&criticality	Criticality,
+	&Extension,
+	&presence		Presence
+}
+WITH SYNTAX {
+	ID				&id
+	CRITICALITY		&criticality
+	EXTENSION		&Extension
+	PRESENCE		&presence
+}
+
+-- **************************************************************
+--
+-- Class Definition for Private IEs
+--
+-- **************************************************************
+
+F1AP-PRIVATE-IES ::= CLASS {
+	&id				PrivateIE-ID,
+	&criticality	Criticality,
+	&Value,
+	&presence		Presence
+}
+WITH SYNTAX {
+	ID				&id
+	CRITICALITY		&criticality
+	TYPE			&Value
+	PRESENCE		&presence
+}
+
+-- **************************************************************
+--
+-- Container for Protocol IEs
+--
+-- **************************************************************
+
+ProtocolIE-Container {F1AP-PROTOCOL-IES : IEsSetParam} ::= 
+	SEQUENCE (SIZE (0..maxProtocolIEs)) OF
+	ProtocolIE-Field {{IEsSetParam}}
+
+ProtocolIE-SingleContainer {F1AP-PROTOCOL-IES : IEsSetParam} ::= 
+	ProtocolIE-Field {{IEsSetParam}}
+
+ProtocolIE-Field {F1AP-PROTOCOL-IES : IEsSetParam} ::= SEQUENCE {
+	id				F1AP-PROTOCOL-IES.&id				({IEsSetParam}),
+	criticality		F1AP-PROTOCOL-IES.&criticality		({IEsSetParam}{@id}),
+	value			F1AP-PROTOCOL-IES.&Value			({IEsSetParam}{@id})
+}
+
+-- **************************************************************
+--
+-- Container for Protocol IE Pairs
+--
+-- **************************************************************
+
+ProtocolIE-ContainerPair {F1AP-PROTOCOL-IES-PAIR : IEsSetParam} ::= 
+	SEQUENCE (SIZE (0..maxProtocolIEs)) OF
+	ProtocolIE-FieldPair {{IEsSetParam}}
+
+ProtocolIE-FieldPair {F1AP-PROTOCOL-IES-PAIR : IEsSetParam} ::= SEQUENCE {
+	id					F1AP-PROTOCOL-IES-PAIR.&id					({IEsSetParam}),
+	firstCriticality	F1AP-PROTOCOL-IES-PAIR.&firstCriticality	({IEsSetParam}{@id}),
+	firstValue			F1AP-PROTOCOL-IES-PAIR.&FirstValue			({IEsSetParam}{@id}),
+	secondCriticality	F1AP-PROTOCOL-IES-PAIR.&secondCriticality	({IEsSetParam}{@id}),
+	secondValue			F1AP-PROTOCOL-IES-PAIR.&SecondValue			({IEsSetParam}{@id})
+}
+
+-- **************************************************************
+--
+-- Container for Protocol Extensions
+--
+-- **************************************************************
+
+ProtocolExtensionContainer {F1AP-PROTOCOL-EXTENSION : ExtensionSetParam} ::= 
+	SEQUENCE (SIZE (1..maxProtocolExtensions)) OF
+	ProtocolExtensionField {{ExtensionSetParam}}
+
+ProtocolExtensionField {F1AP-PROTOCOL-EXTENSION : ExtensionSetParam} ::= SEQUENCE {
+	id					F1AP-PROTOCOL-EXTENSION.&id				({ExtensionSetParam}),
+	criticality			F1AP-PROTOCOL-EXTENSION.&criticality	({ExtensionSetParam}{@id}),
+	extensionValue		F1AP-PROTOCOL-EXTENSION.&Extension		({ExtensionSetParam}{@id})
+}
+
+-- **************************************************************
+--
+-- Container for Private IEs
+--
+-- **************************************************************
+
+PrivateIE-Container {F1AP-PRIVATE-IES : IEsSetParam } ::= 
+	SEQUENCE (SIZE (1.. maxPrivateIEs)) OF
+	PrivateIE-Field {{IEsSetParam}}
+
+PrivateIE-Field {F1AP-PRIVATE-IES : IEsSetParam} ::= SEQUENCE {
+	id					F1AP-PRIVATE-IES.&id				({IEsSetParam}),
+	criticality			F1AP-PRIVATE-IES.&criticality		({IEsSetParam}{@id}),
+	value				F1AP-PRIVATE-IES.&Value				({IEsSetParam}{@id})
+}
+
+END
diff --git a/openair2/F1AP/MESSAGES/ASN1/R15.2.1/F1AP-IEs.asn b/openair2/F1AP/MESSAGES/ASN1/R15.2.1/F1AP-IEs.asn
new file mode 100644
index 0000000000000000000000000000000000000000..aa92b8d3f8af026224a7e182b15187e41d8d50c2
--- /dev/null
+++ b/openair2/F1AP/MESSAGES/ASN1/R15.2.1/F1AP-IEs.asn
@@ -0,0 +1,1441 @@
+-- **************************************************************
+--
+-- Information Element Definitions
+--
+-- **************************************************************
+
+F1AP-IEs {
+itu-t (0) identified-organization (4) etsi (0) mobileDomain (0) 
+ngran-access (22) modules (3) f1ap (3) version1 (1) f1ap-IEs (2) }
+
+DEFINITIONS AUTOMATIC TAGS ::= 
+
+BEGIN
+
+IMPORTS
+	id-gNB-CUSystemInformation,
+	id-HandoverPreparationInformation,
+	id-TAISliceSupportList,
+	id-RANAC,
+	maxNRARFCN,
+	maxnoofErrors,
+	maxnoofBPLMNs,
+	maxnoofDLUPTNLInformation,
+	maxnoofNrCellBands,
+	maxnoofULUPTNLInformation,
+	maxnoofQoSFlows,
+	maxnoofSliceItems,
+	maxnoofSIBTypes,
+	maxCellineNB
+
+FROM F1AP-Constants
+
+	Criticality,
+	ProcedureCode,
+	ProtocolIE-ID,
+	TriggeringMessage
+
+FROM F1AP-CommonDataTypes
+
+	ProtocolExtensionContainer{},
+	F1AP-PROTOCOL-EXTENSION,
+	ProtocolIE-SingleContainer{},
+	F1AP-PROTOCOL-IES
+
+FROM F1AP-Containers;
+
+-- A
+
+Active-Cells-Item ::= SEQUENCE {
+	nRCGI		NRCGI	,
+	iE-Extensions				ProtocolExtensionContainer { { Active-Cells-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+Active-Cells-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+
+AllocationAndRetentionPriority ::= SEQUENCE {
+	priorityLevel				PriorityLevel,
+	pre-emptionCapability		Pre-emptionCapability,
+	pre-emptionVulnerability	Pre-emptionVulnerability,
+	iE-Extensions				ProtocolExtensionContainer { {AllocationAndRetentionPriority-ExtIEs} } OPTIONAL,
+	...
+}
+
+AllocationAndRetentionPriority-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+AveragingWindow  ::= INTEGER (0..63) -- this IE may need to be refined
+
+-- B
+
+BitRate ::= INTEGER (0..4000000000000,...)
+
+BroadcastPLMNs-List ::= SEQUENCE (SIZE(1..maxnoofBPLMNs)) OF BroadcastPLMNs-Item
+
+BroadcastPLMNs-Item ::= SEQUENCE {
+	pLMN-Identity				PLMN-Identity,
+	iE-Extensions				ProtocolExtensionContainer { { BroadcastPLMNs-ItemExtIEs} } OPTIONAL,
+	...
+}
+
+BroadcastPLMNs-ItemExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+{ ID id-TAISliceSupportList	CRITICALITY ignore	EXTENSION SliceSupportList		PRESENCE optional	},
+	...
+}
+
+
+-- C
+
+Cancel-all-Warning-Messages-Indicator ::= ENUMERATED {true, ...}
+
+Candidate-SpCell-Item ::= SEQUENCE {
+	candidate-SpCell-ID			NRCGI	,
+	iE-Extensions	ProtocolExtensionContainer { { Candidate-SpCell-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+Candidate-SpCell-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+Cause ::= CHOICE {
+	radioNetwork		CauseRadioNetwork,
+	transport			CauseTransport,
+	protocol			CauseProtocol,
+	misc				CauseMisc,
+	...
+}
+
+CauseMisc ::= ENUMERATED {
+	control-processing-overload,
+	not-enough-user-plane-processing-resources,
+	hardware-failure,
+	om-intervention,
+	unspecified,
+...
+}
+
+CauseProtocol ::= ENUMERATED {
+	transfer-syntax-error,
+	abstract-syntax-error-reject,
+	abstract-syntax-error-ignore-and-notify,
+	message-not-compatible-with-receiver-state,
+	semantic-error,
+	abstract-syntax-error-falsely-constructed-message,
+	unspecified,
+	...
+}
+
+CauseRadioNetwork ::= ENUMERATED {
+	unspecified,
+	rl-failure,
+	unknown-or-already-allocated-gnb-cu-ue-f1ap-id,
+	unknown-or-already-allocated-gnd-du-ue-f1ap-id,
+	unknown-or-inconsistent-pair-of-ue-f1ap-id,
+	interaction-with-other-procedure,
+	not-supported-qci-Value,
+	action-desirable-for-radio-reasons,
+	no-radio-resources-available,
+	procedure-cancelled,
+	normal-release,
+	...
+}
+
+CauseTransport ::= ENUMERATED {
+	unspecified,
+	transport-resource-unavailable,
+	...
+}
+
+
+
+CellGroupConfig ::= OCTET STRING
+
+Cells-Failed-to-be-Activated-List-Item ::= SEQUENCE {
+	nRCGI				NRCGI,
+	cause				Cause,
+	iE-Extensions		ProtocolExtensionContainer { { Cells-Failed-to-be-Activated-List-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+Cells-Failed-to-be-Activated-List-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+Cells-To-Be-Broadcast-Item ::= SEQUENCE {
+	nRCGI				NRCGI,
+	iE-Extensions		ProtocolExtensionContainer { { Cells-To-Be-Broadcast-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+Cells-To-Be-Broadcast-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+Cells-Broadcast-Completed-Item ::= SEQUENCE {
+	nRCGI				NRCGI,
+	iE-Extensions		ProtocolExtensionContainer { { Cells-Broadcast-Completed-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+Cells-Broadcast-Completed-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+Broadcast-To-Be-Cancelled-Item ::= SEQUENCE {
+	nRCGI				NRCGI,
+	iE-Extensions		ProtocolExtensionContainer { { Broadcast-To-Be-Cancelled-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+Broadcast-To-Be-Cancelled-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+
+Cells-Broadcast-Cancelled-Item ::= SEQUENCE {
+	nRCGI				NRCGI,
+	numberOfBroadcasts	NumberOfBroadcasts,
+	iE-Extensions		ProtocolExtensionContainer { { Cells-Broadcast-Cancelled-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+Cells-Broadcast-Cancelled-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+Cells-to-be-Activated-List-Item ::= SEQUENCE {
+	nRCGI		NRCGI,
+	nRPCI		NRPCI		OPTIONAL,
+	iE-Extensions				ProtocolExtensionContainer { { Cells-to-be-Activated-List-ItemExtIEs} }	OPTIONAL,
+	...
+}
+
+Cells-to-be-Activated-List-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+{ ID id-gNB-CUSystemInformation	CRITICALITY reject	EXTENSION GNB-CUSystemInformation		PRESENCE optional },
+	...
+}
+
+Cells-to-be-Deactivated-List-Item ::= SEQUENCE {
+	nRCGI			NRCGI	,
+	iE-Extensions				ProtocolExtensionContainer { { Cells-to-be-Deactivated-List-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+Cells-to-be-Deactivated-List-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+Cells-to-be-Barred-Item::= SEQUENCE {
+	nRCGI			NRCGI	,
+	cellBarred		CellBarred,
+	iE-Extensions				ProtocolExtensionContainer { { Cells-to-be-Barred-Item-ExtIEs } }	OPTIONAL
+}
+
+Cells-to-be-Barred-Item-ExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+CellBarred	::=	ENUMERATED {barred, not-barred, ...}
+
+CellULConfigured ::=  ENUMERATED {none, ul, sul, ul-and-sul, ...}
+
+CNUEPagingIdentity ::= CHOICE {
+	fiveG-S-TMSI			BIT STRING (SIZE(48)),
+	choice-extension			ProtocolExtensionContainer { { CNUEPagingIdentity-ExtIEs } },
+	...
+}
+
+CNUEPagingIdentity-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+
+ConcurrentWarningMessageIndicator ::= ENUMERATED {true, ...}
+
+CP-TransportLayerAddress ::= CHOICE {
+	endpoint-IP-address				TransportLayerAddress,
+	endpoint-IP-address-and-port	Endpoint-IP-address-and-port, 
+	choice-extension			ProtocolExtensionContainer { { CP-TransportLayerAddress-ExtIEs } },
+	...
+}
+
+CP-TransportLayerAddress-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+CriticalityDiagnostics ::= SEQUENCE {
+	procedureCode					ProcedureCode														OPTIONAL,
+	triggeringMessage				TriggeringMessage													OPTIONAL,
+	procedureCriticality			Criticality															OPTIONAL,
+	transactionID					TransactionID														OPTIONAL,
+	iEsCriticalityDiagnostics		CriticalityDiagnostics-IE-List										OPTIONAL,
+	iE-Extensions					ProtocolExtensionContainer {{CriticalityDiagnostics-ExtIEs}}		OPTIONAL,
+	...
+}
+
+CriticalityDiagnostics-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+CriticalityDiagnostics-IE-List ::= SEQUENCE (SIZE (1.. maxnoofErrors)) OF CriticalityDiagnostics-IE-Item
+
+CriticalityDiagnostics-IE-Item ::= SEQUENCE {
+	iECriticality			Criticality,
+	iE-ID					ProtocolIE-ID,
+	typeOfError 			TypeOfError,
+	iE-Extensions			ProtocolExtensionContainer {{CriticalityDiagnostics-IE-Item-ExtIEs}}	OPTIONAL,
+	...
+}
+
+CriticalityDiagnostics-IE-Item-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+C-RNTI ::= BIT STRING (SIZE (16))
+
+CUtoDURRCInformation ::= SEQUENCE {
+	cG-ConfigInfo						CG-ConfigInfo						OPTIONAL,
+	uE-CapabilityRAT-ContainerList		UE-CapabilityRAT-ContainerList		OPTIONAL,
+	measConfig							MeasConfig							OPTIONAL,
+	iE-Extensions				ProtocolExtensionContainer { { CUtoDURRCInformation-ExtIEs} } OPTIONAL,
+	...
+}
+
+CUtoDURRCInformation-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+{ ID id-HandoverPreparationInformation	CRITICALITY ignore	EXTENSION HandoverPreparationInformation		PRESENCE optional },
+	...
+}
+
+-- D
+
+DLUPTNLInformation-ToBeSetup-List ::= SEQUENCE (SIZE(1..maxnoofDLUPTNLInformation)) OF DLUPTNLInformation-ToBeSetup-Item
+
+DLUPTNLInformation-ToBeSetup-Item ::= SEQUENCE {
+	dLUPTNLInformation	UPTransportLayerInformation	,
+	iE-Extensions	ProtocolExtensionContainer { { DLUPTNLInformation-ToBeSetup-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+DLUPTNLInformation-ToBeSetup-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+DRB-Activity-Item ::= SEQUENCE {
+	dRBID			DRBID,
+	dRB-Activity	DRB-Activity		OPTIONAL,
+	iE-Extensions	ProtocolExtensionContainer { { DRB-Activity-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+DRB-Activity-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+DRB-Activity ::= ENUMERATED {active, not-active}
+
+DRBID ::= INTEGER (1..32, ...)
+
+DRBs-FailedToBeModified-Item	::= SEQUENCE {
+	dRBID		DRBID		,
+	cause		Cause		OPTIONAL,
+	iE-Extensions	ProtocolExtensionContainer { { DRBs-FailedToBeModified-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+DRBs-FailedToBeModified-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+DRBs-FailedToBeSetup-Item	::= SEQUENCE {
+	dRBID	DRBID,
+	cause	Cause	OPTIONAL,
+	iE-Extensions	ProtocolExtensionContainer { { DRBs-FailedToBeSetup-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+DRBs-FailedToBeSetup-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+
+DRBs-FailedToBeSetupMod-Item	::= SEQUENCE {
+	dRBID		DRBID	,
+	cause		Cause			OPTIONAL ,
+	iE-Extensions	ProtocolExtensionContainer { { DRBs-FailedToBeSetupMod-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+DRBs-FailedToBeSetupMod-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+DRB-Information	::=	SEQUENCE {
+	dRB-QoS		QoSFlowLevelQoSParameters, 
+	sNSSAI		SNSSAI, 
+	notificationControl		NotificationControl		OPTIONAL,
+	flows-Mapped-To-DRB-List	Flows-Mapped-To-DRB-List,
+	iE-Extensions	ProtocolExtensionContainer { { DRB-Information-ItemExtIEs } }	OPTIONAL
+}
+
+DRB-Information-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+DRBs-Modified-Item	::= SEQUENCE {
+	dRBID							DRBID,
+	lCID								LCID		OPTIONAL,
+	dLUPTNLInformation-ToBeSetup-List		DLUPTNLInformation-ToBeSetup-List,
+	iE-Extensions	ProtocolExtensionContainer { { DRBs-Modified-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+DRBs-Modified-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+DRBs-ModifiedConf-Item	::= SEQUENCE {
+	dRBID							DRBID,
+	uLUPTNLInformation-ToBeSetup-List		ULUPTNLInformation-ToBeSetup-List	,
+	iE-Extensions	ProtocolExtensionContainer { { DRBs-ModifiedConf-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+DRBs-ModifiedConf-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+DRB-Notify-Item ::= SEQUENCE {
+	dRBID			DRBID,
+	notification-Cause	Notification-Cause,
+	iE-Extensions	ProtocolExtensionContainer { { DRB-Notify-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+DRB-Notify-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+DRBs-Required-ToBeModified-Item	::= SEQUENCE {
+	dRBID							DRBID,
+	dLUPTNLInformation-ToBeSetup-List		DLUPTNLInformation-ToBeSetup-List	,
+	iE-Extensions	ProtocolExtensionContainer { { DRBs-Required-ToBeModified-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+DRBs-Required-ToBeModified-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+DRBs-Required-ToBeReleased-Item	::= SEQUENCE {
+	dRBID		DRBID,
+	iE-Extensions	ProtocolExtensionContainer { { DRBs-Required-ToBeReleased-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+DRBs-Required-ToBeReleased-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+DRBs-Setup-Item ::= SEQUENCE {
+	dRBID							DRBID,
+	lCID								LCID		OPTIONAL,
+	dLUPTNLInformation-ToBeSetup-List		DLUPTNLInformation-ToBeSetup-List	, 
+	iE-Extensions	ProtocolExtensionContainer { { DRBs-Setup-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+DRBs-Setup-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+DRBs-SetupMod-Item	::= SEQUENCE {
+	dRBID							DRBID,
+	lCID								LCID		OPTIONAL,
+	dLUPTNLInformation-ToBeSetup-List		DLUPTNLInformation-ToBeSetup-List	,
+	iE-Extensions	ProtocolExtensionContainer { { DRBs-SetupMod-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+DRBs-SetupMod-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+
+DRBs-ToBeModified-Item	::= SEQUENCE {
+	dRBID						DRBID,
+	qoSInformation				QoSInformation,
+	uLUPTNLInformation-ToBeSetup-List	ULUPTNLInformation-ToBeSetup-List	, 
+	uLConfiguration				ULConfiguration	OPTIONAL,
+	iE-Extensions	ProtocolExtensionContainer { { DRBs-ToBeModified-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+DRBs-ToBeModified-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+DRBs-ToBeReleased-Item	::= SEQUENCE {
+	dRBID	DRBID,
+	iE-Extensions	ProtocolExtensionContainer { { DRBs-ToBeReleased-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+DRBs-ToBeReleased-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+DRBs-ToBeSetup-Item ::= SEQUENCE	{
+	dRBID						DRBID,
+	qoSInformation				QoSInformation,
+	uLUPTNLInformation-ToBeSetup-List	ULUPTNLInformation-ToBeSetup-List	, 
+	rLCMode						RLCMode, 
+	uLConfiguration				ULConfiguration	OPTIONAL,
+	duplicationActivation		DuplicationActivation	OPTIONAL,
+	iE-Extensions	ProtocolExtensionContainer { { DRBs-ToBeSetup-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+DRBs-ToBeSetup-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+
+DRBs-ToBeSetupMod-Item	::= SEQUENCE {
+	dRBID						DRBID,
+	qoSInformation				QoSInformation,
+	uLUPTNLInformation-ToBeSetup-List		ULUPTNLInformation-ToBeSetup-List,
+	rLCMode						RLCMode, 
+	uLConfiguration				ULConfiguration	OPTIONAL,
+	duplicationActivation		DuplicationActivation	OPTIONAL,
+	iE-Extensions	ProtocolExtensionContainer { { DRBs-ToBeSetupMod-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+DRBs-ToBeSetupMod-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+DRXCycle	::= SEQUENCE {
+	longDRXCycleLength	LongDRXCycleLength,
+	shortDRXCycleLength		ShortDRXCycleLength	OPTIONAL,
+	shortDRXCycleTimer	ShortDRXCycleTimer OPTIONAL,
+	iE-Extensions		ProtocolExtensionContainer { { DRXCycle-ExtIEs} } OPTIONAL,
+	...
+}
+
+DRXCycle-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+DUtoCURRCContainer ::= OCTET STRING
+
+DUtoCURRCInformation ::= SEQUENCE {
+	cellGroupConfig		CellGroupConfig,
+	measGapConfig			MeasGapConfig	OPTIONAL,
+	requestedP-MaxFR1				OCTET STRING				OPTIONAL,
+	iE-Extensions				ProtocolExtensionContainer { { DUtoCURRCInformation-ExtIEs} } OPTIONAL,
+	...
+}
+
+DUtoCURRCInformation-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+DuplicationActivation ::= ENUMERATED{active,inactive,... }
+
+DuplicationIndication ::= ENUMERATED {true, ...}
+
+Dynamic5QIDescriptor	::= SEQUENCE {
+	qoSPriorityLevel					INTEGER (1..127),
+	packetDelayBudget					PacketDelayBudget,
+	packetErrorRate						PacketErrorRate,
+	delayCritical						ENUMERATED {delay-critical, non-delay-critical}		OPTIONAL,
+	averagingWindow 					AveragingWindow										OPTIONAL,
+	maxDataBurstVolume					MaxDataBurstVolume									OPTIONAL,
+	iE-Extensions					ProtocolExtensionContainer { { Dynamic5QIDescriptor-ExtIEs } } OPTIONAL
+}
+
+Dynamic5QIDescriptor-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+-- E
+
+Endpoint-IP-address-and-port ::=SEQUENCE {
+	endpointIPAddress TransportLayerAddress,
+	iE-Extensions					ProtocolExtensionContainer { { Endpoint-IP-address-and-port-ExtIEs} } OPTIONAL
+}
+
+Endpoint-IP-address-and-port-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+EUTRANQoS	::= SEQUENCE {
+	qCI								QCI,
+	allocationAndRetentionPriority	AllocationAndRetentionPriority,
+	gbrQosInformation				GBR-QosInformation									OPTIONAL,
+	iE-Extensions					ProtocolExtensionContainer { { EUTRANQoS-ExtIEs} }	OPTIONAL,
+	...
+}
+
+EUTRANQoS-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+ExecuteDuplication ::= ENUMERATED{true,...}
+
+EUTRA-Mode-Info ::= CHOICE {
+	eUTRAFDD		EUTRA-FDD-Info,
+	eUTRATDD		EUTRA-TDD-Info,
+	...
+}
+
+EUTRA-NR-CellResourceCoordinationReq-Container	::= OCTET STRING
+
+EUTRA-NR-CellResourceCoordinationReqAck-Container	::= OCTET STRING
+
+EUTRA-FDD-Info ::= SEQUENCE {
+	uL-offsetToPointA				OffsetToPointA,
+	dL-offsetToPointA				OffsetToPointA,
+	iE-Extensions					ProtocolExtensionContainer { {EUTRA-FDD-Info-ExtIEs} } OPTIONAL,
+	...
+}
+
+EUTRA-FDD-Info-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+EUTRA-TDD-Info ::= SEQUENCE {
+	offsetToPointA					OffsetToPointA,
+	iE-Extensions					ProtocolExtensionContainer { {EUTRA-TDD-Info-ExtIEs} } OPTIONAL,
+	...
+}
+
+EUTRA-TDD-Info-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+-- F
+
+FDD-Info ::= SEQUENCE {
+	uL-NRFreqInfo						NRFreqInfo,
+	dL-NRFreqInfo						NRFreqInfo,
+	uL-Transmission-Bandwidth		Transmission-Bandwidth,
+	dL-Transmission-Bandwidth		Transmission-Bandwidth,
+	iE-Extensions					ProtocolExtensionContainer { {FDD-Info-ExtIEs} } OPTIONAL,
+	...
+}
+
+FDD-Info-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+
+Flows-Mapped-To-DRB-List	::=	SEQUENCE (SIZE(1.. maxnoofQoSFlows)) OF Flows-Mapped-To-DRB-Item
+
+Flows-Mapped-To-DRB-Item 	::= SEQUENCE {
+	qoSFlowIndicator							QoSFlowIndicator,
+	qoSFlowLevelQoSParameters				QoSFlowLevelQoSParameters,
+	iE-Extensions				ProtocolExtensionContainer { { Flows-Mapped-To-DRB-ItemExtIEs} } OPTIONAL
+}
+
+Flows-Mapped-To-DRB-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+FreqBandNrItem ::= SEQUENCE {
+	freqBandIndicatorNr 			INTEGER (1..1024,...), 
+	supportedSULBandList		SEQUENCE (SIZE(0..maxnoofNrCellBands)) OF SupportedSULFreqBandItem,
+	iE-Extensions				ProtocolExtensionContainer { {FreqBandNrItem-ExtIEs} } OPTIONAL,
+	...
+}
+
+FreqBandNrItem-ExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+FullConfiguration ::= ENUMERATED {full, ...}
+
+-- G
+
+
+GBR-QosInformation ::= SEQUENCE {
+	e-RAB-MaximumBitrateDL			BitRate,
+	e-RAB-MaximumBitrateUL			BitRate,
+	e-RAB-GuaranteedBitrateDL		BitRate,
+	e-RAB-GuaranteedBitrateUL		BitRate,
+	iE-Extensions					ProtocolExtensionContainer { { GBR-QosInformation-ExtIEs} } OPTIONAL,
+	...
+}
+
+GBR-QosInformation-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+GBR-QoSFlowInformation::= SEQUENCE {
+	maxFlowBitRateDownlink			BitRate,
+	maxFlowBitRateUplink			BitRate, 
+	guaranteedFlowBitRateDownlink	BitRate,
+	guaranteedFlowBitRateUplink		BitRate, 
+	maxPacketLossRateDownlink		MaxPacketLossRate		OPTIONAL,
+	maxPacketLossRateUplink			MaxPacketLossRate		OPTIONAL,
+	iE-Extensions					ProtocolExtensionContainer { { GBR-QosFlowInformation-ExtIEs} } OPTIONAL,
+	...
+}
+
+GBR-QosFlowInformation-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+
+GNB-CUSystemInformation::= SEQUENCE {
+	sImessage		OCTET STRING,
+	iE-Extensions					ProtocolExtensionContainer { { GNB-CUSystemInformation-ExtIEs} } OPTIONAL,
+	...
+}
+
+GNB-CUSystemInformation-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+GNB-CU-TNL-Association-Setup-Item::= SEQUENCE {
+	tNLAssociationTransportLayerAddress		CP-TransportLayerAddress	,
+	iE-Extensions					ProtocolExtensionContainer { { GNB-CU-TNL-Association-Setup-Item-ExtIEs} } OPTIONAL
+}
+
+GNB-CU-TNL-Association-Setup-Item-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+GNB-CU-TNL-Association-Failed-To-Setup-Item ::= SEQUENCE {
+	tNLAssociationTransportLayerAddress		CP-TransportLayerAddress	,
+	cause									Cause,
+	iE-Extensions					ProtocolExtensionContainer { { GNB-CU-TNL-Association-Failed-To-Setup-Item-ExtIEs} } OPTIONAL
+}
+
+GNB-CU-TNL-Association-Failed-To-Setup-Item-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+
+GNB-CU-TNL-Association-To-Add-Item ::= SEQUENCE {
+	tNLAssociationTransportLayerAddress		CP-TransportLayerAddress	,
+	tNLAssociationUsage							TNLAssociationUsage,
+	iE-Extensions					ProtocolExtensionContainer { { GNB-CU-TNL-Association-To-Add-Item-ExtIEs} } OPTIONAL
+}
+
+GNB-CU-TNL-Association-To-Add-Item-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+GNB-CU-TNL-Association-To-Remove-Item::= SEQUENCE {
+	tNLAssociationTransportLayerAddress		CP-TransportLayerAddress	,
+	iE-Extensions					ProtocolExtensionContainer { { GNB-CU-TNL-Association-To-Remove-Item-ExtIEs} } OPTIONAL
+}
+
+GNB-CU-TNL-Association-To-Remove-Item-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+
+GNB-CU-TNL-Association-To-Update-Item::= SEQUENCE {
+	tNLAssociationTransportLayerAddress		CP-TransportLayerAddress	,
+	tNLAssociationUsage							TNLAssociationUsage OPTIONAL,
+	iE-Extensions					ProtocolExtensionContainer { { GNB-CU-TNL-Association-To-Update-Item-ExtIEs} } OPTIONAL
+}
+
+GNB-CU-TNL-Association-To-Update-Item-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+GNB-CU-UE-F1AP-ID		::= INTEGER (0..4294967295)
+
+GNB-DU-UE-F1AP-ID		::= INTEGER (0..4294967295)
+
+GNB-DU-ID			::= INTEGER (0..68719476735)
+
+GNB-CU-Name ::= PrintableString(SIZE(1..150,...))
+
+GNB-DU-Name ::= PrintableString(SIZE(1..150,...))
+
+GNB-DU-Served-Cells-Item ::= SEQUENCE {
+	served-Cell-Information		Served-Cell-Information,
+	gNB-DU-System-Information	GNB-DU-System-Information	OPTIONAL,
+	iE-Extensions				ProtocolExtensionContainer { { GNB-DU-Served-Cells-ItemExtIEs} }	OPTIONAL,
+	...
+}
+
+GNB-DU-Served-Cells-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+GNB-DU-System-Information ::= SEQUENCE {
+	mIB-message		MIB-message,
+	sIB1-message		SIB1-message,
+	iE-Extensions					ProtocolExtensionContainer { { GNB-DU-System-Information-ExtIEs } } OPTIONAL,
+	...
+}
+
+GNB-DU-System-Information-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+GTP-TEID				::= OCTET STRING (SIZE (4))
+
+GTPTunnel				::= SEQUENCE {
+	transportLayerAddress		TransportLayerAddress,
+	gTP-TEID		GTP-TEID,
+	iE-Extensions					ProtocolExtensionContainer { { GTPTunnel-ExtIEs } } OPTIONAL,
+	...
+}
+
+GTPTunnel-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+-- H
+
+HandoverPreparationInformation ::= OCTET STRING
+
+-- I
+InactivityMonitoringRequest ::= ENUMERATED { true,...}
+InactivityMonitoringResponse ::= ENUMERATED { not-supported,...}
+
+-- J
+
+-- K
+
+-- L
+
+LCID ::= INTEGER (1..32, ...)
+
+ListofEUTRACellsinGNBDUCoordination  ::= SEQUENCE (SIZE (0.. maxCellineNB)) OF Served-EUTRA-Cells-Information
+
+LongDRXCycleLength ::= 	ENUMERATED
+{ms10, ms20, ms32, ms40, ms60, ms64, ms70, ms80, ms128, ms160, ms256, ms320, ms512, ms640, ms1024, ms1280, ms2048, ms2560, ms5120, ms10240, ...}
+
+-- M
+
+MaskedIMEISV ::= 	BIT STRING (SIZE (64))
+
+MaxDataBurstVolume  ::= INTEGER (0..63) -- this IE may need to be refined
+MaxPacketLossRate ::= INTEGER (0..1000)
+
+MIB-message ::= OCTET STRING
+
+MeasConfig ::= OCTET STRING
+
+MeasGapConfig ::= OCTET STRING
+
+-- N
+
+NGRANAllocationAndRetentionPriority ::= SEQUENCE {
+	priorityLevel				PriorityLevel,
+	pre-emptionCapability		Pre-emptionCapability,
+	pre-emptionVulnerability	Pre-emptionVulnerability,
+	iE-Extensions				ProtocolExtensionContainer { {NGRANAllocationAndRetentionPriority-ExtIEs} } OPTIONAL
+}
+
+NGRANAllocationAndRetentionPriority-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+NR-CGI-List-For-Restart-Item ::= SEQUENCE {
+	nRCGI				NRCGI,
+	iE-Extensions		ProtocolExtensionContainer { { NR-CGI-List-For-Restart-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+NR-CGI-List-For-Restart-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+NonDynamic5QIDescriptor	::= SEQUENCE {
+	fiveQI						INTEGER (0..255),
+	qoSPriorityLevel			INTEGER (1..127)				OPTIONAL,
+	averagingWindow 			AveragingWindow					OPTIONAL,
+	maxDataBurstVolume			MaxDataBurstVolume				OPTIONAL,
+	iE-Extensions	ProtocolExtensionContainer { { NonDynamic5QIDescriptor-ExtIEs } } OPTIONAL
+}
+
+NonDynamic5QIDescriptor-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+Notification-Cause ::= ENUMERATED {fulfilled, not-fulfilled, ...}
+
+NotificationControl ::= ENUMERATED {active, not-active, ...}
+
+NRFreqInfo ::=  SEQUENCE {
+	nRARFCN			INTEGER (0..maxNRARFCN),
+	sul-Information	SUL-Information		OPTIONAL,
+	freqBandListNr	SEQUENCE (SIZE(1..maxnoofNrCellBands)) OF FreqBandNrItem,
+	iE-Extensions	ProtocolExtensionContainer { { NRFreqInfoExtIEs} } OPTIONAL,
+	...
+}
+
+NRFreqInfoExtIEs		F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+NRCGI ::= SEQUENCE {
+	pLMN-Identity			PLMN-Identity,
+	nRCellIdentity			NRCellIdentity,
+	iE-Extensions			ProtocolExtensionContainer { {NRCGI-ExtIEs} } OPTIONAL,
+	...
+}
+
+NRCGI-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+NR-Mode-Info ::= CHOICE {
+	fDD		FDD-Info,
+	tDD		TDD-Info,
+	choice-extension			ProtocolExtensionContainer { { NR-Mode-Info-ExtIEs} },
+	...
+}
+
+NR-Mode-Info-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {	...
+}
+
+
+NRCellIdentity ::= BIT STRING (SIZE(36))
+
+NRNRB ::= ENUMERATED { nrb11, nrb18, nrb24, nrb25, nrb31, nrb32, nrb38, nrb51, nrb52, nrb65, nrb66, nrb78, nrb79, nrb93, nrb106, nrb107, nrb121, nrb132, nrb133, nrb135, nrb160, nrb162, nrb189, nrb216, nrb217, nrb245, nrb264, nrb270, nrb273, ...}
+
+NRPCI ::= INTEGER(0..1007)
+
+NRSCS ::= ENUMERATED { scs15, scs30, scs60, scs120, ...}
+
+NumberOfBroadcasts ::= INTEGER (0..65535)
+
+NumberofBroadcastRequest ::= INTEGER (0..65535)
+
+-- O
+
+OffsetToPointA	::= INTEGER (0..2199,...)
+
+-- P
+
+PacketDelayBudget ::= INTEGER (0..63) -- this IE may need to be refined
+
+PacketErrorRate ::= INTEGER (0..63) -- this IE may need to be refined
+
+PagingCell-Item ::= SEQUENCE {
+	nRCGI		NRCGI	,
+	iE-Extensions	ProtocolExtensionContainer { { PagingCell-ItemExtIEs } }	OPTIONAL
+}
+
+PagingCell-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+PagingDRX ::= INTEGER (0..63) -- this IE may need to be refined
+
+PagingIdentity ::=	CHOICE {
+	rANUEPagingIdentity	RANUEPagingIdentity,
+	cNUEPagingIdentity	CNUEPagingIdentity, 
+	choice-extension			ProtocolExtensionContainer { { PagingIdentity-ExtIEs } },
+	...
+}
+
+PagingIdentity-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+PagingPriority ::= ENUMERATED { priolevel1, priolevel2, priolevel3, priolevel4, priolevel5, priolevel6, priolevel7, priolevel8,...}
+
+PLMN-Identity ::= OCTET STRING (SIZE(3))
+
+Pre-emptionCapability ::= ENUMERATED {
+	shall-not-trigger-pre-emption,
+	may-trigger-pre-emption
+}
+
+Pre-emptionVulnerability ::= ENUMERATED {
+	not-pre-emptable,
+	pre-emptable
+}
+
+PriorityLevel	::= INTEGER { spare (0), highest (1), lowest (14), no-priority (15) } (0..15)
+
+ProtectedEUTRAResourceIndication		::= OCTET STRING
+
+Potential-SpCell-Item ::= SEQUENCE {
+	potential-SpCell-ID			NRCGI	,
+	iE-Extensions	ProtocolExtensionContainer { { Potential-SpCell-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+Potential-SpCell-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+PWS-Failed-NR-CGI-Item ::= SEQUENCE {
+	nRCGI				NRCGI,
+	numberOfBroadcasts	NumberOfBroadcasts,
+	iE-Extensions		ProtocolExtensionContainer { { PWS-Failed-NR-CGI-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+PWS-Failed-NR-CGI-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+PWSSystemInformation ::= OCTET STRING
+
+-- Q
+
+QCI ::= INTEGER (0..255)
+
+QoS-Characteristics ::= CHOICE {
+	non-Dynamic-5QI				NonDynamic5QIDescriptor,
+	dynamic-5QI					Dynamic5QIDescriptor, 
+	choice-extension			ProtocolExtensionContainer { { QoS-Characteristics-ExtIEs } },
+	...
+}
+
+QoS-Characteristics-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+QoSFlowIndicator ::= INTEGER (0..63) 
+
+QoSFlowLevelQoSParameters	::= SEQUENCE {
+	qoS-Characteristics					QoS-Characteristics,
+	nGRANallocationRetentionPriority		NGRANAllocationAndRetentionPriority,
+	gBR-QoS-Flow-Information				GBR-QoSFlowInformation				OPTIONAL,
+	reflective-QoS-Attribute				ENUMERATED {subject-to, ...}				OPTIONAL,
+	iE-Extensions				ProtocolExtensionContainer { { QoSFlowLevelQoSParameters-ExtIEs } }	OPTIONAL
+}
+
+QoSFlowLevelQoSParameters-ExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+QoSInformation	::=	CHOICE {
+	eUTRANQoS					EUTRANQoS,
+        dRB-Information                         DRB-Information,
+	choice-extension			ProtocolExtensionContainer { { QoSInformation-ExtIEs} },
+	...
+}
+
+QoSInformation-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+-- R
+
+RANAC ::= INTEGER (0..64)
+
+RANUEPagingIdentity ::= SEQUENCE	{
+	iRNTI						BIT STRING (SIZE(40)),
+	iE-Extensions				ProtocolExtensionContainer { { RANUEPagingIdentity-ExtIEs } }	OPTIONAL}
+
+RANUEPagingIdentity-ExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+RAT-FrequencyPriorityInformation::= CHOICE {
+	subscriberProfileIDforRFP		SubscriberProfileIDforRFP,
+	rAT-FrequencySelectionPriority		RAT-FrequencySelectionPriority,
+	choice-extension			ProtocolExtensionContainer { { RAT-FrequencyPriorityInformation-ExtIEs} },
+	...
+}
+
+RAT-FrequencyPriorityInformation-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+RAT-FrequencySelectionPriority::= INTEGER (1.. 256, ...)
+
+RequestType	::= ENUMERATED {offer, execution, ...}
+
+ResourceCoordinationTransferContainer ::= OCTET STRING
+
+RepetitionPeriod ::= INTEGER (0..131071, ...)
+RLCMode ::= ENUMERATED {
+	rlc-am,
+	rlc-um
+}
+
+RRCContainer ::= OCTET STRING
+
+RRCRconfigurationCompleteIndicator	::= ENUMERATED {true, ...}
+
+-- S
+
+SCell-FailedtoSetup-Item	::= SEQUENCE {
+	sCell-ID			NRCGI	, 
+	cause		Cause			OPTIONAL ,
+	iE-Extensions	ProtocolExtensionContainer { { SCell-FailedtoSetup-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+SCell-FailedtoSetup-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+SCell-FailedtoSetupMod-Item	::= SEQUENCE {
+	sCell-ID			NRCGI	, 
+    cause		Cause			OPTIONAL ,
+	iE-Extensions	ProtocolExtensionContainer { { SCell-FailedtoSetupMod-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+SCell-FailedtoSetupMod-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+SCell-ToBeRemoved-Item	::= SEQUENCE {
+	sCell-ID			NRCGI	, 
+	iE-Extensions	ProtocolExtensionContainer { { SCell-ToBeRemoved-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+SCell-ToBeRemoved-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+SCell-ToBeSetup-Item ::= SEQUENCE {
+	sCell-ID			NRCGI	,
+	sCellIndex			SCellIndex, 
+	sCellULConfigured		CellULConfigured 	OPTIONAL,
+	iE-Extensions	ProtocolExtensionContainer { { SCell-ToBeSetup-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+SCell-ToBeSetup-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+SCell-ToBeSetupMod-Item	::= SEQUENCE {
+	sCell-ID			NRCGI	, 
+	sCellIndex			SCellIndex,
+	sCellULConfigured		CellULConfigured 	OPTIONAL,
+	iE-Extensions	ProtocolExtensionContainer { { SCell-ToBeSetupMod-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+SCell-ToBeSetupMod-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+SCellIndex ::=INTEGER (1..31, ...)
+
+CG-ConfigInfo ::= OCTET STRING
+
+ServCellIndex ::= INTEGER (0..31, ...)
+
+Served-Cell-Information ::= SEQUENCE {
+	nRCGI							NRCGI,
+	nRPCI							NRPCI,
+	fiveGS-TAC							FiveGS-TAC,
+	configured-EPS-TAC				Configured-EPS-TAC 		OPTIONAL,
+	servedPLMNs					BroadcastPLMNs-List,
+	nR-Mode-Info					NR-Mode-Info, 
+	measurementTimingConfiguration	OCTET STRING,
+	iE-Extensions		ProtocolExtensionContainer { {Served-Cell-Information-ExtIEs} } OPTIONAL,
+	...
+}
+
+Served-Cell-Information-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+{	ID id-RANAC		CRITICALITY ignore EXTENSION RANAC		PRESENCE optional},
+	...
+}
+
+Served-Cells-To-Add-Item ::= SEQUENCE {
+	served-Cell-Information		Served-Cell-Information,
+	gNB-DU-System-Information	GNB-DU-System-Information	 OPTIONAL, 
+	iE-Extensions				ProtocolExtensionContainer { { Served-Cells-To-Add-ItemExtIEs} }	OPTIONAL,
+	...
+}
+
+Served-Cells-To-Add-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+Served-Cells-To-Delete-Item ::= SEQUENCE {
+	oldNRCGI					NRCGI	,
+	iE-Extensions				ProtocolExtensionContainer { { Served-Cells-To-Delete-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+Served-Cells-To-Delete-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+Served-Cells-To-Modify-Item ::= SEQUENCE {
+	oldNRCGI					NRCGI							,
+	served-Cell-Information		Served-Cell-Information		,
+	gNB-DU-System-Information	GNB-DU-System-Information 	OPTIONAL	,
+	iE-Extensions				ProtocolExtensionContainer { { Served-Cells-To-Modify-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+Served-Cells-To-Modify-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+Served-EUTRA-Cells-Information::= SEQUENCE {
+	eUTRA-Mode-Info						EUTRA-Mode-Info,
+	protectedEUTRAResourceIndication		ProtectedEUTRAResourceIndication,
+	iE-Extensions						ProtocolExtensionContainer { {Served-EUTRA-Cell-Information-ExtIEs} } OPTIONAL,
+	...
+}
+
+Served-EUTRA-Cell-Information-ExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+ShortDRXCycleLength ::=  ENUMERATED {ms2, ms3, ms4, ms5, ms6, ms7, ms8, ms10, ms14, ms16, ms20, ms30, ms32, ms35, ms40, ms64, ms80, ms128, ms160, ms256, ms320, ms512, ms640, ...}
+
+ShortDRXCycleTimer ::= INTEGER (1..16)
+
+SIB1-message ::= OCTET STRING
+
+SIBtype ::= ENUMERATED {
+	sibtype2,sibtype3, sibtype4, sibtype5, sibtype6, sibtype7, sibtype8, sibtype9,
+	...
+}
+
+SIBtype-List ::= SEQUENCE (SIZE(1.. maxnoofSIBTypes)) OF SIBtype-Item
+
+SIBtype-Item ::= SEQUENCE {
+	sIBtype		SIBtype	,
+	iE-Extensions	ProtocolExtensionContainer { { SIBtype-ItemExtIEs } }	OPTIONAL
+}
+
+SIBtype-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+SliceSupportList ::= SEQUENCE (SIZE(1.. maxnoofSliceItems)) OF SliceSupportItem
+
+SliceSupportItem ::= SEQUENCE {
+	sNSSAI	SNSSAI,
+	iE-Extensions				ProtocolExtensionContainer { { SliceSupportItem-ExtIEs } }	OPTIONAL
+}
+
+SliceSupportItem-ExtIEs	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+SNSSAI ::= SEQUENCE {
+	sST			OCTET STRING (SIZE(1)),
+	sD			OCTET STRING (SIZE(3)) 	OPTIONAL	,
+	iE-Extensions				ProtocolExtensionContainer { { SNSSAI-ExtIEs } }	OPTIONAL
+}
+
+SNSSAI-ExtIEs	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+SpectrumSharingGroupID ::= INTEGER (1..maxCellineNB)
+
+SRBID ::= INTEGER (0..3, ...)
+
+SRBs-FailedToBeSetup-Item	::= SEQUENCE {
+	sRBID		SRBID	,
+	cause		Cause	OPTIONAL,
+	iE-Extensions	ProtocolExtensionContainer { { SRBs-FailedToBeSetup-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+SRBs-FailedToBeSetup-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+SRBs-FailedToBeSetupMod-Item	::= SEQUENCE {
+	sRBID		SRBID		,
+	cause		Cause		OPTIONAL,
+	iE-Extensions	ProtocolExtensionContainer { { SRBs-FailedToBeSetupMod-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+SRBs-FailedToBeSetupMod-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+
+SRBs-Required-ToBeReleased-Item	::= SEQUENCE {
+	sRBID	SRBID,
+	iE-Extensions	ProtocolExtensionContainer { { SRBs-Required-ToBeReleased-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+SRBs-Required-ToBeReleased-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+SRBs-ToBeReleased-Item	::= SEQUENCE {
+	sRBID		SRBID,
+	iE-Extensions	ProtocolExtensionContainer { { SRBs-ToBeReleased-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+SRBs-ToBeReleased-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+SRBs-ToBeSetup-Item ::= SEQUENCE {
+	sRBID	 SRBID	,
+	duplicationIndication	DuplicationIndication	OPTIONAL,
+	iE-Extensions	ProtocolExtensionContainer { { SRBs-ToBeSetup-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+SRBs-ToBeSetup-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+SRBs-ToBeSetupMod-Item	::= SEQUENCE {
+	sRBID	SRBID,
+	duplicationIndication	DuplicationIndication	OPTIONAL,
+	iE-Extensions	ProtocolExtensionContainer { { SRBs-ToBeSetupMod-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+SRBs-ToBeSetupMod-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+SUL-Information ::= SEQUENCE {
+	sUL-NRARFCN							INTEGER (0..maxNRARFCN),
+	sUL-transmission-Bandwidth			Transmission-Bandwidth,
+	iE-Extensions				ProtocolExtensionContainer { { SUL-InformationExtIEs} } OPTIONAL,
+	...
+}
+
+SUL-InformationExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+SubscriberProfileIDforRFP ::= INTEGER (1..256, ...)
+
+SupportedSULFreqBandItem ::= SEQUENCE {
+	freqBandIndicatorNr 			INTEGER (1..1024,...),
+	iE-Extensions				ProtocolExtensionContainer { { SupportedSULFreqBandItem-ExtIEs} } OPTIONAL,
+	...
+}
+
+SupportedSULFreqBandItem-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+-- T
+
+FiveGS-TAC ::= OCTET STRING (SIZE(3))
+
+Configured-EPS-TAC ::= OCTET STRING (SIZE(2))
+
+TDD-Info ::= SEQUENCE {
+	nRFreqInfo							NRFreqInfo,
+	transmission-Bandwidth			Transmission-Bandwidth,
+	iE-Extensions				ProtocolExtensionContainer { {TDD-Info-ExtIEs} } OPTIONAL,
+	...
+}
+
+TDD-Info-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+TimeToWait ::= ENUMERATED {v1s, v2s, v5s, v10s, v20s, v60s, ...}
+
+TNLAssociationUsage ::= ENUMERATED {
+	ue,
+	non-ue,
+	both, 
+...
+}
+
+TransportLayerAddress		::= BIT STRING (SIZE(1..160, ...))
+
+TransactionID				::= INTEGER (0..255, ...)
+
+Transmission-Bandwidth ::= SEQUENCE {
+	nRSCS	NRSCS,
+	nRNRB	NRNRB,
+	iE-Extensions				ProtocolExtensionContainer { { Transmission-Bandwidth-ExtIEs} } OPTIONAL,
+	...
+}
+
+Transmission-Bandwidth-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+TransmissionStopIndicator ::= ENUMERATED {true, ...}
+
+TypeOfError ::= ENUMERATED {
+	not-understood,
+	missing,
+	...
+}
+
+-- U
+
+UE-associatedLogicalF1-ConnectionItem ::= SEQUENCE {
+	gNB-CU-UE-F1AP-ID		GNB-CU-UE-F1AP-ID	 OPTIONAL,
+	gNB-DU-UE-F1AP-ID		GNB-DU-UE-F1AP-ID	 OPTIONAL,
+	iE-Extensions		ProtocolExtensionContainer { { UE-associatedLogicalF1-ConnectionItemExtIEs} } OPTIONAL,
+	...
+}
+
+UE-associatedLogicalF1-ConnectionItemExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+UE-CapabilityRAT-ContainerList::= OCTET STRING
+
+UEIdentityIndexValue ::= INTEGER (0..63) -- 	This IE may need to be refined.
+
+ULConfiguration ::= SEQUENCE	{
+	uLUEConfiguration		ULUEConfiguration,
+	iE-Extensions	ProtocolExtensionContainer { { ULConfigurationExtIEs } }	OPTIONAL,
+	...
+}
+ULConfigurationExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+ULUEConfiguration ::= ENUMERATED {no-data, shared, only, ...}
+
+
+ULUPTNLInformation-ToBeSetup-List ::= SEQUENCE (SIZE(1..maxnoofULUPTNLInformation)) OF ULUPTNLInformation-ToBeSetup-Item
+
+ULUPTNLInformation-ToBeSetup-Item ::=SEQUENCE {
+	uLUPTNLInformation		UPTransportLayerInformation, 
+	iE-Extensions	ProtocolExtensionContainer { { ULUPTNLInformation-ToBeSetup-ItemExtIEs } }	OPTIONAL,
+	...
+}
+
+ULUPTNLInformation-ToBeSetup-ItemExtIEs 	F1AP-PROTOCOL-EXTENSION ::= {
+	...
+}
+
+UPTransportLayerInformation		::= CHOICE {
+	gTPTunnel		GTPTunnel,
+	choice-extension			ProtocolExtensionContainer { { UPTransportLayerInformation-ExtIEs} },
+	...
+}
+
+UPTransportLayerInformation-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
+	...
+	}
+-- V
+
+-- W
+
+-- X
+
+-- Y
+
+-- Z
+
+END
diff --git a/openair2/F1AP/MESSAGES/ASN1/R15.2.1/F1AP-PDU-Contents.asn b/openair2/F1AP/MESSAGES/ASN1/R15.2.1/F1AP-PDU-Contents.asn
new file mode 100644
index 0000000000000000000000000000000000000000..ec6e3733b1417c1bd6cfedbcc30eb71f7683a92b
--- /dev/null
+++ b/openair2/F1AP/MESSAGES/ASN1/R15.2.1/F1AP-PDU-Contents.asn
@@ -0,0 +1,1578 @@
+-- **************************************************************
+--
+-- PDU definitions for F1AP.
+--
+-- **************************************************************
+
+F1AP-PDU-Contents { 
+itu-t (0) identified-organization (4) etsi (0) mobileDomain (0) 
+ngran-access (22) modules (3) f1ap (3) version1 (1) f1ap-PDU-Contents (1) }
+
+DEFINITIONS AUTOMATIC TAGS ::= 
+
+BEGIN
+
+-- **************************************************************
+--
+-- IE parameter types from other modules.
+--
+-- **************************************************************
+
+IMPORTS
+	Active-Cells-Item,
+	Candidate-SpCell-Item,
+	Cause,
+	Cells-Failed-to-be-Activated-List-Item,
+	Cells-to-be-Activated-List-Item,
+	Cells-to-be-Deactivated-List-Item, 
+	CellULConfigured,
+	CriticalityDiagnostics, 
+	C-RNTI,
+	CUtoDURRCInformation, 
+	DRB-Activity-Item,
+	DRBID,
+	DRBs-FailedToBeModified-Item,
+	DRBs-FailedToBeSetup-Item,
+	DRBs-FailedToBeSetupMod-Item,
+	DRB-Notify-Item,
+	DRBs-ModifiedConf-Item,
+	DRBs-Modified-Item,
+	DRBs-Required-ToBeModified-Item,
+	DRBs-Required-ToBeReleased-Item,
+	DRBs-Setup-Item,
+	DRBs-SetupMod-Item,
+	DRBs-ToBeModified-Item,
+	DRBs-ToBeReleased-Item,
+	DRBs-ToBeSetup-Item,
+	DRBs-ToBeSetupMod-Item,
+	DRXCycle,
+	DUtoCURRCInformation,
+	EUTRANQoS,
+	ExecuteDuplication,
+	FullConfiguration,
+	GNB-CU-UE-F1AP-ID,
+	GNB-DU-UE-F1AP-ID,
+	GNB-DU-ID,
+	GNB-DU-Served-Cells-Item,
+	GNB-DU-System-Information, 
+	GNB-CU-Name,
+	GNB-DU-Name,
+	InactivityMonitoringRequest,
+	InactivityMonitoringResponse,
+	NotificationControl,
+	NRCGI,
+	NRPCI,
+	Potential-SpCell-Item,
+	RAT-FrequencyPriorityInformation,
+	ResourceCoordinationTransferContainer,
+	RRCContainer,
+	RRCRconfigurationCompleteIndicator,
+	SCellIndex,
+	SCell-ToBeRemoved-Item,
+	SCell-ToBeSetup-Item,
+	SCell-ToBeSetupMod-Item,
+	SCell-FailedtoSetup-Item,
+	SCell-FailedtoSetupMod-Item, 
+	ServCellIndex,
+	Served-Cell-Information,
+	Served-Cells-To-Add-Item,
+	Served-Cells-To-Delete-Item,
+	Served-Cells-To-Modify-Item,
+	SRBID,
+	SRBs-FailedToBeSetup-Item,
+	SRBs-FailedToBeSetupMod-Item,
+	SRBs-Required-ToBeReleased-Item,
+	SRBs-ToBeReleased-Item,
+	SRBs-ToBeSetup-Item,
+	SRBs-ToBeSetupMod-Item,
+	TimeToWait,
+	TransactionID,
+	TransmissionStopIndicator,
+	UE-associatedLogicalF1-ConnectionItem,
+	DUtoCURRCContainer,
+	PagingCell-Item, 
+	SIBtype-List,
+	UEIdentityIndexValue,
+	GNB-CU-TNL-Association-Setup-Item,
+	GNB-CU-TNL-Association-Failed-To-Setup-Item,
+	GNB-CU-TNL-Association-To-Add-Item,
+	GNB-CU-TNL-Association-To-Remove-Item,
+	GNB-CU-TNL-Association-To-Update-Item,
+	MaskedIMEISV,
+	PagingDRX,
+	PagingPriority,
+	PagingIdentity,
+	Cells-to-be-Barred-Item,
+	PWSSystemInformation,
+	Broadcast-To-Be-Cancelled-Item,
+	Cells-Broadcast-Cancelled-Item,
+	ConcurrentWarningMessageIndicator,
+	NR-CGI-List-For-Restart-Item,
+	PWS-Failed-NR-CGI-Item,
+	RepetitionPeriod,
+	NumberofBroadcastRequest,
+	Cells-To-Be-Broadcast-Item,
+	Cells-Broadcast-Completed-Item,
+	Cancel-all-Warning-Messages-Indicator,
+	EUTRA-NR-CellResourceCoordinationReq-Container,
+	EUTRA-NR-CellResourceCoordinationReqAck-Container,
+	ListofEUTRACellsinGNBDUCoordination,
+	SpectrumSharingGroupID,
+	RequestType
+
+FROM F1AP-IEs
+
+	PrivateIE-Container{},
+	ProtocolExtensionContainer{},
+	ProtocolIE-Container{},
+	ProtocolIE-ContainerPair{},
+	ProtocolIE-SingleContainer{},
+	F1AP-PRIVATE-IES,
+	F1AP-PROTOCOL-EXTENSION,
+	F1AP-PROTOCOL-IES,
+	F1AP-PROTOCOL-IES-PAIR
+
+FROM F1AP-Containers
+
+	id-Active-Cells-Item,
+	id-Active-Cells-List,
+	id-Candidate-SpCell-Item,
+	id-Candidate-SpCell-List,
+	id-Cause,
+	id-Cancel-all-Warning-Messages-Indicator,
+	id-Cells-Failed-to-be-Activated-List,
+	id-Cells-Failed-to-be-Activated-List-Item,
+	id-Cells-to-be-Activated-List,
+	id-Cells-to-be-Activated-List-Item,
+	id-Cells-to-be-Deactivated-List,
+	id-Cells-to-be-Deactivated-List-Item,
+	id-ConfirmedUEID,
+	id-CriticalityDiagnostics,
+	id-C-RNTI,
+	id-CUtoDURRCInformation,
+	id-DRB-Activity-Item,
+	id-DRB-Activity-List,
+	id-DRBs-FailedToBeModified-Item,
+	id-DRBs-FailedToBeModified-List,
+	id-DRBs-FailedToBeSetup-Item,
+	id-DRBs-FailedToBeSetup-List,
+	id-DRBs-FailedToBeSetupMod-Item,
+	id-DRBs-FailedToBeSetupMod-List,
+	id-DRBs-ModifiedConf-Item,
+	id-DRBs-ModifiedConf-List,
+	id-DRBs-Modified-Item,
+	id-DRBs-Modified-List,
+	id-DRB-Notify-Item,
+	id-DRB-Notify-List,
+	id-DRBs-Required-ToBeModified-Item,
+	id-DRBs-Required-ToBeModified-List,
+	id-DRBs-Required-ToBeReleased-Item,
+	id-DRBs-Required-ToBeReleased-List,
+	id-DRBs-Setup-Item,
+	id-DRBs-Setup-List,
+	id-DRBs-SetupMod-Item,
+	id-DRBs-SetupMod-List,
+	id-DRBs-ToBeModified-Item,
+	id-DRBs-ToBeModified-List,
+	id-DRBs-ToBeReleased-Item,
+	id-DRBs-ToBeReleased-List,
+	id-DRBs-ToBeSetup-Item,
+	id-DRBs-ToBeSetup-List,
+	id-DRBs-ToBeSetupMod-Item,
+	id-DRBs-ToBeSetupMod-List,
+	id-DRXCycle,
+	id-DUtoCURRCInformation,
+	id-ExecuteDuplication,
+	id-FullConfiguration,
+	id-gNB-CU-UE-F1AP-ID,
+	id-gNB-DU-UE-F1AP-ID,
+	id-gNB-DU-ID,
+	id-GNB-DU-Served-Cells-Item,
+	id-gNB-DU-Served-Cells-List, 
+	id-gNB-CU-Name,
+	id-gNB-DU-Name,
+	id-InactivityMonitoringRequest,
+	id-InactivityMonitoringResponse,
+	id-oldgNB-DU-UE-F1AP-ID,
+	id-Potential-SpCell-Item,
+	id-Potential-SpCell-List,
+	id-RAT-FrequencyPriorityInformation,
+	id-ResetType,
+	id-ResourceCoordinationTransferContainer,
+	id-RRCContainer,
+	id-RRCRconfigurationCompleteIndicator,
+	id-SCell-FailedtoSetup-List,
+	id-SCell-FailedtoSetup-Item,
+	id-SCell-FailedtoSetupMod-List,
+	id-SCell-FailedtoSetupMod-Item,
+	id-SCell-ToBeRemoved-Item,
+	id-SCell-ToBeRemoved-List,
+	id-SCell-ToBeSetup-Item,
+	id-SCell-ToBeSetup-List,
+	id-SCell-ToBeSetupMod-Item,
+	id-SCell-ToBeSetupMod-List,
+	id-Served-Cells-To-Add-Item,
+	id-Served-Cells-To-Add-List,
+	id-Served-Cells-To-Delete-Item,
+	id-Served-Cells-To-Delete-List,
+	id-Served-Cells-To-Modify-Item,
+	id-Served-Cells-To-Modify-List,
+	id-ServCellndex,
+	id-SpCell-ID,
+	id-SpCellULConfigured,
+	id-SRBID,
+	id-SRBs-FailedToBeSetup-Item,
+	id-SRBs-FailedToBeSetup-List,
+	id-SRBs-FailedToBeSetupMod-Item,
+	id-SRBs-FailedToBeSetupMod-List,
+	id-SRBs-Required-ToBeReleased-Item,
+	id-SRBs-Required-ToBeReleased-List,
+	id-SRBs-ToBeReleased-Item,
+	id-SRBs-ToBeReleased-List, 
+	id-SRBs-ToBeSetup-Item,
+	id-SRBs-ToBeSetup-List,
+	id-SRBs-ToBeSetupMod-Item,
+	id-SRBs-ToBeSetupMod-List,
+	id-TimeToWait,
+	id-TransactionID,
+	id-TransmissionStopIndicator,
+	id-UE-associatedLogicalF1-ConnectionItem,
+	id-UE-associatedLogicalF1-ConnectionListResAck,
+	id-DUtoCURRCContainer,
+	id-NRCGI,
+	id-PagingCell-Item,
+	id-PagingCell-List,
+	id-PagingDRX,
+	id-PagingPriority,
+	id-SIBtype-List,
+	id-UEIdentityIndexValue,
+	id-GNB-CU-TNL-Association-Setup-List,
+	id-GNB-CU-TNL-Association-Setup-Item,
+	id-GNB-CU-TNL-Association-Failed-To-Setup-List,
+	id-GNB-CU-TNL-Association-Failed-To-Setup-Item,
+	id-GNB-CU-TNL-Association-To-Add-Item,
+	id-GNB-CU-TNL-Association-To-Add-List,
+	id-GNB-CU-TNL-Association-To-Remove-Item,
+	id-GNB-CU-TNL-Association-To-Remove-List,
+	id-GNB-CU-TNL-Association-To-Update-Item,
+	id-GNB-CU-TNL-Association-To-Update-List,
+	id-MaskedIMEISV,
+	id-PagingIdentity,
+	id-Cells-to-be-Barred-List,
+	id-Cells-to-be-Barred-Item,
+	id-PWSSystemInformation,
+	id-RepetitionPeriod,
+	id-NumberofBroadcastRequest,
+	id-ConcurrentWarningMessageIndicator,
+	id-Cells-To-Be-Broadcast-List,
+	id-Cells-To-Be-Broadcast-Item,
+	id-Cells-Broadcast-Completed-List,
+	id-Cells-Broadcast-Completed-Item,
+	id-Broadcast-To-Be-Cancelled-List,
+	id-Broadcast-To-Be-Cancelled-Item,
+	id-Cells-Broadcast-Cancelled-List,
+	id-Cells-Broadcast-Cancelled-Item,
+	id-NR-CGI-List-For-Restart-List,
+	id-NR-CGI-List-For-Restart-Item,
+	id-PWS-Failed-NR-CGI-List,
+	id-PWS-Failed-NR-CGI-Item,
+	id-EUTRA-NR-CellResourceCoordinationReq-Container,
+	id-EUTRA-NR-CellResourceCoordinationReqAck-Container,
+	id-SpectrumSharingGroupID,
+	id-ListofEUTRACellsinGNBDUCoordination,
+	id-Protected-EUTRA-Resources-List,
+	id-RequestType,
+	maxCellingNBDU,
+	maxnoofCandidateSpCells,
+	maxnoofDRBs,
+	maxnoofErrors,
+	maxnoofIndividualF1ConnectionsToReset,
+	maxnoofPotentialSpCells,
+	maxnoofSCells,
+	maxnoofSRBs,
+	maxnoofPagingCells,
+	maxnoofTNLAssociations,
+	maxCellineNB
+
+FROM F1AP-Constants;
+
+
+-- **************************************************************
+--
+-- RESET ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- Reset
+--
+-- **************************************************************
+
+Reset ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       { {ResetIEs} },
+	...
+}
+
+ResetIEs F1AP-PROTOCOL-IES ::= { 
+	{ ID id-TransactionID				CRITICALITY reject	TYPE TransactionID				PRESENCE mandatory	}|
+	{ ID id-Cause						CRITICALITY ignore	TYPE Cause						PRESENCE mandatory	}|
+	{ ID id-ResetType					CRITICALITY reject	TYPE ResetType					PRESENCE mandatory	},
+	...
+}
+
+ResetType ::= CHOICE {
+	f1-Interface					ResetAll,
+	partOfF1-Interface				UE-associatedLogicalF1-ConnectionListRes,
+	...
+}
+
+
+ResetAll ::= ENUMERATED {
+	reset-all,
+	...
+}
+
+UE-associatedLogicalF1-ConnectionListRes ::= SEQUENCE (SIZE(1.. maxnoofIndividualF1ConnectionsToReset)) OF ProtocolIE-SingleContainer { { UE-associatedLogicalF1-ConnectionItemRes } }
+
+UE-associatedLogicalF1-ConnectionItemRes F1AP-PROTOCOL-IES ::= {
+	{ ID id-UE-associatedLogicalF1-ConnectionItem	CRITICALITY reject	TYPE UE-associatedLogicalF1-ConnectionItem	PRESENCE mandatory},
+	...
+}
+
+
+-- **************************************************************
+--
+-- Reset Acknowledge
+--
+-- **************************************************************
+
+ResetAcknowledge ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       { {ResetAcknowledgeIEs} },
+	...
+}
+
+ResetAcknowledgeIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-TransactionID									CRITICALITY reject	TYPE TransactionID													PRESENCE mandatory	}|
+	{ ID id-UE-associatedLogicalF1-ConnectionListResAck		CRITICALITY ignore	TYPE UE-associatedLogicalF1-ConnectionListResAck			PRESENCE optional	}|
+	{ ID id-CriticalityDiagnostics		CRITICALITY ignore	TYPE CriticalityDiagnostics			PRESENCE optional	},
+	...
+}
+
+UE-associatedLogicalF1-ConnectionListResAck ::= SEQUENCE (SIZE(1.. maxnoofIndividualF1ConnectionsToReset)) OF ProtocolIE-SingleContainer { { UE-associatedLogicalF1-ConnectionItemResAck } }
+
+UE-associatedLogicalF1-ConnectionItemResAck 	F1AP-PROTOCOL-IES ::= {
+	{ ID id-UE-associatedLogicalF1-ConnectionItem	 CRITICALITY ignore 	TYPE UE-associatedLogicalF1-ConnectionItem  	PRESENCE mandatory },
+	...
+}
+
+-- **************************************************************
+--
+-- ERROR INDICATION ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- Error Indication
+--
+-- **************************************************************
+
+ErrorIndication ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       {{ErrorIndicationIEs}},
+	...
+}
+
+ErrorIndicationIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-TransactionID				CRITICALITY reject	TYPE TransactionID				PRESENCE mandatory}|
+	{ ID id-gNB-CU-UE-F1AP-ID			CRITICALITY ignore	TYPE GNB-CU-UE-F1AP-ID			PRESENCE optional	}|
+	{ ID id-gNB-DU-UE-F1AP-ID			CRITICALITY ignore	TYPE GNB-DU-UE-F1AP-ID			PRESENCE optional	}|
+	{ ID id-Cause						CRITICALITY ignore	TYPE Cause						PRESENCE optional	}|
+	{ ID id-CriticalityDiagnostics		CRITICALITY ignore	TYPE CriticalityDiagnostics		PRESENCE optional	},
+	...
+}
+
+-- **************************************************************
+--
+-- F1 SETUP ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- F1 Setup Request
+--
+-- **************************************************************
+
+F1SetupRequest ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       { {F1SetupRequestIEs} },
+	...
+}
+
+F1SetupRequestIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-TransactionID					CRITICALITY reject	TYPE TransactionID				PRESENCE mandatory	}|
+	{ ID id-gNB-DU-ID						CRITICALITY reject	TYPE GNB-DU-ID					PRESENCE mandatory	}|
+	{ ID id-gNB-DU-Name						CRITICALITY ignore	TYPE GNB-DU-Name				PRESENCE optional	}|
+	{ ID id-gNB-DU-Served-Cells-List		CRITICALITY reject	TYPE GNB-DU-Served-Cells-List	PRESENCE mandatory	},
+	...
+} 
+
+
+GNB-DU-Served-Cells-List 	::= SEQUENCE (SIZE(1.. maxCellingNBDU)) OF ProtocolIE-SingleContainer { { GNB-DU-Served-Cells-ItemIEs } }
+
+GNB-DU-Served-Cells-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-GNB-DU-Served-Cells-Item		CRITICALITY reject	TYPE		GNB-DU-Served-Cells-Item	PRESENCE mandatory	},
+	...
+}
+
+
+-- **************************************************************
+--
+-- F1 Setup Response
+--
+-- **************************************************************
+
+F1SetupResponse ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       { {F1SetupResponseIEs} },
+	...
+}
+
+
+F1SetupResponseIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-TransactionID				CRITICALITY reject	TYPE TransactionID					PRESENCE mandatory	}|
+	{ ID id-gNB-CU-Name					CRITICALITY ignore	TYPE GNB-CU-Name					PRESENCE optional	}|
+	{ ID id-Cells-to-be-Activated-List	CRITICALITY reject	TYPE Cells-to-be-Activated-List		PRESENCE optional	},
+	...
+}
+
+
+Cells-to-be-Activated-List	::= SEQUENCE (SIZE(1.. maxCellingNBDU))	OF ProtocolIE-SingleContainer { { Cells-to-be-Activated-List-ItemIEs } }
+
+Cells-to-be-Activated-List-ItemIEs	F1AP-PROTOCOL-IES::= {
+	{ ID id-Cells-to-be-Activated-List-Item				CRITICALITY reject	TYPE Cells-to-be-Activated-List-Item						PRESENCE mandatory},
+	...
+}
+
+
+
+-- **************************************************************
+--
+-- F1 Setup Failure
+--
+-- **************************************************************
+
+F1SetupFailure ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       { {F1SetupFailureIEs} },
+	...
+}
+
+F1SetupFailureIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-TransactionID				CRITICALITY reject	TYPE TransactionID				PRESENCE mandatory	}|
+	{ ID id-Cause						CRITICALITY ignore	TYPE Cause						PRESENCE mandatory	}|
+	{ ID id-TimeToWait					CRITICALITY ignore	TYPE TimeToWait					PRESENCE optional	}|
+	{ ID id-CriticalityDiagnostics		CRITICALITY ignore	TYPE CriticalityDiagnostics		PRESENCE optional	},
+	...
+}
+
+
+-- **************************************************************
+--
+-- GNB-DU CONFIGURATION UPDATE ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- GNB-DU CONFIGURATION UPDATE
+--
+-- **************************************************************
+
+GNBDUConfigurationUpdate::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       { {GNBDUConfigurationUpdateIEs} },
+	...
+}
+
+GNBDUConfigurationUpdateIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-TransactionID					CRITICALITY reject	TYPE TransactionID									PRESENCE mandatory	}|
+	{ ID id-Served-Cells-To-Add-List		CRITICALITY reject	TYPE Served-Cells-To-Add-List						PRESENCE optional	}|
+	{ ID id-Served-Cells-To-Modify-List		CRITICALITY reject	TYPE Served-Cells-To-Modify-List					PRESENCE optional	}|
+	{ ID id-Served-Cells-To-Delete-List		CRITICALITY reject	TYPE Served-Cells-To-Delete-List					PRESENCE optional	}|
+	{ ID id-Active-Cells-List				CRITICALITY reject	TYPE	 Active-Cells-List							PRESENCE optional	},
+	...
+} 
+Served-Cells-To-Add-List		::= SEQUENCE (SIZE(1.. maxCellingNBDU))	OF ProtocolIE-SingleContainer { { Served-Cells-To-Add-ItemIEs } }
+Served-Cells-To-Modify-List	::= SEQUENCE (SIZE(1.. maxCellingNBDU))	OF ProtocolIE-SingleContainer { { Served-Cells-To-Modify-ItemIEs } }
+Served-Cells-To-Delete-List	::= SEQUENCE (SIZE(1.. maxCellingNBDU))	OF ProtocolIE-SingleContainer { { Served-Cells-To-Delete-ItemIEs } }
+Active-Cells-List	::= SEQUENCE (SIZE(0.. maxCellingNBDU))	OF ProtocolIE-SingleContainer { { Active-Cells-ItemIEs } }
+
+Served-Cells-To-Add-ItemIEs F1AP-PROTOCOL-IES	::= {
+	{ ID id-Served-Cells-To-Add-Item		CRITICALITY reject	TYPE	Served-Cells-To-Add-Item				PRESENCE mandatory	},
+	...
+}
+
+Served-Cells-To-Modify-ItemIEs F1AP-PROTOCOL-IES	::= {
+	{ ID id-Served-Cells-To-Modify-Item			CRITICALITY reject	TYPE		Served-Cells-To-Modify-Item							PRESENCE mandatory	},
+	...
+}
+
+Served-Cells-To-Delete-ItemIEs F1AP-PROTOCOL-IES	::= {
+	{ ID id-Served-Cells-To-Delete-Item				CRITICALITY reject	TYPE		Served-Cells-To-Delete-Item					PRESENCE mandatory	},
+...
+}
+
+Active-Cells-ItemIEs F1AP-PROTOCOL-IES	::= {
+	{ ID id-Active-Cells-Item				CRITICALITY reject	TYPE		Active-Cells-Item					PRESENCE mandatory	},
+	...
+}
+
+
+-- **************************************************************
+--
+-- GNB-DU CONFIGURATION UPDATE ACKNOWLEDGE
+--
+-- **************************************************************
+
+GNBDUConfigurationUpdateAcknowledge ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       { {GNBDUConfigurationUpdateAcknowledgeIEs} },
+	...
+}
+
+
+GNBDUConfigurationUpdateAcknowledgeIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-TransactionID					CRITICALITY reject	TYPE TransactionID						PRESENCE mandatory	}|
+	{ ID id-Cells-to-be-Activated-List		CRITICALITY reject	TYPE Cells-to-be-Activated-List			PRESENCE optional	}|
+	{ ID id-CriticalityDiagnostics			CRITICALITY ignore	TYPE CriticalityDiagnostics				PRESENCE optional	},
+	...
+}
+
+-- **************************************************************
+--
+-- GNB-DU CONFIGURATION UPDATE FAILURE
+--
+-- **************************************************************
+
+GNBDUConfigurationUpdateFailure ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       { {GNBDUConfigurationUpdateFailureIEs} },
+	...
+}
+
+GNBDUConfigurationUpdateFailureIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-TransactionID				CRITICALITY reject	TYPE TransactionID				PRESENCE mandatory	}|
+	{ ID id-Cause						CRITICALITY ignore	TYPE Cause						PRESENCE mandatory	}|
+	{ ID id-TimeToWait					CRITICALITY ignore	TYPE TimeToWait					PRESENCE optional	}|
+	{ ID id-CriticalityDiagnostics		CRITICALITY ignore	TYPE CriticalityDiagnostics		PRESENCE optional	},
+	...
+}
+
+-- **************************************************************
+--
+-- GNB-CU CONFIGURATION UPDATE ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- GNB-CU CONFIGURATION UPDATE
+--
+-- **************************************************************
+
+GNBCUConfigurationUpdate ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       { { GNBCUConfigurationUpdateIEs} },
+	...
+}
+
+GNBCUConfigurationUpdateIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-TransactionID					CRITICALITY reject	TYPE TransactionID									PRESENCE mandatory	}|
+	{ ID id-Cells-to-be-Activated-List		CRITICALITY reject	TYPE	 Cells-to-be-Activated-List				PRESENCE optional	}|
+	{ ID id-Cells-to-be-Deactivated-List	CRITICALITY reject	TYPE	 Cells-to-be-Deactivated-List			PRESENCE optional	}|
+	{ ID id-GNB-CU-TNL-Association-To-Add-List		CRITICALITY ignore	TYPE	 GNB-CU-TNL-Association-To-Add-List				PRESENCE optional	}|
+	{ ID id-GNB-CU-TNL-Association-To-Remove-List	CRITICALITY ignore	TYPE	 GNB-CU-TNL-Association-To-Remove-List			PRESENCE optional	}|
+	{ ID id-GNB-CU-TNL-Association-To-Update-List	CRITICALITY ignore	TYPE	 GNB-CU-TNL-Association-To-Update-List			PRESENCE optional	}|
+	{ ID id-Cells-to-be-Barred-List			CRITICALITY ignore	TYPE	 Cells-to-be-Barred-List											PRESENCE optional	}|
+	{ ID id-Protected-EUTRA-Resources-List	CRITICALITY reject	TYPE	 Protected-EUTRA-Resources-List			PRESENCE optional	},
+	...
+} 
+
+Cells-to-be-Deactivated-List	::= SEQUENCE (SIZE(1.. maxCellingNBDU))	OF ProtocolIE-SingleContainer { { Cells-to-be-Deactivated-List-ItemIEs } }
+GNB-CU-TNL-Association-To-Add-List		::= SEQUENCE (SIZE(1.. maxnoofTNLAssociations))	OF ProtocolIE-SingleContainer { { GNB-CU-TNL-Association-To-Add-ItemIEs } }
+GNB-CU-TNL-Association-To-Remove-List	::= SEQUENCE (SIZE(1.. maxnoofTNLAssociations))	OF ProtocolIE-SingleContainer { { GNB-CU-TNL-Association-To-Remove-ItemIEs } }
+GNB-CU-TNL-Association-To-Update-List	::= SEQUENCE (SIZE(1.. maxnoofTNLAssociations))	OF ProtocolIE-SingleContainer { { GNB-CU-TNL-Association-To-Update-ItemIEs } }
+Cells-to-be-Barred-List			::= SEQUENCE(SIZE(1.. maxCellingNBDU)) OF ProtocolIE-SingleContainer { { Cells-to-be-Barred-ItemIEs } }
+
+
+Cells-to-be-Deactivated-List-ItemIEs F1AP-PROTOCOL-IES	::= {
+	{ ID id-Cells-to-be-Deactivated-List-Item						CRITICALITY reject	TYPE	Cells-to-be-Deactivated-List-Item					PRESENCE mandatory	},
+...}
+
+
+GNB-CU-TNL-Association-To-Add-ItemIEs F1AP-PROTOCOL-IES	::= {
+	{ ID id-GNB-CU-TNL-Association-To-Add-Item		CRITICALITY reject	TYPE	 GNB-CU-TNL-Association-To-Add-Item			PRESENCE mandatory	},
+...}
+
+GNB-CU-TNL-Association-To-Remove-ItemIEs F1AP-PROTOCOL-IES	::= {
+	{ ID id-GNB-CU-TNL-Association-To-Remove-Item		CRITICALITY reject	TYPE	 GNB-CU-TNL-Association-To-Remove-Item			PRESENCE mandatory	},
+...}
+
+GNB-CU-TNL-Association-To-Update-ItemIEs F1AP-PROTOCOL-IES	::= {
+	{ ID id-GNB-CU-TNL-Association-To-Update-Item		CRITICALITY reject	TYPE	 GNB-CU-TNL-Association-To-Update-Item			PRESENCE mandatory	},
+...}
+
+Cells-to-be-Barred-ItemIEs F1AP-PROTOCOL-IES	::= {
+	{ ID id-Cells-to-be-Barred-Item		CRITICALITY ignore	TYPE	 Cells-to-be-Barred-Item				PRESENCE mandatory	},
+	...
+}
+
+Protected-EUTRA-Resources-List ::= SEQUENCE (SIZE(1.. maxCellineNB))	OF ProtocolIE-SingleContainer { { Protected-EUTRA-Resources-ItemIEs } }
+Protected-EUTRA-Resources-ItemIEs F1AP-PROTOCOL-IES	::= {
+	{ ID id-SpectrumSharingGroupID 					CRITICALITY reject 	TYPE SpectrumSharingGroupID 							PRESENCE mandatory}|
+	{ ID id-ListofEUTRACellsinGNBDUCoordination		CRITICALITY reject	TYPE ListofEUTRACellsinGNBDUCoordination			PRESENCE mandatory },
+...}
+
+-- **************************************************************
+--
+-- GNB-CU CONFIGURATION UPDATE ACKNOWLEDGE
+--
+-- **************************************************************
+
+GNBCUConfigurationUpdateAcknowledge ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       { { GNBCUConfigurationUpdateAcknowledgeIEs} },
+	...
+}
+
+
+GNBCUConfigurationUpdateAcknowledgeIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-TransactionID						CRITICALITY reject	TYPE TransactionID									PRESENCE mandatory	}|
+	{ ID id-Cells-Failed-to-be-Activated-List	CRITICALITY reject	TYPE Cells-Failed-to-be-Activated-List			PRESENCE optional}|
+	{ ID id-CriticalityDiagnostics				CRITICALITY ignore	TYPE CriticalityDiagnostics							PRESENCE optional	}|
+	{ ID id-GNB-CU-TNL-Association-Setup-List		CRITICALITY ignore	TYPE	 GNB-CU-TNL-Association-Setup-List				PRESENCE optional	}|
+	{ ID id-GNB-CU-TNL-Association-Failed-To-Setup-List		CRITICALITY ignore	TYPE	 GNB-CU-TNL-Association-Failed-To-Setup-List				PRESENCE optional	},
+	...
+}
+
+Cells-Failed-to-be-Activated-List	::= SEQUENCE (SIZE(1.. maxCellingNBDU))	OF ProtocolIE-SingleContainer { { Cells-Failed-to-be-Activated-List-ItemIEs } }
+GNB-CU-TNL-Association-Setup-List ::= SEQUENCE (SIZE(1.. maxnoofTNLAssociations))	OF ProtocolIE-SingleContainer { { GNB-CU-TNL-Association-Setup-ItemIEs } }
+GNB-CU-TNL-Association-Failed-To-Setup-List ::= SEQUENCE (SIZE(1.. maxnoofTNLAssociations))	OF ProtocolIE-SingleContainer { { GNB-CU-TNL-Association-Failed-To-Setup-ItemIEs } }
+
+Cells-Failed-to-be-Activated-List-ItemIEs F1AP-PROTOCOL-IES		::= {
+	{ ID id-Cells-Failed-to-be-Activated-List-Item		CRITICALITY reject	TYPE Cells-Failed-to-be-Activated-List-Item		PRESENCE mandatory	},
+	...
+}
+
+GNB-CU-TNL-Association-Setup-ItemIEs F1AP-PROTOCOL-IES	::= {
+	{ ID id-GNB-CU-TNL-Association-Setup-Item		CRITICALITY reject	TYPE	 GNB-CU-TNL-Association-Setup-Item			PRESENCE mandatory	},
+...}
+
+
+GNB-CU-TNL-Association-Failed-To-Setup-ItemIEs F1AP-PROTOCOL-IES	::= {
+	{ ID id-GNB-CU-TNL-Association-Failed-To-Setup-Item		CRITICALITY reject	TYPE	 GNB-CU-TNL-Association-Failed-To-Setup-Item			PRESENCE mandatory	},
+...}
+
+
+-- **************************************************************
+--
+-- GNB-CU CONFIGURATION UPDATE FAILURE
+--
+-- **************************************************************
+
+GNBCUConfigurationUpdateFailure ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       { { GNBCUConfigurationUpdateFailureIEs} },
+	...
+}
+
+GNBCUConfigurationUpdateFailureIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-TransactionID				CRITICALITY reject	TYPE TransactionID				PRESENCE mandatory	}|
+	{ ID id-Cause						CRITICALITY ignore	TYPE Cause						PRESENCE mandatory	}|
+	{ ID id-TimeToWait					CRITICALITY ignore	TYPE TimeToWait					PRESENCE optional	}|
+	{ ID id-CriticalityDiagnostics		CRITICALITY ignore	TYPE CriticalityDiagnostics		PRESENCE optional	},
+	...
+}
+
+
+-- **************************************************************
+--
+-- GNB-DU RESOURCE COORDINATION REQUEST 
+--
+-- **************************************************************
+
+GNBDUResourceCoordinationRequest ::= SEQUENCE {
+	protocolIEs		ProtocolIE-Container		{{GNBDUResourceCoordinationRequest-IEs}},
+	...
+}
+
+GNBDUResourceCoordinationRequest-IEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-TransactionID									CRITICALITY reject	TYPE TransactionID						PRESENCE mandatory	}|
+	{ ID id-RequestType	CRITICALITY reject	TYPE RequestType						PRESENCE mandatory	}|
+	{ ID id-EUTRA-NR-CellResourceCoordinationReq-Container	CRITICALITY reject	TYPE EUTRA-NR-CellResourceCoordinationReq-Container		PRESENCE mandatory},
+	...
+}
+
+
+-- **************************************************************
+--
+-- GNB-DU RESOURCE COORDINATION RESPONSE 
+--
+-- **************************************************************
+
+GNBDUResourceCoordinationResponse ::= SEQUENCE {
+	protocolIEs		ProtocolIE-Container		{{GNBDUResourceCoordinationResponse-IEs}},
+	...
+}
+
+GNBDUResourceCoordinationResponse-IEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-TransactionID									CRITICALITY reject	TYPE TransactionID						PRESENCE mandatory	}|
+	{ ID id-EUTRA-NR-CellResourceCoordinationReqAck-Container	CRITICALITY reject	TYPE EUTRA-NR-CellResourceCoordinationReqAck-Container		PRESENCE mandatory},
+	...
+}
+
+-- **************************************************************
+--
+-- UE Context Setup ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- UE CONTEXT SETUP REQUEST
+--
+-- **************************************************************
+
+UEContextSetupRequest ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       { { UEContextSetupRequestIEs} },
+	...
+}
+
+UEContextSetupRequestIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-gNB-CU-UE-F1AP-ID						CRITICALITY reject	TYPE GNB-CU-UE-F1AP-ID								PRESENCE mandatory	}|
+	{ ID id-gNB-DU-UE-F1AP-ID						CRITICALITY ignore	TYPE GNB-DU-UE-F1AP-ID								PRESENCE optional 	}|
+	{ ID id-SpCell-ID								CRITICALITY reject	TYPE NRCGI											PRESENCE mandatory	}|
+	{ ID id-ServCellndex							CRITICALITY reject	TYPE ServCellIndex									PRESENCE mandatory	}|
+	{ ID id-SpCellULConfigured						CRITICALITY ignore	TYPE CellULConfigured								PRESENCE optional	}|
+	{ ID id-CUtoDURRCInformation					CRITICALITY reject	TYPE CUtoDURRCInformation							PRESENCE mandatory}|
+	{ ID id-Candidate-SpCell-List					CRITICALITY ignore	TYPE Candidate-SpCell-List						PRESENCE optional	}|
+	{ ID id-DRXCycle								CRITICALITY ignore	TYPE DRXCycle										PRESENCE optional	}|
+	{ ID id-ResourceCoordinationTransferContainer	CRITICALITY ignore	TYPE ResourceCoordinationTransferContainer	PRESENCE optional	}|
+	{ ID id-SCell-ToBeSetup-List					CRITICALITY ignore	TYPE SCell-ToBeSetup-List							PRESENCE optional	}|
+	{ ID id-SRBs-ToBeSetup-List						CRITICALITY reject	TYPE SRBs-ToBeSetup-List							PRESENCE optional	}|
+	{ ID id-DRBs-ToBeSetup-List						CRITICALITY reject	TYPE DRBs-ToBeSetup-List							PRESENCE optional	}|
+	{ ID id-InactivityMonitoringRequest				CRITICALITY reject	TYPE InactivityMonitoringRequest					PRESENCE optional	}|
+	{ ID id-RAT-FrequencyPriorityInformation		CRITICALITY reject	TYPE RAT-FrequencyPriorityInformation			PRESENCE optional	}|
+	{ ID id-RRCContainer							CRITICALITY ignore	TYPE RRCContainer									PRESENCE optional	}|
+	{ ID id-MaskedIMEISV							CRITICALITY ignore	TYPE MaskedIMEISV									PRESENCE optional	},
+	...
+} 
+
+Candidate-SpCell-List::= SEQUENCE (SIZE(1..maxnoofCandidateSpCells)) OF ProtocolIE-SingleContainer { { Candidate-SpCell-ItemIEs} }
+SCell-ToBeSetup-List::= SEQUENCE (SIZE(1..maxnoofSCells)) OF ProtocolIE-SingleContainer { { SCell-ToBeSetup-ItemIEs} }
+SRBs-ToBeSetup-List ::= SEQUENCE (SIZE(1..maxnoofSRBs)) OF ProtocolIE-SingleContainer { { SRBs-ToBeSetup-ItemIEs} }
+DRBs-ToBeSetup-List ::= SEQUENCE (SIZE(1..maxnoofDRBs)) OF ProtocolIE-SingleContainer { { DRBs-ToBeSetup-ItemIEs} }
+
+
+Candidate-SpCell-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-Candidate-SpCell-Item					CRITICALITY ignore	TYPE Candidate-SpCell-Item						PRESENCE mandatory	},
+	...
+}
+
+
+SCell-ToBeSetup-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-SCell-ToBeSetup-Item						CRITICALITY ignore	TYPE SCell-ToBeSetup-Item					PRESENCE mandatory	},
+	...
+}
+
+SRBs-ToBeSetup-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-SRBs-ToBeSetup-Item		CRITICALITY reject		TYPE SRBs-ToBeSetup-Item		PRESENCE mandatory},
+	...
+}
+
+DRBs-ToBeSetup-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-DRBs-ToBeSetup-Item					CRITICALITY reject	TYPE DRBs-ToBeSetup-Item					PRESENCE mandatory},
+	...
+}
+
+
+
+-- **************************************************************
+--
+-- UE CONTEXT SETUP RESPONSE
+--
+-- **************************************************************
+
+UEContextSetupResponse ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       { { UEContextSetupResponseIEs} },
+	...
+}
+
+
+UEContextSetupResponseIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-gNB-CU-UE-F1AP-ID						CRITICALITY reject	TYPE GNB-CU-UE-F1AP-ID								PRESENCE mandatory	}|
+	{ ID id-gNB-DU-UE-F1AP-ID						CRITICALITY reject	TYPE GNB-DU-UE-F1AP-ID								PRESENCE mandatory	}|
+	{ ID id-DUtoCURRCInformation					CRITICALITY reject	TYPE DUtoCURRCInformation							PRESENCE mandatory }|
+	{ ID id-C-RNTI									CRITICALITY ignore	TYPE C-RNTI											PRESENCE optional	}|
+	{ ID id-ResourceCoordinationTransferContainer	CRITICALITY ignore	TYPE ResourceCoordinationTransferContainer	PRESENCE optional	}|
+	{ ID id-FullConfiguration						CRITICALITY reject	TYPE FullConfiguration								PRESENCE optional	}|
+	{ ID id-DRBs-Setup-List							CRITICALITY ignore	TYPE DRBs-Setup-List								PRESENCE optional	}|
+	{ ID id-SRBs-FailedToBeSetup-List				CRITICALITY ignore	TYPE SRBs-FailedToBeSetup-List					PRESENCE optional	}|
+	{ ID id-DRBs-FailedToBeSetup-List				CRITICALITY ignore	TYPE DRBs-FailedToBeSetup-List					PRESENCE optional	}|
+	{ ID id-SCell-FailedtoSetup-List				CRITICALITY ignore	TYPE SCell-FailedtoSetup-List					PRESENCE optional	}|
+	{ ID id-InactivityMonitoringResponse			CRITICALITY reject	TYPE InactivityMonitoringResponse				PRESENCE optional	}|
+	{ ID id-CriticalityDiagnostics					CRITICALITY ignore	TYPE CriticalityDiagnostics						PRESENCE optional	},
+	...
+}
+
+DRBs-Setup-List ::= SEQUENCE (SIZE(1..maxnoofDRBs)) OF ProtocolIE-SingleContainer { { DRBs-Setup-ItemIEs} }
+SRBs-FailedToBeSetup-List ::= SEQUENCE (SIZE(1..maxnoofSRBs)) OF ProtocolIE-SingleContainer { { SRBs-FailedToBeSetup-ItemIEs} }
+DRBs-FailedToBeSetup-List ::= SEQUENCE (SIZE(1..maxnoofDRBs)) OF ProtocolIE-SingleContainer { { DRBs-FailedToBeSetup-ItemIEs} }
+SCell-FailedtoSetup-List ::= SEQUENCE (SIZE(1..maxnoofSCells)) OF ProtocolIE-SingleContainer { { SCell-FailedtoSetup-ItemIEs} }
+
+DRBs-Setup-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-DRBs-Setup-Item						CRITICALITY ignore	TYPE DRBs-Setup-Item						PRESENCE mandatory},
+	...
+}
+
+SRBs-FailedToBeSetup-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-SRBs-FailedToBeSetup-Item		CRITICALITY ignore		TYPE SRBs-FailedToBeSetup-Item		PRESENCE mandatory},
+	...
+}
+
+
+DRBs-FailedToBeSetup-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-DRBs-FailedToBeSetup-Item		CRITICALITY ignore	TYPE DRBs-FailedToBeSetup-Item			PRESENCE mandatory},
+	...
+}
+
+SCell-FailedtoSetup-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-SCell-FailedtoSetup-Item			CRITICALITY ignore	TYPE SCell-FailedtoSetup-Item			PRESENCE mandatory},
+	...
+}
+
+-- **************************************************************
+--
+-- UE CONTEXT SETUP FAILURE
+--
+-- **************************************************************
+
+UEContextSetupFailure ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       { { UEContextSetupFailureIEs} },
+	...
+}
+
+UEContextSetupFailureIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-gNB-CU-UE-F1AP-ID			CRITICALITY reject	TYPE GNB-CU-UE-F1AP-ID			PRESENCE mandatory	}|
+	{ ID id-gNB-DU-UE-F1AP-ID			CRITICALITY ignore	TYPE GNB-DU-UE-F1AP-ID			PRESENCE optional	}|
+	{ ID id-Cause						CRITICALITY ignore	TYPE Cause						PRESENCE mandatory	}|
+	{ ID id-CriticalityDiagnostics		CRITICALITY ignore	TYPE CriticalityDiagnostics		PRESENCE optional	}|
+	{ ID id-Potential-SpCell-List		CRITICALITY ignore	TYPE Potential-SpCell-List		PRESENCE optional	},
+	...
+}
+
+Potential-SpCell-List::= SEQUENCE (SIZE(0..maxnoofPotentialSpCells)) OF ProtocolIE-SingleContainer { { Potential-SpCell-ItemIEs} }
+
+Potential-SpCell-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-Potential-SpCell-Item				CRITICALITY ignore	TYPE Potential-SpCell-Item					PRESENCE mandatory	},
+	...
+}
+
+-- **************************************************************
+--
+-- UE Context Release Request ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- UE Context Release Request
+--
+-- **************************************************************
+
+UEContextReleaseRequest ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       {{ UEContextReleaseRequestIEs}},
+	...
+}
+
+UEContextReleaseRequestIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-gNB-CU-UE-F1AP-ID				CRITICALITY reject	TYPE GNB-CU-UE-F1AP-ID				PRESENCE mandatory	}|
+	{ ID id-gNB-DU-UE-F1AP-ID				CRITICALITY reject	TYPE GNB-DU-UE-F1AP-ID				PRESENCE mandatory	}|
+	{ ID id-Cause							CRITICALITY ignore	TYPE Cause							PRESENCE mandatory	},
+	...
+}
+
+
+-- **************************************************************
+--
+-- UE Context Release (gNB-CU initiated) ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- UE CONTEXT RELEASE COMMAND 
+--
+-- **************************************************************
+
+UEContextReleaseCommand ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       { { UEContextReleaseCommandIEs} },
+	...
+}
+
+UEContextReleaseCommandIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-gNB-CU-UE-F1AP-ID				CRITICALITY reject	TYPE GNB-CU-UE-F1AP-ID				PRESENCE mandatory	}|
+	{ ID id-gNB-DU-UE-F1AP-ID				CRITICALITY reject	TYPE GNB-DU-UE-F1AP-ID				PRESENCE mandatory	}|
+	{ ID id-Cause							CRITICALITY ignore	TYPE Cause							PRESENCE mandatory	}|
+	{ ID id-RRCContainer						CRITICALITY ignore	TYPE RRCContainer					PRESENCE optional	},
+	...
+} 
+
+-- **************************************************************
+--
+-- UE CONTEXT RELEASE COMPLETE
+--
+-- **************************************************************
+
+UEContextReleaseComplete ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       { { UEContextReleaseCompleteIEs} },
+	...
+}
+
+
+UEContextReleaseCompleteIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-gNB-CU-UE-F1AP-ID			CRITICALITY reject	TYPE GNB-CU-UE-F1AP-ID			PRESENCE mandatory	}|
+	{ ID id-gNB-DU-UE-F1AP-ID			CRITICALITY reject	TYPE GNB-DU-UE-F1AP-ID			PRESENCE mandatory	}|
+	{ ID id-CriticalityDiagnostics		CRITICALITY ignore	TYPE CriticalityDiagnostics		PRESENCE optional	},	...
+}
+
+-- **************************************************************
+--
+-- UE Context Modification ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- UE CONTEXT MODIFICATION REQUEST
+--
+-- **************************************************************
+
+UEContextModificationRequest ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       { { UEContextModificationRequestIEs} },
+	...
+}
+
+UEContextModificationRequestIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-gNB-CU-UE-F1AP-ID						CRITICALITY reject	TYPE GNB-CU-UE-F1AP-ID								PRESENCE mandatory	}|
+	{ ID id-gNB-DU-UE-F1AP-ID						CRITICALITY reject	TYPE GNB-DU-UE-F1AP-ID								PRESENCE mandatory	}|
+	{ ID id-SpCell-ID								CRITICALITY ignore	TYPE NRCGI											PRESENCE optional	}|
+	{ ID id-ServCellndex							CRITICALITY reject	TYPE ServCellIndex									PRESENCE mandatory	}|
+	{ ID id-SpCellULConfigured						CRITICALITY ignore	TYPE CellULConfigured								PRESENCE optional	}|
+	{ ID id-DRXCycle								CRITICALITY ignore	TYPE DRXCycle										PRESENCE optional	}|
+	{ ID id-CUtoDURRCInformation					CRITICALITY reject	TYPE CUtoDURRCInformation							PRESENCE optional	}|
+	{ ID id-TransmissionStopIndicator				CRITICALITY ignore	TYPE TransmissionStopIndicator					PRESENCE optional	}|
+	{ ID id-ResourceCoordinationTransferContainer	CRITICALITY ignore	TYPE ResourceCoordinationTransferContainer	PRESENCE optional	}|
+	{ ID id-RRCRconfigurationCompleteIndicator		CRITICALITY ignore	TYPE RRCRconfigurationCompleteIndicator		PRESENCE optional	}|
+	{ ID id-RRCContainer							CRITICALITY reject	TYPE RRCContainer									PRESENCE optional	}|
+	{ ID id-SCell-ToBeSetupMod-List					CRITICALITY ignore	TYPE SCell-ToBeSetupMod-List						PRESENCE optional	}|
+	{ ID id-SCell-ToBeRemoved-List					CRITICALITY ignore	TYPE SCell-ToBeRemoved-List 						PRESENCE optional }|
+	{ ID id-SRBs-ToBeSetupMod-List					CRITICALITY reject	TYPE SRBs-ToBeSetupMod-List						PRESENCE optional	}|
+	{ ID id-DRBs-ToBeSetupMod-List					CRITICALITY reject	TYPE DRBs-ToBeSetupMod-List						PRESENCE optional	}|
+	{ ID id-DRBs-ToBeModified-List					CRITICALITY reject	TYPE DRBs-ToBeModified-List						PRESENCE optional	}|
+	{ ID id-SRBs-ToBeReleased-List					CRITICALITY reject	TYPE SRBs-ToBeReleased-List						PRESENCE optional	}|
+	{ ID id-DRBs-ToBeReleased-List					CRITICALITY reject	TYPE DRBs-ToBeReleased-List						PRESENCE optional	}|
+	{ ID id-InactivityMonitoringRequest				CRITICALITY reject	TYPE InactivityMonitoringRequest				PRESENCE optional	}|	
+	{ ID id-RAT-FrequencyPriorityInformation		CRITICALITY reject	TYPE RAT-FrequencyPriorityInformation				PRESENCE optional	},
+	...
+} 
+
+SCell-ToBeSetupMod-List::= SEQUENCE (SIZE(1..maxnoofSCells)) OF ProtocolIE-SingleContainer { { SCell-ToBeSetupMod-ItemIEs} }
+SCell-ToBeRemoved-List::= SEQUENCE (SIZE(1..maxnoofSCells)) OF ProtocolIE-SingleContainer { { SCell-ToBeRemoved-ItemIEs} }
+SRBs-ToBeSetupMod-List ::= SEQUENCE (SIZE(1..maxnoofSRBs)) OF ProtocolIE-SingleContainer { { SRBs-ToBeSetupMod-ItemIEs} }
+DRBs-ToBeSetupMod-List ::= SEQUENCE (SIZE(1..maxnoofDRBs)) OF ProtocolIE-SingleContainer { { DRBs-ToBeSetupMod-ItemIEs} }
+
+DRBs-ToBeModified-List ::= SEQUENCE (SIZE(1..maxnoofDRBs)) OF ProtocolIE-SingleContainer { { DRBs-ToBeModified-ItemIEs} }
+SRBs-ToBeReleased-List ::= SEQUENCE (SIZE(1..maxnoofSRBs)) OF ProtocolIE-SingleContainer { { SRBs-ToBeReleased-ItemIEs} }
+DRBs-ToBeReleased-List ::= SEQUENCE (SIZE(1..maxnoofDRBs)) OF ProtocolIE-SingleContainer { { DRBs-ToBeReleased-ItemIEs} }
+
+SCell-ToBeSetupMod-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-SCell-ToBeSetupMod-Item			CRITICALITY ignore	TYPE SCell-ToBeSetupMod-Item			PRESENCE mandatory	},
+	...
+}
+
+SCell-ToBeRemoved-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-SCell-ToBeRemoved-Item			CRITICALITY ignore	TYPE SCell-ToBeRemoved-Item			PRESENCE mandatory	},
+	...
+}
+
+
+SRBs-ToBeSetupMod-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-SRBs-ToBeSetupMod-Item		CRITICALITY reject	TYPE SRBs-ToBeSetupMod-Item		PRESENCE mandatory},
+	...
+}
+
+
+DRBs-ToBeSetupMod-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-DRBs-ToBeSetupMod-Item		CRITICALITY reject	TYPE DRBs-ToBeSetupMod-Item		PRESENCE mandatory},
+	...
+}
+
+DRBs-ToBeModified-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-DRBs-ToBeModified-Item		CRITICALITY reject	TYPE DRBs-ToBeModified-Item			PRESENCE mandatory},
+	...
+}
+
+
+SRBs-ToBeReleased-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-SRBs-ToBeReleased-Item	CRITICALITY reject	TYPE SRBs-ToBeReleased-Item		PRESENCE mandatory},
+	...
+}
+
+DRBs-ToBeReleased-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-DRBs-ToBeReleased-Item		CRITICALITY reject	TYPE DRBs-ToBeReleased-Item		PRESENCE mandatory},
+	...
+}
+
+-- **************************************************************
+--
+-- UE CONTEXT MODIFICATION RESPONSE
+--
+-- **************************************************************
+
+UEContextModificationResponse ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       { { UEContextModificationResponseIEs} },
+	...
+}
+
+
+UEContextModificationResponseIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-gNB-CU-UE-F1AP-ID						CRITICALITY reject	TYPE GNB-CU-UE-F1AP-ID								PRESENCE mandatory	}|
+	{ ID id-gNB-DU-UE-F1AP-ID						CRITICALITY reject	TYPE GNB-DU-UE-F1AP-ID								PRESENCE mandatory	}|
+	{ ID id-ResourceCoordinationTransferContainer	CRITICALITY ignore	TYPE ResourceCoordinationTransferContainer	PRESENCE optional	}|
+	{ ID id-DUtoCURRCInformation					CRITICALITY reject	TYPE DUtoCURRCInformation							PRESENCE optional}|
+	{ ID id-DRBs-SetupMod-List						CRITICALITY ignore	TYPE DRBs-SetupMod-List								PRESENCE optional}|
+	{ ID id-DRBs-Modified-List						CRITICALITY ignore	TYPE DRBs-Modified-List								PRESENCE optional}|
+	{ ID id-SRBs-FailedToBeSetupMod-List			CRITICALITY ignore	TYPE SRBs-FailedToBeSetupMod-List				PRESENCE optional	}|
+	{ ID id-DRBs-FailedToBeSetupMod-List			CRITICALITY ignore	TYPE DRBs-FailedToBeSetupMod-List				PRESENCE optional	}|
+	{ ID id-SCell-FailedtoSetupMod-List				CRITICALITY ignore	TYPE SCell-FailedtoSetupMod-List				PRESENCE optional	}|
+	{ ID id-DRBs-FailedToBeModified-List			CRITICALITY ignore	TYPE DRBs-FailedToBeModified-List				PRESENCE optional	}|
+	{ ID id-InactivityMonitoringResponse			CRITICALITY reject	TYPE InactivityMonitoringResponse				PRESENCE optional	}|
+	{ ID id-CriticalityDiagnostics					CRITICALITY ignore	TYPE CriticalityDiagnostics						PRESENCE optional	},
+	...
+}
+
+
+DRBs-SetupMod-List ::= SEQUENCE (SIZE(1..maxnoofDRBs)) OF ProtocolIE-SingleContainer { { DRBs-SetupMod-ItemIEs} }
+DRBs-Modified-List::= SEQUENCE (SIZE(1..maxnoofDRBs)) OF ProtocolIE-SingleContainer { { DRBs-Modified-ItemIEs } }
+DRBs-FailedToBeModified-List ::= SEQUENCE (SIZE(1..maxnoofDRBs)) OF ProtocolIE-SingleContainer { { DRBs-FailedToBeModified-ItemIEs} }
+SRBs-FailedToBeSetupMod-List ::= SEQUENCE (SIZE(1..maxnoofSRBs)) OF ProtocolIE-SingleContainer { { SRBs-FailedToBeSetupMod-ItemIEs} }
+DRBs-FailedToBeSetupMod-List ::= SEQUENCE (SIZE(1..maxnoofDRBs)) OF ProtocolIE-SingleContainer { { DRBs-FailedToBeSetupMod-ItemIEs} }
+SCell-FailedtoSetupMod-List ::= SEQUENCE (SIZE(1..maxnoofSCells)) OF ProtocolIE-SingleContainer { { SCell-FailedtoSetupMod-ItemIEs} }
+
+DRBs-SetupMod-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-DRBs-SetupMod-Item		CRITICALITY ignore		TYPE DRBs-SetupMod-Item		PRESENCE mandatory},
+	...
+}
+
+
+DRBs-Modified-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-DRBs-Modified-Item			CRITICALITY ignore	TYPE DRBs-Modified-Item		PRESENCE mandatory},
+	...
+}
+
+SRBs-FailedToBeSetupMod-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-SRBs-FailedToBeSetupMod-Item		CRITICALITY ignore	TYPE SRBs-FailedToBeSetupMod-Item		PRESENCE mandatory},
+	...
+}
+
+
+
+DRBs-FailedToBeSetupMod-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-DRBs-FailedToBeSetupMod-Item		CRITICALITY ignore	TYPE DRBs-FailedToBeSetupMod-Item		PRESENCE mandatory},
+	...
+}
+
+
+DRBs-FailedToBeModified-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-DRBs-FailedToBeModified-Item		CRITICALITY ignore	TYPE DRBs-FailedToBeModified-Item		PRESENCE mandatory},
+	...
+}
+
+SCell-FailedtoSetupMod-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-SCell-FailedtoSetupMod-Item			CRITICALITY ignore	TYPE SCell-FailedtoSetupMod-Item			PRESENCE mandatory},
+	...
+}
+
+-- **************************************************************
+--
+-- UE CONTEXT MODIFICATION FAILURE
+--
+-- **************************************************************
+
+UEContextModificationFailure ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       { { UEContextModificationFailureIEs} },
+	...
+}
+
+UEContextModificationFailureIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-gNB-CU-UE-F1AP-ID				CRITICALITY reject	TYPE GNB-CU-UE-F1AP-ID				PRESENCE mandatory	}|
+	{ ID id-gNB-DU-UE-F1AP-ID				CRITICALITY reject	TYPE GNB-DU-UE-F1AP-ID				PRESENCE mandatory	}|
+	{ ID id-Cause							CRITICALITY ignore	TYPE Cause							PRESENCE mandatory	}|
+	{ ID id-CriticalityDiagnostics			CRITICALITY ignore	TYPE CriticalityDiagnostics			PRESENCE optional	},
+	...
+}
+
+
+-- **************************************************************
+--
+-- UE Context Modification Required (gNB-DU initiated) ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- UE CONTEXT MODIFICATION REQUIRED
+--
+-- **************************************************************
+
+UEContextModificationRequired ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       { { UEContextModificationRequiredIEs} },
+	...
+}
+
+UEContextModificationRequiredIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-gNB-CU-UE-F1AP-ID							CRITICALITY reject	TYPE GNB-CU-UE-F1AP-ID								PRESENCE mandatory	}|
+	{ ID id-gNB-DU-UE-F1AP-ID							CRITICALITY reject	TYPE GNB-DU-UE-F1AP-ID								PRESENCE mandatory	}|
+	{ ID id-ResourceCoordinationTransferContainer		CRITICALITY ignore	TYPE ResourceCoordinationTransferContainer		PRESENCE optional	}|
+	{ ID id-DUtoCURRCInformation						CRITICALITY reject	TYPE DUtoCURRCInformation							PRESENCE optional}|
+	{ ID id-DRBs-Required-ToBeModified-List				CRITICALITY reject	TYPE DRBs-Required-ToBeModified-List				PRESENCE optional}|
+	{ ID id-SRBs-Required-ToBeReleased-List				CRITICALITY reject	TYPE SRBs-Required-ToBeReleased-List				PRESENCE optional}|
+	{ ID id-DRBs-Required-ToBeReleased-List				CRITICALITY reject	TYPE DRBs-Required-ToBeReleased-List				PRESENCE optional}|
+	{ ID id-Cause										CRITICALITY ignore	TYPE Cause												PRESENCE mandatory	},
+	...
+} 
+
+DRBs-Required-ToBeModified-List::= SEQUENCE (SIZE(1..maxnoofDRBs)) OF ProtocolIE-SingleContainer { { DRBs-Required-ToBeModified-ItemIEs } }
+DRBs-Required-ToBeReleased-List::= SEQUENCE (SIZE(1..maxnoofDRBs)) OF ProtocolIE-SingleContainer { { DRBs-Required-ToBeReleased-ItemIEs } }
+
+SRBs-Required-ToBeReleased-List::= SEQUENCE (SIZE(1..maxnoofSRBs)) OF ProtocolIE-SingleContainer { { SRBs-Required-ToBeReleased-ItemIEs } }
+
+DRBs-Required-ToBeModified-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-DRBs-Required-ToBeModified-Item			CRITICALITY reject	TYPE DRBs-Required-ToBeModified-Item		PRESENCE mandatory},
+	...
+}
+
+DRBs-Required-ToBeReleased-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-DRBs-Required-ToBeReleased-Item			CRITICALITY reject	TYPE DRBs-Required-ToBeReleased-Item		PRESENCE mandatory},
+	...
+}
+
+SRBs-Required-ToBeReleased-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-SRBs-Required-ToBeReleased-Item			CRITICALITY reject	TYPE SRBs-Required-ToBeReleased-Item			PRESENCE mandatory},
+	...
+}
+
+-- **************************************************************
+--
+-- UE CONTEXT MODIFICATION CONFIRM
+--
+-- **************************************************************
+
+UEContextModificationConfirm::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       { { UEContextModificationConfirmIEs} },
+	...
+}
+
+
+UEContextModificationConfirmIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-gNB-CU-UE-F1AP-ID							CRITICALITY reject	TYPE GNB-CU-UE-F1AP-ID								PRESENCE mandatory	}|
+	{ ID id-gNB-DU-UE-F1AP-ID							CRITICALITY reject	TYPE GNB-DU-UE-F1AP-ID								PRESENCE mandatory	}|
+	{ ID id-ResourceCoordinationTransferContainer		CRITICALITY ignore	TYPE ResourceCoordinationTransferContainer		PRESENCE optional	}|
+	{ ID id-DRBs-ModifiedConf-List						CRITICALITY ignore	TYPE DRBs-ModifiedConf-List							PRESENCE optional}|
+	{ ID id-RRCContainer								CRITICALITY ignore	TYPE RRCContainer										PRESENCE optional	}|
+	{ ID id-CriticalityDiagnostics						CRITICALITY ignore	TYPE CriticalityDiagnostics							PRESENCE optional	},
+	...
+}
+
+DRBs-ModifiedConf-List::= SEQUENCE (SIZE(1..maxnoofDRBs)) OF ProtocolIE-SingleContainer { { DRBs-ModifiedConf-ItemIEs } }
+
+DRBs-ModifiedConf-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-DRBs-ModifiedConf-Item		CRITICALITY ignore	TYPE DRBs-ModifiedConf-Item			PRESENCE mandatory},
+	...
+}
+
+
+
+-- ************************************************************** 
+-- 
+-- WRITE-REPLACE WARNING ELEMENTARY PROCEDURE 
+-- 
+-- ************************************************************** 
+
+-- ************************************************************** 
+-- 
+-- Write-Replace Warning Request 
+-- 
+-- ************************************************************** 
+
+WriteReplaceWarningRequest ::= SEQUENCE { 
+protocolIEs ProtocolIE-Container { {WriteReplaceWarningRequestIEs} }, 
+... 
+} 
+WriteReplaceWarningRequestIEs F1AP-PROTOCOL-IES ::= { 
+{ ID id-TransactionID						CRITICALITY reject	TYPE TransactionID								PRESENCE mandatory	}|
+{ ID id-PWSSystemInformation 				CRITICALITY reject	TYPE PWSSystemInformation 						PRESENCE mandatory }| 
+{ ID id-RepetitionPeriod 					CRITICALITY reject	TYPE RepetitionPeriod 							PRESENCE mandatory }| 
+{ ID id-NumberofBroadcastRequest 			CRITICALITY reject	TYPE NumberofBroadcastRequest 					PRESENCE mandatory }| 
+{ ID id-ConcurrentWarningMessageIndicator 	CRITICALITY reject	TYPE ConcurrentWarningMessageIndicator 		PRESENCE optional }| 
+{ ID id-Cells-To-Be-Broadcast-List			CRITICALITY reject	TYPE Cells-To-Be-Broadcast-List					PRESENCE optional	},
+... 
+}
+Cells-To-Be-Broadcast-List		::= SEQUENCE (SIZE(1.. maxCellingNBDU))	OF ProtocolIE-SingleContainer { { Cells-To-Be-Broadcast-List-ItemIEs } }
+
+Cells-To-Be-Broadcast-List-ItemIEs F1AP-PROTOCOL-IES	::= {
+	{ ID id-Cells-To-Be-Broadcast-Item		CRITICALITY reject	TYPE	Cells-To-Be-Broadcast-Item		PRESENCE mandatory	},
+	...
+}
+
+-- ************************************************************** 
+-- 
+-- Write-Replace Warning Response 
+-- 
+-- ************************************************************** 
+
+WriteReplaceWarningResponse ::= SEQUENCE { 
+protocolIEs ProtocolIE-Container { {WriteReplaceWarningResponseIEs} }, 
+... 
+} 
+WriteReplaceWarningResponseIEs F1AP-PROTOCOL-IES ::= { 
+{ ID id-TransactionID						CRITICALITY reject	TYPE TransactionID							PRESENCE mandatory	}|
+{ ID id-Cells-Broadcast-Completed-List		CRITICALITY reject	TYPE Cells-Broadcast-Completed-List		PRESENCE optional	}|
+{ ID id-CriticalityDiagnostics						CRITICALITY ignore	TYPE CriticalityDiagnostics							PRESENCE optional	},
+... 
+}
+Cells-Broadcast-Completed-List		::= SEQUENCE (SIZE(1.. maxCellingNBDU))	OF ProtocolIE-SingleContainer { { Cells-Broadcast-Completed-List-ItemIEs } }
+
+Cells-Broadcast-Completed-List-ItemIEs F1AP-PROTOCOL-IES	::= {
+	{ ID id-Cells-Broadcast-Completed-Item		CRITICALITY reject	TYPE	Cells-Broadcast-Completed-Item		PRESENCE mandatory	},
+	...
+}
+
+
+-- ************************************************************** 
+-- 
+-- PWS CANCEL ELEMENTARY PROCEDURE 
+-- 
+-- ************************************************************** 
+
+-- ************************************************************** 
+-- 
+-- PWS Cancel Request 
+-- 
+-- ************************************************************** 
+
+PWSCancelRequest ::= SEQUENCE { 
+protocolIEs ProtocolIE-Container { {PWSCancelRequestIEs} }, 
+... 
+} 
+PWSCancelRequestIEs F1AP-PROTOCOL-IES ::= { 
+{ ID id-TransactionID					CRITICALITY reject TYPE TransactionID					PRESENCE mandatory	}|
+{ ID id-NumberofBroadcastRequest 		CRITICALITY reject TYPE NumberofBroadcastRequest 		PRESENCE mandatory }| 
+{ ID id-Broadcast-To-Be-Cancelled-List	CRITICALITY reject TYPE Broadcast-To-Be-Cancelled-List	PRESENCE optional	}|
+{ ID id-Cancel-all-Warning-Messages-Indicator	CRITICALITY reject TYPE Cancel-all-Warning-Messages-Indicator	PRESENCE optional	}
+,
+... 
+}
+Broadcast-To-Be-Cancelled-List		::= SEQUENCE (SIZE(1.. maxCellingNBDU))	OF ProtocolIE-SingleContainer { { Broadcast-To-Be-Cancelled-List-ItemIEs } }
+
+Broadcast-To-Be-Cancelled-List-ItemIEs F1AP-PROTOCOL-IES	::= {
+	{ ID id-Broadcast-To-Be-Cancelled-Item		CRITICALITY reject	TYPE	Broadcast-To-Be-Cancelled-Item		PRESENCE mandatory	},
+	...
+}
+
+-- ************************************************************** 
+-- 
+-- PWS Cancel Response 
+-- 
+-- ************************************************************** 
+
+PWSCancelResponse ::= SEQUENCE { 
+	protocolIEs ProtocolIE-Container { {PWSCancelResponseIEs} }, 
+... 
+} 
+
+PWSCancelResponseIEs F1AP-PROTOCOL-IES ::= { 
+{ ID id-TransactionID					CRITICALITY reject	TYPE TransactionID					PRESENCE mandatory	}|
+{ ID id-Cells-Broadcast-Cancelled-List	CRITICALITY reject	TYPE Cells-Broadcast-Cancelled-List	PRESENCE optional	}|
+{ ID id-CriticalityDiagnostics						CRITICALITY ignore	TYPE CriticalityDiagnostics							PRESENCE optional	},
+... 
+}
+Cells-Broadcast-Cancelled-List		::= SEQUENCE (SIZE(1.. maxCellingNBDU))	OF ProtocolIE-SingleContainer { { Cells-Broadcast-Cancelled-List-ItemIEs } }
+
+Cells-Broadcast-Cancelled-List-ItemIEs F1AP-PROTOCOL-IES	::= {
+	{ ID id-Cells-Broadcast-Cancelled-Item		CRITICALITY reject	TYPE	Cells-Broadcast-Cancelled-Item		PRESENCE mandatory	},
+	...
+}
+
+-- **************************************************************
+--
+-- UE Inactivity Notification ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- UE Inactivity Notification
+--
+-- **************************************************************
+
+UEInactivityNotification ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       {{ UEInactivityNotificationIEs}},
+	...
+}
+
+UEInactivityNotificationIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-gNB-CU-UE-F1AP-ID							CRITICALITY reject	TYPE GNB-CU-UE-F1AP-ID							PRESENCE mandatory	}|
+	{ ID id-gNB-DU-UE-F1AP-ID							CRITICALITY reject	TYPE GNB-DU-UE-F1AP-ID							PRESENCE mandatory	}|
+	{ ID id-DRB-Activity-List							CRITICALITY reject	TYPE DRB-Activity-List							PRESENCE mandatory	}	,
+	...
+}
+
+DRB-Activity-List::= SEQUENCE (SIZE(1..maxnoofDRBs)) OF ProtocolIE-SingleContainer { { DRB-Activity-ItemIEs } }
+
+DRB-Activity-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-DRB-Activity-Item			CRITICALITY reject	TYPE DRB-Activity-Item		PRESENCE mandatory},
+	...
+}
+
+-- **************************************************************
+--
+-- Initial UL RRC Message Transfer ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- INITIAL UL RRC Message Transfer
+--
+-- **************************************************************
+
+InitialULRRCMessageTransfer ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       {{ InitialULRRCMessageTransferIEs}},
+	...
+}
+
+InitialULRRCMessageTransferIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-gNB-DU-UE-F1AP-ID		CRITICALITY reject	TYPE GNB-DU-UE-F1AP-ID			PRESENCE mandatory	}|
+	{ ID id-NRCGI					CRITICALITY reject	TYPE NRCGI						PRESENCE mandatory	}|
+	{ ID id-C-RNTI					CRITICALITY reject	TYPE C-RNTI						PRESENCE mandatory	}|
+	{ ID id-RRCContainer				CRITICALITY reject	TYPE RRCContainer				PRESENCE mandatory	}|
+	{ ID id-DUtoCURRCContainer		CRITICALITY reject	TYPE DUtoCURRCContainer			PRESENCE optional	},
+	...
+}
+
+
+-- **************************************************************
+--
+-- DL RRC Message Transfer ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- DL RRC Message Transfer
+--
+-- **************************************************************
+
+DLRRCMessageTransfer ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       {{ DLRRCMessageTransferIEs}},
+	...
+}
+
+DLRRCMessageTransferIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-gNB-CU-UE-F1AP-ID							CRITICALITY reject	TYPE GNB-CU-UE-F1AP-ID							PRESENCE mandatory	}|
+	{ ID id-gNB-DU-UE-F1AP-ID							CRITICALITY reject	TYPE GNB-DU-UE-F1AP-ID							PRESENCE mandatory	}|
+	{ ID id-oldgNB-DU-UE-F1AP-ID						CRITICALITY reject	TYPE GNB-DU-UE-F1AP-ID							PRESENCE optional	}|
+	{ ID id-SRBID										CRITICALITY reject	TYPE SRBID											PRESENCE mandatory	}|
+	{ ID id-ExecuteDuplication							CRITICALITY ignore	TYPE ExecuteDuplication							PRESENCE optional}|
+	{ ID id-RRCContainer								CRITICALITY reject	TYPE RRCContainer									PRESENCE mandatory	}|
+	{ ID id-RAT-FrequencyPriorityInformation			CRITICALITY reject	TYPE RAT-FrequencyPriorityInformation		PRESENCE optional	},
+	...
+}
+-- **************************************************************
+--
+-- UL RRC Message Transfer ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- UL RRC Message Transfer
+--
+-- **************************************************************
+
+ULRRCMessageTransfer ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       {{ ULRRCMessageTransferIEs}},
+	...
+}
+
+ULRRCMessageTransferIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-gNB-CU-UE-F1AP-ID				CRITICALITY reject	TYPE GNB-CU-UE-F1AP-ID				PRESENCE mandatory	}|
+	{ ID id-gNB-DU-UE-F1AP-ID				CRITICALITY reject	TYPE GNB-DU-UE-F1AP-ID				PRESENCE mandatory	}|
+	{ ID id-SRBID							CRITICALITY reject	TYPE SRBID							PRESENCE mandatory	}|
+	{ ID id-RRCContainer					CRITICALITY reject	TYPE RRCContainer					PRESENCE mandatory	},
+	...
+}
+
+-- **************************************************************
+--
+-- PRIVATE MESSAGE
+--
+-- **************************************************************
+
+PrivateMessage ::= SEQUENCE {
+	privateIEs		PrivateIE-Container	{{PrivateMessage-IEs}},
+	...
+}
+
+PrivateMessage-IEs F1AP-PRIVATE-IES ::= {
+	...
+}
+
+
+-- **************************************************************
+--
+-- System Information ELEMENTARY PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- System information Delivery Command
+--
+-- **************************************************************
+
+SystemInformationDeliveryCommand ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       {{ SystemInformationDeliveryCommandIEs}},
+	...
+}
+
+SystemInformationDeliveryCommandIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-NRCGI				CRITICALITY reject	TYPE NRCGI					PRESENCE mandatory	}|
+	{ ID id-SIBtype-List			CRITICALITY reject	TYPE SIBtype-List				PRESENCE mandatory	}|
+	{ ID id-ConfirmedUEID 		CRITICALITY reject	TYPE GNB-DU-UE-F1AP-ID		PRESENCE mandatory	},
+	...
+}
+
+
+-- **************************************************************
+--
+-- Paging PROCEDURE
+--
+-- **************************************************************
+
+-- **************************************************************
+--
+-- Paging
+--
+-- **************************************************************
+
+Paging ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       {{ PagingIEs}},
+	...
+}
+
+PagingIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-UEIdentityIndexValue		CRITICALITY reject	TYPE UEIdentityIndexValue		PRESENCE mandatory	}|
+	{ ID id-PagingIdentity			CRITICALITY reject	TYPE PagingIdentity				PRESENCE optional	}|
+	{ ID id-PagingDRX				CRITICALITY ignore	TYPE PagingDRX					PRESENCE optional	}|
+	{ ID id-PagingPriority			CRITICALITY ignore	TYPE PagingPriority				PRESENCE optional	}|
+	{ ID id-PagingCell-List			CRITICALITY ignore	TYPE PagingCell-list				PRESENCE optional	},
+	...
+}
+
+PagingCell-list::= SEQUENCE (SIZE(1.. maxnoofPagingCells)) OF ProtocolIE-SingleContainer { { PagingCell-ItemIEs } }
+
+PagingCell-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-PagingCell-Item		CRITICALITY ignore	TYPE PagingCell-Item			PRESENCE mandatory}	,
+	...
+}
+
+
+
+-- **************************************************************
+--
+-- Notify
+--
+-- **************************************************************
+
+Notify ::= SEQUENCE {
+	protocolIEs			ProtocolIE-Container       {{ NotifyIEs}},
+	...
+}
+
+NotifyIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-gNB-CU-UE-F1AP-ID					CRITICALITY reject	TYPE GNB-CU-UE-F1AP-ID						PRESENCE mandatory	}|
+	{ ID id-gNB-DU-UE-F1AP-ID					CRITICALITY reject	TYPE GNB-DU-UE-F1AP-ID						PRESENCE mandatory	}|
+	{ ID id-DRB-Notify-List						CRITICALITY reject	TYPE DRB-Notify-List						PRESENCE mandatory	},
+	...
+}
+
+DRB-Notify-List::= SEQUENCE (SIZE(1)) OF ProtocolIE-SingleContainer { { DRB-Notify-ItemIEs } }
+
+DRB-Notify-ItemIEs F1AP-PROTOCOL-IES ::= {
+	{ ID id-DRB-Notify-Item			CRITICALITY reject	TYPE DRB-Notify-Item		PRESENCE mandatory},
+	...
+}
+
+
+
+-- ************************************************************** 
+-- 
+-- PWS RESTART INDICATION ELEMENTARY PROCEDURE 
+-- 
+-- ************************************************************** 
+
+-- ************************************************************** 
+-- 
+-- PWS Restart Indication 
+-- 
+-- ************************************************************** 
+
+PWSRestartIndication ::= SEQUENCE { 
+protocolIEs ProtocolIE-Container { { PWSRestartIndicationIEs} }, 
+... 
+} 
+PWSRestartIndicationIEs F1AP-PROTOCOL-IES ::= { 
+{ ID id-NR-CGI-List-For-Restart-List	CRITICALITY reject	TYPE	 NR-CGI-List-For-Restart-List	PRESENCE optional	},
+... 
+}
+NR-CGI-List-For-Restart-List		::= SEQUENCE (SIZE(1.. maxCellingNBDU))	OF ProtocolIE-SingleContainer { { NR-CGI-List-For-Restart-List-ItemIEs } }
+
+NR-CGI-List-For-Restart-List-ItemIEs F1AP-PROTOCOL-IES	::= {
+	{ ID id-NR-CGI-List-For-Restart-Item		CRITICALITY reject	TYPE	NR-CGI-List-For-Restart-Item		PRESENCE mandatory	},
+	...
+}
+
+-- ************************************************************** 
+-- 
+-- PWS FAILURE INDICATION ELEMENTARY PROCEDURE 
+-- 
+-- ************************************************************** 
+
+-- ************************************************************** 
+-- 
+-- PWS Failure Indication 
+-- 
+-- ************************************************************** 
+
+PWSFailureIndication ::= SEQUENCE { 
+protocolIEs ProtocolIE-Container { { PWSFailureIndicationIEs} }, 
+... 
+} 
+PWSFailureIndicationIEs F1AP-PROTOCOL-IES ::= { 
+{ ID id-PWS-Failed-NR-CGI-List	CRITICALITY reject	TYPE	 PWS-Failed-NR-CGI-List	PRESENCE optional	},
+... 
+}
+PWS-Failed-NR-CGI-List		::= SEQUENCE (SIZE(1.. maxCellingNBDU))	OF ProtocolIE-SingleContainer { { PWS-Failed-NR-CGI-List-ItemIEs } }
+
+PWS-Failed-NR-CGI-List-ItemIEs F1AP-PROTOCOL-IES	::= {
+	{ ID id-PWS-Failed-NR-CGI-Item		CRITICALITY reject	TYPE	PWS-Failed-NR-CGI-Item		PRESENCE mandatory	},
+	...
+}
+
+END
diff --git a/openair2/F1AP/MESSAGES/ASN1/R15.2.1/F1AP-PDU-Descriptions.asn b/openair2/F1AP/MESSAGES/ASN1/R15.2.1/F1AP-PDU-Descriptions.asn
new file mode 100644
index 0000000000000000000000000000000000000000..6ca80a706cd012a00027d7b30f2c5042f96d7c31
--- /dev/null
+++ b/openair2/F1AP/MESSAGES/ASN1/R15.2.1/F1AP-PDU-Descriptions.asn
@@ -0,0 +1,353 @@
+-- **************************************************************
+--
+-- Elementary Procedure definitions
+--
+-- **************************************************************
+
+F1AP-PDU-Descriptions  { 
+itu-t (0) identified-organization (4) etsi (0) mobileDomain (0) 
+ngran-access (22) modules (3) f1ap (3) version1 (1) f1ap-PDU-Descriptions (0)}
+
+DEFINITIONS AUTOMATIC TAGS ::= 
+
+BEGIN
+
+-- **************************************************************
+--
+-- IE parameter types from other modules.
+--
+-- **************************************************************
+
+IMPORTS
+	Criticality,
+	ProcedureCode
+
+FROM F1AP-CommonDataTypes
+	Reset,
+	ResetAcknowledge,
+	F1SetupRequest,
+	F1SetupResponse,
+	F1SetupFailure, 
+	GNBDUConfigurationUpdate,
+	GNBDUConfigurationUpdateAcknowledge,
+	GNBDUConfigurationUpdateFailure,
+	GNBCUConfigurationUpdate,
+	GNBCUConfigurationUpdateAcknowledge,
+	GNBCUConfigurationUpdateFailure,
+	UEContextSetupRequest,
+	UEContextSetupResponse,
+	UEContextSetupFailure,
+	UEContextReleaseCommand,
+	UEContextReleaseComplete,
+	UEContextModificationRequest,
+	UEContextModificationResponse,
+	UEContextModificationFailure,
+	UEContextModificationRequired,
+	UEContextModificationConfirm,
+	ErrorIndication,
+	UEContextReleaseRequest,
+	DLRRCMessageTransfer,
+	ULRRCMessageTransfer,
+	GNBDUResourceCoordinationRequest,
+	GNBDUResourceCoordinationResponse,
+	PrivateMessage,
+	UEInactivityNotification,
+	InitialULRRCMessageTransfer,
+	SystemInformationDeliveryCommand,
+	Paging,
+	Notify,
+	WriteReplaceWarningRequest,
+	WriteReplaceWarningResponse,
+	PWSCancelRequest,
+	PWSCancelResponse,
+	PWSRestartIndication,
+	PWSFailureIndication
+
+FROM F1AP-PDU-Contents
+	id-Reset,
+	id-F1Setup,
+	id-gNBDUConfigurationUpdate,
+	id-gNBCUConfigurationUpdate,
+	id-UEContextSetup,
+	id-UEContextRelease,
+	id-UEContextModification,
+	id-UEContextModificationRequired,
+	id-ErrorIndication, 
+	id-UEContextReleaseRequest,
+	id-DLRRCMessageTransfer,
+	id-ULRRCMessageTransfer,
+	id-GNBDUResourceCoordination,
+	id-privateMessage,
+	id-UEInactivityNotification,
+	id-InitialULRRCMessageTransfer,
+	id-SystemInformationDeliveryCommand,
+	id-Paging,
+	id-Notify,
+	id-WriteReplaceWarning,
+	id-PWSCancel,
+	id-PWSRestartIndication,
+	id-PWSFailureIndication
+
+
+FROM F1AP-Constants;
+
+
+-- **************************************************************
+--
+-- Interface Elementary Procedure Class
+--
+-- **************************************************************
+
+F1AP-ELEMENTARY-PROCEDURE ::= CLASS {
+	&InitiatingMessage				,
+	&SuccessfulOutcome							OPTIONAL,
+	&UnsuccessfulOutcome						OPTIONAL,
+	&procedureCode				ProcedureCode 	UNIQUE,
+	&criticality				Criticality 	DEFAULT ignore
+}
+WITH SYNTAX {
+	INITIATING MESSAGE			&InitiatingMessage
+	[SUCCESSFUL OUTCOME			&SuccessfulOutcome]
+	[UNSUCCESSFUL OUTCOME		&UnsuccessfulOutcome]
+	PROCEDURE CODE				&procedureCode
+	[CRITICALITY				&criticality]
+}
+
+-- **************************************************************
+--
+-- Interface PDU Definition
+--
+-- **************************************************************
+
+F1AP-PDU ::= CHOICE {
+	initiatingMessage	InitiatingMessage,
+	successfulOutcome	SuccessfulOutcome,
+	unsuccessfulOutcome	UnsuccessfulOutcome,
+	...
+}
+
+InitiatingMessage ::= SEQUENCE {
+	procedureCode	F1AP-ELEMENTARY-PROCEDURE.&procedureCode		({F1AP-ELEMENTARY-PROCEDURES}),
+	criticality		F1AP-ELEMENTARY-PROCEDURE.&criticality			({F1AP-ELEMENTARY-PROCEDURES}{@procedureCode}),
+	value			F1AP-ELEMENTARY-PROCEDURE.&InitiatingMessage	({F1AP-ELEMENTARY-PROCEDURES}{@procedureCode})
+}
+
+SuccessfulOutcome ::= SEQUENCE {
+	procedureCode	F1AP-ELEMENTARY-PROCEDURE.&procedureCode		({F1AP-ELEMENTARY-PROCEDURES}),
+	criticality		F1AP-ELEMENTARY-PROCEDURE.&criticality			({F1AP-ELEMENTARY-PROCEDURES}{@procedureCode}),
+	value			F1AP-ELEMENTARY-PROCEDURE.&SuccessfulOutcome	({F1AP-ELEMENTARY-PROCEDURES}{@procedureCode})
+}
+
+UnsuccessfulOutcome ::= SEQUENCE {
+	procedureCode	F1AP-ELEMENTARY-PROCEDURE.&procedureCode		({F1AP-ELEMENTARY-PROCEDURES}),
+	criticality		F1AP-ELEMENTARY-PROCEDURE.&criticality			({F1AP-ELEMENTARY-PROCEDURES}{@procedureCode}),
+	value			F1AP-ELEMENTARY-PROCEDURE.&UnsuccessfulOutcome	({F1AP-ELEMENTARY-PROCEDURES}{@procedureCode})
+}
+
+-- **************************************************************
+--
+-- Interface Elementary Procedure List
+--
+-- **************************************************************
+
+F1AP-ELEMENTARY-PROCEDURES F1AP-ELEMENTARY-PROCEDURE ::= {
+	F1AP-ELEMENTARY-PROCEDURES-CLASS-1			|
+	F1AP-ELEMENTARY-PROCEDURES-CLASS-2,	
+	...
+}
+
+
+F1AP-ELEMENTARY-PROCEDURES-CLASS-1 F1AP-ELEMENTARY-PROCEDURE ::= {
+	reset							|
+	f1Setup							|
+	gNBDUConfigurationUpdate		|
+	gNBCUConfigurationUpdate		|
+	uEContextSetup					|
+	uEContextRelease				|
+	uEContextModification			|
+	uEContextModificationRequired	|
+	writeReplaceWarning			|
+	pWSCancel					|
+	gNBDUResourceCoordination		,
+	...}
+
+ F1AP-ELEMENTARY-PROCEDURES-CLASS-2 F1AP-ELEMENTARY-PROCEDURE ::= {	
+	errorIndication					|
+	uEContextReleaseRequest			|
+	dLRRCMessageTransfer			|
+	uLRRCMessageTransfer			|
+	uEInactivityNotification		|
+	privateMessage					|
+	initialULRRCMessageTransfer		|
+	systemInformationDelivery		|
+	paging							|
+	notify							|
+	pWSRestartIndication				|
+	pWSFailureIndication			,
+	...
+}
+-- **************************************************************
+--
+-- Interface Elementary Procedures
+--
+-- **************************************************************
+
+reset F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		Reset
+	SUCCESSFUL OUTCOME		ResetAcknowledge
+	PROCEDURE CODE			id-Reset
+	CRITICALITY				reject
+}
+
+f1Setup F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		F1SetupRequest
+	SUCCESSFUL OUTCOME		F1SetupResponse
+	UNSUCCESSFUL 			OUTCOME	F1SetupFailure
+	PROCEDURE CODE			id-F1Setup
+	CRITICALITY				reject
+}
+
+gNBDUConfigurationUpdate F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		GNBDUConfigurationUpdate
+	SUCCESSFUL OUTCOME		GNBDUConfigurationUpdateAcknowledge
+	UNSUCCESSFUL OUTCOME		GNBDUConfigurationUpdateFailure
+	PROCEDURE CODE			id-gNBDUConfigurationUpdate
+	CRITICALITY				reject
+}
+
+gNBCUConfigurationUpdate F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		GNBCUConfigurationUpdate
+	SUCCESSFUL OUTCOME		GNBCUConfigurationUpdateAcknowledge
+	UNSUCCESSFUL OUTCOME		GNBCUConfigurationUpdateFailure
+	PROCEDURE CODE			id-gNBCUConfigurationUpdate
+	CRITICALITY				reject
+}
+
+uEContextSetup F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		UEContextSetupRequest
+	SUCCESSFUL OUTCOME		UEContextSetupResponse
+	UNSUCCESSFUL OUTCOME		UEContextSetupFailure
+	PROCEDURE CODE			id-UEContextSetup
+	CRITICALITY				reject
+}
+
+uEContextRelease F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		UEContextReleaseCommand
+	SUCCESSFUL OUTCOME		UEContextReleaseComplete
+	PROCEDURE CODE			id-UEContextRelease
+	CRITICALITY				reject
+}
+
+uEContextModification F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		UEContextModificationRequest
+	SUCCESSFUL OUTCOME		UEContextModificationResponse
+	UNSUCCESSFUL OUTCOME		UEContextModificationFailure
+	PROCEDURE CODE			id-UEContextModification
+	CRITICALITY				reject
+}
+
+uEContextModificationRequired F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		UEContextModificationRequired
+	SUCCESSFUL OUTCOME		UEContextModificationConfirm
+	PROCEDURE CODE			id-UEContextModificationRequired
+	CRITICALITY				reject
+}
+
+writeReplaceWarning F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		WriteReplaceWarningRequest
+	SUCCESSFUL OUTCOME		WriteReplaceWarningResponse
+	PROCEDURE CODE			id-WriteReplaceWarning
+	CRITICALITY				reject
+}
+
+pWSCancel F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		PWSCancelRequest
+	SUCCESSFUL OUTCOME		PWSCancelResponse
+	PROCEDURE CODE			id-PWSCancel
+	CRITICALITY				reject
+}
+
+errorIndication F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		ErrorIndication
+	PROCEDURE CODE			id-ErrorIndication
+	CRITICALITY				ignore
+}
+
+uEContextReleaseRequest F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		UEContextReleaseRequest
+	PROCEDURE CODE			id-UEContextReleaseRequest
+	CRITICALITY				ignore
+}
+
+
+initialULRRCMessageTransfer F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		InitialULRRCMessageTransfer
+	PROCEDURE CODE			id-InitialULRRCMessageTransfer
+	CRITICALITY				ignore
+}
+
+dLRRCMessageTransfer F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		DLRRCMessageTransfer
+	PROCEDURE CODE			id-DLRRCMessageTransfer
+	CRITICALITY				ignore
+}
+
+uLRRCMessageTransfer F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		ULRRCMessageTransfer
+	PROCEDURE CODE			id-ULRRCMessageTransfer
+	CRITICALITY				ignore
+}
+
+
+uEInactivityNotification  F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		UEInactivityNotification
+	PROCEDURE CODE			id-UEInactivityNotification
+	CRITICALITY				ignore
+}
+
+gNBDUResourceCoordination F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		GNBDUResourceCoordinationRequest
+	SUCCESSFUL OUTCOME		GNBDUResourceCoordinationResponse
+	PROCEDURE CODE			id-GNBDUResourceCoordination
+	CRITICALITY				reject
+}
+
+privateMessage F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		PrivateMessage
+	PROCEDURE CODE			id-privateMessage
+	CRITICALITY				ignore
+}
+
+systemInformationDelivery F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		SystemInformationDeliveryCommand
+	PROCEDURE CODE			id-SystemInformationDeliveryCommand
+	CRITICALITY				ignore
+}
+
+
+paging F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		Paging
+	PROCEDURE CODE			id-Paging
+	CRITICALITY				ignore
+}
+
+notify F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		Notify
+	PROCEDURE CODE			id-Notify
+	CRITICALITY				ignore
+}
+
+pWSRestartIndication F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		PWSRestartIndication
+	PROCEDURE CODE			id-PWSRestartIndication
+	CRITICALITY				ignore
+}
+
+pWSFailureIndication F1AP-ELEMENTARY-PROCEDURE ::= {
+	INITIATING MESSAGE		PWSFailureIndication
+	PROCEDURE CODE			id-PWSFailureIndication
+	CRITICALITY				ignore
+}
+
+
+END
diff --git a/openair2/F1AP/MESSAGES/ASN1/asn1tostruct.py b/openair2/F1AP/MESSAGES/ASN1/asn1tostruct.py
new file mode 100644
index 0000000000000000000000000000000000000000..b5f019f486ed3a5dfe4103afeb9b07c59f31f43a
--- /dev/null
+++ b/openair2/F1AP/MESSAGES/ASN1/asn1tostruct.py
@@ -0,0 +1,697 @@
+import re, os, sys, string
+import datetime
+import getopt
+import getpass
+
+version = "1.0.2"
+
+lines = ""
+iesDefs = {}
+ieofielist = {}
+outdir = './'
+
+filenames = []
+verbosity = 0
+prefix = ""
+
+FAIL = '\033[91m'
+WARN = '\033[93m'
+ENDC = '\033[0m'
+
+fileprefix = ""
+fileprefix_first_upper = ""
+
+def printFail(string):
+    sys.stderr.write(FAIL + string + ENDC + "\n")
+
+def printWarning(string):
+    print WARN + string + ENDC
+
+def printDebug(string):
+    if verbosity > 0:
+        print string
+
+def outputHeaderToFile(f, filename):
+    now = datetime.datetime.now()
+    f.write("""/*
+ * 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
+ */
+
+""")
+    f.write("/*******************************************************************************\n")
+    f.write(" * This file had been created by asn1tostruct.py script v%s\n" % (version))
+    f.write(" * Please do not modify this file but regenerate it via script.\n")
+    f.write(" * Created on: %s by %s\n * from %s\n" % (str(now), getpass.getuser(), filenames))
+    f.write(" ******************************************************************************/\n")
+
+def lowerFirstCamelWord(word):
+    """ puts the first word in a CamelCase Word in lowercase.
+
+    I.e. CustomerID becomes customerID, XMLInfoTest becomes xmlInfoTest
+    """
+    newstr = ''
+    swapped = word.swapcase()
+    idx = 0
+
+    # if it's all-caps, return an all-lowered version
+    lowered = word.lower()
+
+    if swapped == lowered:
+        return lowered
+
+    for c in swapped:
+        if c in string.lowercase:
+            newstr += c
+            idx    += 1
+        else:
+            break
+    if idx < 2:
+        newstr += word[idx:]
+    else:
+        newstr = newstr[:-1]+ word[idx-1:]
+
+    return newstr
+
+def usage():
+    print "Python parser for asn1 v%s" % (version)
+    print "Usage: python asn1tostruct.py [options]"
+    print "Available options:"
+    print "-d        Enable script debug"
+    print "-f [file] Input file to parse"
+    print "-o [dir]  Output files to given directory"
+    print "-h        Print this help and return"
+
+try:
+    opts, args = getopt.getopt(sys.argv[1:], "df:ho:", ["debug", "file", "help", "outdir"])
+except getopt.GetoptError as err:
+    # print help information and exit:
+    usage()
+    sys.exit(2)
+
+for o, a in opts:
+    if o in ("-f", "--file"):
+        filenames.append(a)
+    if o in ("-d", "--debug"):
+        verbosity = 1
+    if o in ("-o", "--outdir"):
+        outdir = a
+        if outdir.rfind('/') != len(outdir):
+            outdir += '/'
+    if o in ("-h", "--help"):
+        usage()
+        sys.exit(2)
+
+for filename in filenames:
+    file = open(filename, 'r')
+    for line in file:
+        # Removing any comment
+        if line.find('--') >= 0:
+            line = line[:line.find('--')]
+        # Removing any carriage return
+        lines += re.sub('\r', '', line)
+
+    for m in re.findall(r'([a-zA-Z0-9-]+)\s*::=\s+SEQUENCE\s+\(\s*SIZE\s*\(\s*\d+\s*\.\.\s*[0-9a-zA-Z-]+\s*\)\s*\)\s*OF\s+[a-zA-Z-]+\s*\{\s*\{\s*([0-9a-zA-Z-]+)\s*\}\s*\}', lines, re.MULTILINE):
+        ieofielist[m[0]] = m[1]
+    for m in re.findall(r'([a-zA-Z0-9-]+)\s*::=\s+E-RAB-IE-ContainerList\s*\{\s*\{\s*([a-zA-Z0-9-]+)\s*\}\s*\}', lines, re.MULTILINE):
+        ieofielist[m[0]] = m[1]
+
+    for i in re.findall(r'([a-zA-Z0-9-]+)\s+([A-Z0-9-]+)\s*::=\s*\{\s+([\,\|\{\}\t\n\.{3}\ \-a-zA-Z0-9]+)\s+}\n?', lines, re.MULTILINE):
+        ies = []
+        maxLength = 0
+        # TODO: handle extensions
+        if i[1].find('EXTENSION') >= 0:
+            continue
+        if fileprefix == "":
+            fileprefix = i[1][:i[1].find('-')].lower()
+        for j in re.findall(r'\s*\{\s*([a-zA-Z0-9-\ \t]+)\s*\}\s*[\|,]*', i[2], re.MULTILINE):
+            for k in re.findall(r'ID\s*([a-zA-Z0-9\-]+)\s*CRITICALITY\s*([a-zA-Z0-9\-]+)\s+[A-Z]+\s+([a-zA-Z0-9\-]+)\s*PRESENCE\s*([a-zA-Z0-9\-]+)', j, re.MULTILINE):
+                printDebug("Got new ie for message " + i[0] + ": " + str(k))
+                if len(k[2]) > maxLength:
+                    maxLength = len(k[2])
+                ies.append(k)
+
+        if len(ies) > 0:
+            iesDefs[i[0]] = { "length": maxLength, "ies": ies }
+        else:
+            printWarning("Didn't find any information element for message: " + i[0])
+
+if len(iesDefs) == 0:
+    printFail("No Information Element parsed, exiting")
+    sys.exit(0)
+
+fileprefix_first_upper = fileprefix[0].upper() + fileprefix[1:]
+
+f = open(outdir + fileprefix + '_ies_defs.h', 'w')
+outputHeaderToFile(f, filename)
+f.write("#include \"%s_common.h\"\n\n" % (fileprefix))
+f.write("#ifndef %s_IES_DEFS_H_\n#define %s_IES_DEFS_H_\n\n" % (fileprefix.upper(), fileprefix.upper()))
+f.write("/* Define the version of script used to generate this file */\n")
+f.write("#define %s_SCRIPT_VERSION (%s)\n\n" % (fileprefix.upper(), re.sub('\.', '', version)))
+
+for key in iesDefs:
+
+    if key not in ieofielist.values():
+        continue
+
+    for (i, j) in ieofielist.items():
+        if j == key:
+            break
+
+    f.write("typedef struct %sIEs_s {\n" % (re.sub('-', '_', i)))
+    f.write("    A_SEQUENCE_OF(struct %s_s) %s;\n" % (re.sub('IEs', '', re.sub('-', '_', ieofielist[i])), lowerFirstCamelWord(re.sub('IEs', '', re.sub('-', '_', ieofielist[i])))))
+    f.write("} %sIEs_t;\n\n" % (re.sub('-', '_', i)))
+
+for key in iesDefs:
+    keyupperunderscore = re.sub('-', '_', key.upper())
+    keylowerunderscore = re.sub('-', '_', key.lower())
+    shift = 0
+
+    if len(iesDefs[key]["ies"]) == 0:
+        continue
+
+    # Presence mask
+    for ie in iesDefs[key]["ies"]:
+        ieupperunderscore = re.sub('-', '_', re.sub('id-', '', ie[0])).upper()
+
+        if ie[3] == "optional" or ie[3] == "conditional":
+            f.write("#define {0:<{pad}} {1}\n".format("%s_%s_PRESENT" % (keyupperunderscore, ieupperunderscore), "(1 << %d)" % shift,
+            pad=iesDefs[key]["length"] + len(keyupperunderscore) + 9))
+            shift += 1
+    if (shift > 0):
+        f.write("\n")
+
+    f.write("typedef struct %s_s {\n" % (re.sub('-', '_', key)))
+    if (shift > 0):
+        f.write("    {0:<{pad}} {1};\n".format("uint16_t", "presenceMask", pad=iesDefs[key]["length"] + 2))
+    for ie in iesDefs[key]["ies"]:
+        ieunderscore = re.sub('-', '_', ie[2])
+        iename = re.sub('id-', '', ie[0])
+        ienameunderscore = lowerFirstCamelWord(re.sub('-', '_', iename))
+        if ie[2] in ieofielist:
+            f.write("    %sIEs_t %s;" % (re.sub('-', '_', ie[2]), ienameunderscore))
+        else:
+            f.write("    {0:<{pad}} {1};".format("%s_t" % ieunderscore, ienameunderscore, pad=iesDefs[key]["length"] + 2))
+        if ie[3] == "optional":
+            f.write(" ///< Optional field")
+        elif ie[3] == "conditional":
+            f.write(" ///< Conditional field")
+        f.write("\n")
+
+    f.write("} %s_t;\n\n" % (re.sub('-', '_', key)))
+
+f.write("typedef struct %s_message_s {\n" % (fileprefix))
+f.write("    %s_ProcedureCode_t procedureCode;\n" % (fileprefix_first_upper))
+f.write("    %s_Criticality_t   criticality;\n" % (fileprefix_first_upper))
+f.write("    uint8_t            direction;\n")
+f.write("    union {\n")
+
+messageList = iesDefs.keys()
+messageList.sort()
+for message in messageList:
+    if message in ieofielist.values():
+        continue
+    if len(iesDefs[message]["ies"]) == 0:
+        continue
+    f.write("        %s_t %s;\n" % (re.sub('-', '_', message), lowerFirstCamelWord(re.sub('-', '_', message))))
+f.write("    } msg;\n")
+f.write("} %s_message;\n\n" % (fileprefix))
+
+for key in iesDefs:
+    if key in ieofielist.values():
+        continue
+    structName = re.sub('ies', '', key)
+    asn1cStruct = re.sub('-', '_', re.sub('IEs', '', re.sub('-IEs', '', key)))
+    asn1cStruct = re.sub('Item', 'List', asn1cStruct)
+    keylowerunderscore = re.sub('-', '_', key.lower())
+    firstlower = re.sub('Item', 'List', re.sub('enb', 'eNB', lowerFirstCamelWord(asn1cStruct)))
+    f.write("/** \\brief Decode function for %s ies.\n" % (key))
+    if len(iesDefs[key]["ies"]) != 0:
+        f.write(" * \\param %s Pointer to ASN1 structure in which data will be stored\n" % (lowerFirstCamelWord(re.sub('-', '_', key))))
+    f.write(" *  \\param any_p Pointer to the ANY value to decode.\n")
+    f.write(" **/\n")
+    f.write("int %s_decode_%s(\n" % (fileprefix, keylowerunderscore))
+
+    if len(iesDefs[key]["ies"]) != 0:
+        f.write("    %s_t *%s,\n" % (re.sub('-', '_', key), lowerFirstCamelWord(re.sub('-', '_', key))))
+    f.write("    ANY_t *any_p);\n\n")
+
+    if len(iesDefs[key]["ies"]) == 0:
+        continue
+
+    f.write("/** \\brief Encode function for %s ies.\n" % (key))
+    f.write(" *  \\param %s Pointer to the ASN1 structure.\n" % (firstlower))
+    f.write(" *  \\param %s Pointer to the IES structure.\n" % (lowerFirstCamelWord(re.sub('-', '_', key))))
+    f.write(" **/\n")
+    f.write("int %s_encode_%s(\n" % (fileprefix, re.sub('-', '_', structName.lower())))
+    f.write("    %s_t *%s,\n" % (asn1cStruct, firstlower))
+    f.write("    %s_t *%s);\n\n" % (re.sub('-', '_', key), lowerFirstCamelWord(re.sub('-', '_', key))))
+
+for key in iesDefs:
+    if key not in ieofielist.values():
+        continue
+    asn1cStruct = re.sub('-', '_', re.sub('IEs', '', key))
+    asn1cStruct = re.sub('Item', 'List', asn1cStruct)
+    firstlower = re.sub('Item', 'List', re.sub('enb', 'eNB', lowerFirstCamelWord(asn1cStruct)))
+    f.write("/** \\brief Encode function for %s ies.\n" % (key))
+    f.write(" *  \\param %s Pointer to the ASN1 structure.\n" % (firstlower))
+    f.write(" *  \\param %s Pointer to the IES structure.\n" % (lowerFirstCamelWord(re.sub('-', '_', key))))
+    f.write(" **/\n")
+    f.write("int %s_encode_%s(\n" % (fileprefix, firstlower.lower()))
+    f.write("    %s_t *%s,\n" % (asn1cStruct, firstlower))
+    f.write("    %sIEs_t *%sIEs);\n\n" % (asn1cStruct, firstlower))
+    f.write("/** \\brief Decode function for %s ies.\n" % (key))
+    f.write(" *  \\param any_p Pointer to the ANY value to decode.\n")
+    f.write(" *  \\param callback Callback function called when any_p is successfully decoded.\n")
+    f.write(" **/\n")
+    f.write("int %s_decode_%s(\n" % (fileprefix, firstlower.lower()))
+    f.write("    %sIEs_t *%sIEs,\n" % (asn1cStruct, firstlower))
+    f.write("    %s_t *%s);\n\n" % (asn1cStruct, lowerFirstCamelWord(asn1cStruct)))
+
+for key in iesDefs:
+    asn1cStruct = re.sub('-', '_', re.sub('IEs', '', key))
+    asn1cStruct = re.sub('Item', 'List', asn1cStruct)
+    firstlower = re.sub('Item', 'List', re.sub('enb', 'eNB', lowerFirstCamelWord(asn1cStruct)))
+
+    if key in ieofielist.values():
+        f.write("/** \\brief Display %s encapsulated IE using XER encoding.\n" % (asn1cStruct))
+        f.write(" *  \\param %s Pointer to the IES structure.\n" % (lowerFirstCamelWord(re.sub('-', '_', key))))
+        f.write(" *  \\param file File descriptor to write output.\n")
+        f.write(" **/\n")
+        f.write("asn_enc_rval_t %s_xer_print_%s(\n" % (fileprefix, re.sub('item', 'list', firstlower.lower())))
+        f.write("    asn_app_consume_bytes_f *cb,\n")
+        f.write("    void *app_key,\n")
+        f.write("    %sIEs_t *%sIEs);\n\n" % (re.sub('item', 'list', asn1cStruct), firstlower))
+    else:
+        f.write("/** \\brief Display %s message using XER encoding.\n" % (asn1cStruct))
+        f.write(" *  \\param message_p Pointer to root message.\n")
+        f.write(" *  \\param file File descriptor to write output.\n")
+        f.write(" **/\n")
+        f.write("asn_enc_rval_t %s_xer_print_%s(\n" % (fileprefix, firstlower.lower()))
+        f.write("    asn_app_consume_bytes_f *cb,\n")
+        f.write("    void *app_key,\n")
+        f.write("    %s_message *message_p);\n\n" % (fileprefix))
+
+f.write("int %s_xer__print2sp(const void *buffer, size_t size, void *app_key);\n\n" % (fileprefix.lower()))
+f.write("int %s_xer__print2fp(const void *buffer, size_t size, void *app_key);\n\n" % (fileprefix.lower()))
+f.write("extern size_t %s_string_total_size;\n\n" % (fileprefix.lower()))
+f.write("#endif /* %s_IES_DEFS_H_ */\n\n" % (fileprefix.upper()))
+
+#Generate Decode functions
+f = open(outdir + fileprefix + '_decoder.c', 'w')
+outputHeaderToFile(f, filename)
+f.write("#include \"%s_common.h\"\n#include \"%s_ies_defs.h\"\n\n" % (fileprefix, fileprefix))
+for key in iesDefs:
+    if key in ieofielist.values():
+        continue
+    structName = re.sub('ies', '', key)
+    asn1cStruct = re.sub('-', '_', re.sub('IEs', '', key))
+    if asn1cStruct.rfind('_') == len(asn1cStruct) - 1:
+        asn1cStruct = asn1cStruct[:-1]
+    asn1cStruct = re.sub('Item', 'List', asn1cStruct)
+    ielistname = re.sub('UE', 'ue', asn1cStruct)
+    ielistnamefirstlower = ielistname[:1].lower() + ielistname[1:]
+    asn1cStructfirstlower = asn1cStruct[:1].lower() + asn1cStruct[1:]
+    keyName = re.sub('-', '_', key)
+    keyupperunderscore = keyName.upper()
+    firstlower = re.sub('Item', 'List', re.sub('enb', 'eNB', lowerFirstCamelWord(asn1cStruct)))
+
+    iesaccess = ""
+    if key not in ieofielist.values():
+        iesaccess = "%s_ies." % (firstlower)
+
+    f.write("int %s_decode_%s(\n" % (fileprefix, re.sub('-', '_', structName.lower())))
+    if len(iesDefs[key]["ies"]) != 0:
+        f.write("    %s_t *%s,\n" % (re.sub('-', '_', key), lowerFirstCamelWord(re.sub('-', '_', key))))
+    f.write("    ANY_t *any_p) {\n\n")
+
+    f.write("    %s_t  %s;\n    %s_t *%s_p = &%s;\n" % (asn1cStruct, asn1cStructfirstlower, asn1cStruct, asn1cStructfirstlower, asn1cStructfirstlower))
+    f.write("    int i, decoded = 0;\n")
+    if len(iesDefs[key]["ies"]) != 0:
+        f.write("    int tempDecoded = 0;\n")
+
+    f.write("    assert(any_p != NULL);\n")
+    if len(iesDefs[key]["ies"]) != 0:
+        f.write("    assert(%s != NULL);\n\n" % (lowerFirstCamelWord(re.sub('-', '_', key))))
+
+    f.write("    %s_DEBUG(\"Decoding message %s (%%s:%%d)\\n\", __FILE__, __LINE__);\n\n" % (fileprefix.upper(), re.sub('-', '_', keyName)))
+    f.write("    ANY_to_type_aper(any_p, &asn_DEF_%s, (void**)&%s_p);\n\n" % (asn1cStruct, asn1cStructfirstlower))
+    f.write("    for (i = 0; i < %s_p->%slist.count; i++) {\n" % (asn1cStructfirstlower, iesaccess))
+    f.write("        %s_IE_t *ie_p;\n" % (fileprefix[0].upper() + fileprefix[1:]))
+    f.write("        ie_p = %s_p->%slist.array[i];\n" % (asn1cStructfirstlower, iesaccess))
+    f.write("        switch(ie_p->id) {\n")
+    for ie in iesDefs[key]["ies"]:
+        iename = re.sub('id-', '', ie[0])
+        ienameunderscore = lowerFirstCamelWord(re.sub('-', '_', iename))
+        ienameunderscorefirstlower = lowerFirstCamelWord(ienameunderscore)
+        ietypesubst = re.sub('-', '', ie[2])
+        ietypeunderscore = re.sub('-', '_', ie[2])
+        ieupperunderscore = re.sub('-', '_', re.sub('id-', '', ie[0])).upper()
+
+        if ie[3] == "optional":
+            f.write("            /* Optional field */\n")
+        elif ie[3] == "conditional":
+            f.write("            /* Conditional field */\n")
+        f.write("            case %s_ProtocolIE_ID_%s:\n" % (fileprefix_first_upper, re.sub('-', '_', ie[0])))
+        f.write("            {\n")
+        f.write("                %s_t *%s_p = NULL;\n" % (ietypeunderscore, lowerFirstCamelWord(ietypesubst)))
+        if ie[3] != "mandatory":
+            f.write("                %s->presenceMask |= %s_%s_PRESENT;\n" % (lowerFirstCamelWord(re.sub('-', '_', key)), keyupperunderscore, ieupperunderscore))
+        f.write("                tempDecoded = ANY_to_type_aper(&ie_p->value, &asn_DEF_%s, (void**)&%s_p);\n" % (ietypeunderscore, lowerFirstCamelWord(ietypesubst)))
+        f.write("                if (tempDecoded < 0 || %s_p == NULL) {\n" % (lowerFirstCamelWord(ietypesubst)))
+        f.write("                    %s_ERROR(\"Decoding of IE %s failed\\n\");\n" % (fileprefix.upper(), ienameunderscore))
+        f.write("                    if (%s_p)\n" % (lowerFirstCamelWord(ietypesubst)))
+        f.write("                        ASN_STRUCT_FREE(asn_DEF_%s, %s_p);\n" % (ietypeunderscore, lowerFirstCamelWord(ietypesubst)))
+        f.write("                    return -1;\n")
+        f.write("                }\n")
+        f.write("                decoded += tempDecoded;\n")
+        f.write("                if (asn1_xer_print)\n")
+        f.write("                    xer_fprint(stdout, &asn_DEF_%s, %s_p);\n" % (ietypeunderscore, lowerFirstCamelWord(ietypesubst)))
+        if ie[2] in ieofielist.keys():
+            f.write("                if (%s_decode_%s(&%s->%s, %s_p) < 0) {\n" % (fileprefix, ietypeunderscore.lower(), lowerFirstCamelWord(re.sub('-', '_', key)), ienameunderscore, lowerFirstCamelWord(ietypesubst)))
+            f.write("                    %s_ERROR(\"Decoding of encapsulated IE %s failed\\n\");\n" % (fileprefix.upper(), lowerFirstCamelWord(ietypesubst)))
+            f.write("                    ASN_STRUCT_FREE(asn_DEF_%s, %s_p);\n" % (ietypeunderscore, lowerFirstCamelWord(ietypesubst)))
+            f.write("                }\n")
+        else:
+            f.write("                memcpy(&%s->%s, %s_p, sizeof(%s_t));\n" % (lowerFirstCamelWord(re.sub('-', '_', key)), ienameunderscore, lowerFirstCamelWord(ietypesubst), ietypeunderscore))
+            #f.write("                ASN_STRUCT_FREE(asn_DEF_%s, %s_p);\n" % (ietypeunderscore, lowerFirstCamelWord(ietypesubst)))
+        f.write("            } break;\n")
+    f.write("            default:\n")
+    f.write("                %s_ERROR(\"Unknown protocol IE id (%%d) for message %s\\n\", (int)ie_p->id);\n" % (fileprefix.upper(), re.sub('-', '_', structName.lower())))
+    f.write("                return -1;\n")
+    f.write("        }\n")
+    f.write("    }\n")
+    f.write("    return decoded;\n")
+    f.write("}\n\n")
+
+for key in iesDefs:
+    if key not in ieofielist.values():
+        continue
+
+    keyname = re.sub('IEs', '', re.sub('Item', 'List', key))
+
+    f.write("int %s_decode_%s(\n" % (fileprefix, re.sub('-', '_', keyname).lower()))
+    f.write("    %sIEs_t *%sIEs,\n" % (re.sub('-', '_', keyname), lowerFirstCamelWord(re.sub('-', '_', keyname))))
+    f.write("    %s_t *%s) {\n\n" % (re.sub('-', '_', keyname), lowerFirstCamelWord(re.sub('-', '_', keyname))))
+    f.write("    int i, decoded = 0;\n")
+    f.write("    int tempDecoded = 0;\n\n")
+
+    f.write("    assert(%s != NULL);\n" % (lowerFirstCamelWord(re.sub('-', '_', keyname))));
+    f.write("    assert(%sIEs != NULL);\n\n" % (lowerFirstCamelWord(re.sub('-', '_', keyname))));
+
+    f.write("    for (i = 0; i < %s->list.count; i++) {\n" % (lowerFirstCamelWord(re.sub('-', '_', keyname))))
+    f.write("        %s_IE_t *ie_p = %s->list.array[i];\n" % (fileprefix[0].upper() + fileprefix[1:], lowerFirstCamelWord(re.sub('-', '_', keyname))))
+    f.write("        switch (ie_p->id) {\n")
+    for ie in iesDefs[key]["ies"]:
+        iename = re.sub('id-', '', ie[0])
+        ienameunderscore = lowerFirstCamelWord(re.sub('-', '_', iename))
+        f.write("            case %s_ProtocolIE_ID_%s:\n" % (fileprefix_first_upper, re.sub('-', '_', ie[0])))
+        f.write("            {\n")
+        f.write("                %s_t *%s_p = NULL;\n" % (re.sub('-', '_', ie[2]), lowerFirstCamelWord(re.sub('-', '', ie[2]))))
+        f.write("                tempDecoded = ANY_to_type_aper(&ie_p->value, &asn_DEF_%s, (void**)&%s_p);\n" % (re.sub('-', '_', ie[2]), lowerFirstCamelWord(re.sub('-', '', ie[2]))))
+        f.write("                if (tempDecoded < 0 || %s_p == NULL) {\n" % (lowerFirstCamelWord(re.sub('-', '', ie[2]))))
+        f.write("                    %s_ERROR(\"Decoding of IE %s for message %s failed\\n\");\n" % (fileprefix.upper(), ienameunderscore, re.sub('-', '_', keyname)))
+        f.write("                    if (%s_p)\n" % (lowerFirstCamelWord(re.sub('-', '', ie[2]))))
+        #f.write("                        free(%s_p);\n" % (lowerFirstCamelWord(re.sub('-', '', ie[2]))))
+        f.write("                        ASN_STRUCT_FREE(asn_DEF_%s, %s_p);\n" % (re.sub('-', '_', ie[2]), lowerFirstCamelWord(re.sub('-', '', ie[2]))))
+        f.write("                    return -1;\n")
+        f.write("                }\n")
+        f.write("                decoded += tempDecoded;\n")
+        f.write("                if (asn1_xer_print)\n")
+        f.write("                    xer_fprint(stdout, &asn_DEF_%s, %s_p);\n" % (re.sub('-', '_', ie[2]), lowerFirstCamelWord(re.sub('-', '', ie[2]))))
+        f.write("                ASN_SEQUENCE_ADD(&%sIEs->%s, %s_p);\n" % (lowerFirstCamelWord(re.sub('-', '_', keyname)),
+        re.sub('IEs', '', lowerFirstCamelWord(re.sub('-', '_', key))), lowerFirstCamelWord(re.sub('-', '', ie[2]))))
+        f.write("            } break;\n")
+    f.write("            default:\n")
+    f.write("                %s_ERROR(\"Unknown protocol IE id (%%d) for message %s\\n\", (int)ie_p->id);\n" % (fileprefix.upper(), re.sub('-', '_', structName.lower())))
+    f.write("                return -1;\n")
+    f.write("        }\n")
+    f.write("    }\n")
+    f.write("    return decoded;\n")
+    f.write("}\n\n")
+
+
+#Generate IES Encode functions
+f = open(outdir + fileprefix + '_encoder.c', 'w')
+outputHeaderToFile(f,filename)
+f.write("#include \"%s_common.h\"\n" % (fileprefix))
+f.write("#include \"%s_ies_defs.h\"\n\n" % (fileprefix))
+for key in iesDefs:
+    if key in ieofielist.values():
+        continue
+
+    structName = re.sub('ies', '', key)
+    asn1cStruct = re.sub('-', '_', re.sub('IEs', '', key))
+    asn1cStruct = re.sub('Item', 'List', asn1cStruct)
+    if asn1cStruct.rfind('_') == len(asn1cStruct) - 1:
+        asn1cStruct = asn1cStruct[:-1]
+    asn1cStructfirstlower = asn1cStruct[:1].lower() + asn1cStruct[1:]
+    firstwordlower = re.sub('Item', 'List', re.sub('enb', 'eNB', lowerFirstCamelWord(asn1cStruct)))
+
+    iesaccess = ""
+    if key not in ieofielist.values():
+        iesaccess = "%s_ies." % (firstwordlower)
+
+    keyName = re.sub('-', '_', key)
+    keyupperunderscore = keyName.upper()
+    # No IE to encode...
+    if len(iesDefs[key]["ies"]) == 0:
+        continue
+
+    f.write("int %s_encode_%s(\n" % (fileprefix, re.sub('-', '_', structName.lower())))
+    f.write("    %s_t *%s,\n" % (asn1cStruct, firstwordlower))
+    f.write("    %s_t *%s) {\n\n" % (re.sub('-', '_', key), lowerFirstCamelWord(re.sub('-', '_', key))))
+
+    f.write("    %s_IE_t *ie;\n\n" % (fileprefix_first_upper))
+
+    f.write("    assert(%s != NULL);\n" % (firstwordlower));
+    f.write("    assert(%s != NULL);\n\n" % (lowerFirstCamelWord(re.sub('-', '_', key))));
+
+    for ie in iesDefs[key]["ies"]:
+        iename = re.sub('-', '_', re.sub('id-', '', ie[0]))
+        ienameunderscore = re.sub('-', '_', iename)
+        ienamefirstwordlower = lowerFirstCamelWord(iename)
+        ieupperunderscore = re.sub('-', '_', re.sub('id-', '', ie[0])).upper()
+        ietypeunderscore = re.sub('-', '_', ie[2])
+
+        if ie[3] != "mandatory":
+            if ie[3] == "optional":
+                f.write("    /* Optional field */\n")
+            elif ie[3] == "conditional":
+                f.write("    /* Conditional field */\n")
+            f.write("    if (%s->presenceMask & %s_%s_PRESENT) {\n" % (lowerFirstCamelWord(re.sub('-', '_', key)), keyupperunderscore, ieupperunderscore))
+            #f.write("        == %s_%s_PRESENT) {\n" % (keyupperunderscore, ieupperunderscore))
+            f.write("        if ((ie = %s_new_ie(%s_ProtocolIE_ID_%s,\n" % (fileprefix, fileprefix_first_upper, re.sub('-', '_', ie[0])))
+            f.write("                            %s_Criticality_%s,\n" % (fileprefix_first_upper, ie[1]))
+            f.write("                            &asn_DEF_%s,\n" % (ietypeunderscore))
+            f.write("                            &%s->%s)) == NULL) {\n" % (lowerFirstCamelWord(re.sub('-', '_', key)), ienamefirstwordlower))
+            f.write("            return -1;\n")
+            f.write("        }\n")
+            f.write("        ASN_SEQUENCE_ADD(&%s->%slist, ie);\n" % (firstwordlower, iesaccess))
+            f.write("    }\n\n")
+        else:
+            if ie[2] in ieofielist.keys():
+                f.write("    %s_t %s;\n\n" % (ietypeunderscore, ienamefirstwordlower))
+                f.write("    memset(&%s, 0, sizeof(%s_t));\n" % (ienamefirstwordlower, ietypeunderscore))
+                f.write("\n")
+                f.write("    if (%s_encode_%s(&%s, &%s->%s) < 0) return -1;\n" % (fileprefix, ietypeunderscore.lower(), ienamefirstwordlower, lowerFirstCamelWord(re.sub('-', '_', key)), ienamefirstwordlower))
+            f.write("    if ((ie = %s_new_ie(%s_ProtocolIE_ID_%s,\n" % (fileprefix, fileprefix_first_upper, re.sub('-', '_', ie[0])))
+            f.write("                        %s_Criticality_%s,\n" % (fileprefix_first_upper, ie[1]))
+            f.write("                        &asn_DEF_%s,\n" % (ietypeunderscore))
+            if ie[2] in ieofielist.keys():
+                f.write("                          &%s)) == NULL) {\n" % (ienamefirstwordlower))
+            else:
+                f.write("                          &%s->%s)) == NULL) {\n" % (lowerFirstCamelWord(re.sub('-', '_', key)), ienamefirstwordlower))
+            f.write("        return -1;\n")
+            f.write("    }\n")
+            f.write("    ASN_SEQUENCE_ADD(&%s->%slist, ie);\n\n" % (firstwordlower, iesaccess))
+            if ie[2] in ieofielist.keys():
+                f.write("    /* Free any dynamic allocation that is no more used */\n")
+                f.write("    ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_%s, &%s);\n\n" % (ietypeunderscore, ienamefirstwordlower))
+
+    f.write("    return 0;\n")
+    f.write("}\n\n")
+
+for (key, value) in iesDefs.items():
+    if key not in ieofielist.values():
+        continue
+
+    ie = value["ies"][0]
+    ietypeunderscore = re.sub('-', '_', ie[2])
+    asn1cStruct = re.sub('-', '_', re.sub('IEs', '', re.sub('-IEs', '', key)))
+    asn1cStruct = re.sub('Item', 'List', asn1cStruct)
+    firstwordlower = re.sub('Item', 'List', re.sub('enb', 'eNB', lowerFirstCamelWord(asn1cStruct)))
+
+    for (i, j) in ieofielist.items():
+        if j == key:
+            break
+    f.write("int %s_encode_%s(\n" % (fileprefix, re.sub('-', '_', i).lower()))
+    f.write("    %s_t *%s,\n" % (asn1cStruct, firstwordlower))
+    f.write("    %sIEs_t *%sIEs) {\n\n" % (re.sub('-', '_', i), lowerFirstCamelWord(re.sub('-', '_', i))))
+    f.write("    int i;\n")
+
+    f.write("    %s_IE_t *ie;\n\n" % (fileprefix_first_upper))
+
+    f.write("    assert(%s != NULL);\n" % (firstwordlower));
+    f.write("    assert(%sIEs != NULL);\n\n" % (lowerFirstCamelWord(re.sub('-', '_', i))));
+
+    f.write("    for (i = 0; i < %sIEs->%s.count; i++) {\n" % (firstwordlower, re.sub('IEs', '', lowerFirstCamelWord(re.sub('-', '_', key)))))
+    f.write("        if ((ie = %s_new_ie(%s_ProtocolIE_ID_%s,\n" % (fileprefix, fileprefix_first_upper, re.sub('-', '_', ie[0])))
+    f.write("                            %s_Criticality_%s,\n" % (fileprefix_first_upper, ie[1]))
+    f.write("                            &asn_DEF_%s,\n" % (ietypeunderscore))
+    f.write("                            %sIEs->%s.array[i])) == NULL) {\n" % (firstwordlower, re.sub('IEs', '', lowerFirstCamelWord(re.sub('-', '_', key)))))
+    f.write("            return -1;\n")
+    f.write("        }\n")
+    f.write("        ASN_SEQUENCE_ADD(&%s->list, ie);\n" % (firstwordlower))
+    f.write("    }\n")
+    f.write("    return 0;\n")
+    f.write("}\n\n")
+
+#Generate xer print functions
+f = open(outdir + fileprefix + '_xer_print.c', 'w')
+outputHeaderToFile(f, filename)
+f.write("#include <stdlib.h>\n")
+f.write("#include <stdio.h>\n\n")
+f.write("#include <asn_application.h>\n#include <asn_internal.h>\n\n")
+f.write("#include \"%s_common.h\"\n#include \"%s_ies_defs.h\"\n\n" % (fileprefix, fileprefix))
+
+f.write("size_t %s_string_total_size = 0;\n\n" % (fileprefix.lower()))
+f.write("""int
+%s_xer__print2fp(const void *buffer, size_t size, void *app_key) {
+    FILE *stream = (FILE *)app_key;
+
+    if(fwrite(buffer, 1, size, stream) != size)
+        return -1;
+
+    return 0;
+}
+
+""" % (fileprefix.lower()))
+
+f.write("""int %s_xer__print2sp(const void *buffer, size_t size, void *app_key) {
+    char *string = (char *)app_key;
+
+    /* Copy buffer to the formatted string */
+    memcpy(&string[%s_string_total_size], buffer, size);
+
+    %s_string_total_size += size;
+
+    return 0;
+}
+
+""" % (fileprefix.lower(), fileprefix.lower(), fileprefix.lower()))
+
+f.write("""static asn_enc_rval_t
+xer_encode_local(asn_TYPE_descriptor_t *td, void *sptr,
+        asn_app_consume_bytes_f *cb, void *app_key, int indent) {
+    asn_enc_rval_t er, tmper;
+    const char *mname;
+    size_t mlen;
+    int xcan = 2;
+
+    if(!td || !sptr) goto cb_failed;
+
+    mname = td->xml_tag;
+    mlen = strlen(mname);
+
+    _i_ASN_TEXT_INDENT(0, indent);
+    _ASN_CALLBACK3("<", 1, mname, mlen, ">", 1);
+
+    tmper = td->xer_encoder(td, sptr, indent + 1, XER_F_BASIC, cb, app_key);
+    if(tmper.encoded == -1) return tmper;
+
+    _ASN_CALLBACK3("</", 2, mname, mlen, ">\\n", xcan);
+
+    er.encoded = 4 + xcan + (2 * mlen) + tmper.encoded;
+
+    _ASN_ENCODED_OK(er);
+cb_failed:
+    _ASN_ENCODE_FAILED;
+}
+""")
+
+for (key, value) in iesDefs.items():
+    keyName = re.sub('-', '_', key)
+    keyupperunderscore = keyName.upper()
+    iesStructName = lowerFirstCamelWord(re.sub('-', '_', key))
+
+    ie = value["ies"][0]
+    ietypeunderscore = re.sub('-', '_', ie[2])
+
+    if key in ieofielist.values():
+        f.write("asn_enc_rval_t %s_xer_print_%s(\n" % (fileprefix, re.sub('ies', '', re.sub('item', 'list', re.sub('-', '_', key).lower()))))
+    else:
+        f.write("asn_enc_rval_t %s_xer_print_%s(\n" % (fileprefix, re.sub('ies', '', re.sub('-', '_', key).lower())))
+    #f.write("    FILE *file,\n")
+    f.write("    asn_app_consume_bytes_f *cb,\n")
+    f.write("    void *app_key,\n")
+    if key in ieofielist.values():
+        iesStructName = lowerFirstCamelWord(re.sub('Item', 'List', re.sub('-', '_', key)))
+        f.write("    %sIEs_t *%s) {\n\n" % (re.sub('IEs', '', re.sub('Item', 'List', re.sub('-', '_', key))), iesStructName))
+        f.write("    int i;\n")
+        f.write("    asn_enc_rval_t er;\n")
+    else:
+        f.write("    %s_message *message_p)\n{\n" % (fileprefix))
+        f.write("    %s_t *%s;\n" % (re.sub('-', '_', key), iesStructName))
+        f.write("    asn_enc_rval_t er;\n")
+        #f.write("    void *app_key = (void *)file;\n")
+        #f.write("    asn_app_consume_bytes_f *cb = %s_xer__print2fp;\n\n" % (fileprefix.lower()))
+
+        f.write("    %s = &message_p->msg.%s;\n\n" % (iesStructName, iesStructName))
+
+    if key in ieofielist.values():
+        # Increase indentation level
+        f.write("    for (i = 0; i < %s->%s.count; i++) {\n" % (iesStructName, re.sub('IEs', '', lowerFirstCamelWord(re.sub('-', '_', key)))))
+        #f.write("        xer_fprint(file, &asn_DEF_%s, %s->%s.array[i]);\n" % (ietypeunderscore, iesStructName, re.sub('IEs', '', lowerFirstCamelWord(re.sub('-', '_', key)))))
+        f.write("        er = xer_encode(&asn_DEF_%s, %s->%s.array[i], XER_F_BASIC, cb, app_key);\n" % (ietypeunderscore, iesStructName, re.sub('IEs', '', lowerFirstCamelWord(re.sub('-', '_', key)))))
+        f.write("    }\n")
+    else:
+        f.write("    cb(\"<%s-PDU>\\n\", %d, app_key);\n" % (key, len("<%s-PDU>\n" % (key))))
+        f.write("    xer_encode_local(&asn_DEF_%s_Criticality, &message_p->criticality, cb, app_key, 1);\n" % fileprefix_first_upper)
+        f.write("    xer_encode_local(&asn_DEF_%s_ProcedureCode, &message_p->procedureCode, cb, app_key, 1);\n" % fileprefix_first_upper)
+
+        f.write("    cb(\"    <%s>\\n\", %d, app_key);\n" % (key, len("    <%s>\n" % (key))))
+
+        for ie in iesDefs[key]["ies"]:
+            iename = re.sub('-', '_', re.sub('id-', '', ie[0]))
+            ienameunderscore = re.sub('-', '_', iename)
+            ienamefirstwordlower = lowerFirstCamelWord(iename)
+            ietypeunderscore = re.sub('-', '_', ie[2])
+            ieupperunderscore = re.sub('-', '_', re.sub('id-', '', ie[0])).upper()
+
+            if ie[3] != "mandatory":
+                if ie[3] == "optional":
+                    f.write("    /* Optional field */\n")
+                elif ie[3] == "conditional":
+                    f.write("    /* Conditional field */\n")
+                f.write("    if (%s->presenceMask & %s_%s_PRESENT)\n    " % (iesStructName, keyupperunderscore, ieupperunderscore))
+
+            # Is it an encapsulated IE ?
+            if ie[2] in ieofielist.keys():
+                f.write("    %s_xer_print_%s(cb, app_key, &%s->%s);\n" % (fileprefix, re.sub('ies', '', re.sub('-', '_', ie[2]).lower()), iesStructName, ienamefirstwordlower))
+            else:
+                f.write("    xer_encode_local(&asn_DEF_%s, &%s->%s, cb, app_key, 2);\n" % (ietypeunderscore, iesStructName, ienamefirstwordlower))
+        f.write("    cb(\"    </%s>\\n\", %d, app_key);\n" % (key, len("    </%s>\n" % (key))))
+        f.write("    cb(\"</%s-PDU>\\n\", %d, app_key);\n" % (key, len("</%s-PDU>\n" % (key))))
+
+    f.write("    _ASN_ENCODED_OK(er);\n")
+    #if key not in ieofielist.values():
+        #f.write("cb_failed:\n")
+        #f.write("    return er;\n")
+    f.write("}\n\n")
diff --git a/openair2/F1AP/f1ap_common.c b/openair2/F1AP/f1ap_common.c
new file mode 100644
index 0000000000000000000000000000000000000000..e9e69732beab8fcfc2a1a5670c30b5b05c19f58e
--- /dev/null
+++ b/openair2/F1AP/f1ap_common.c
@@ -0,0 +1,194 @@
+/*
+ * 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
+ */
+
+/*! \file f1ap_common.c
+ * \brief f1ap procedures for both CU and DU
+ * \author EURECOM/NTUST
+ * \date 2018
+ * \version 0.1
+ * \company Eurecom
+ * \email: navid.nikaein@eurecom.fr, bing-kai.hong@eurecom.fr
+ * \note
+ * \warning
+ */
+
+#include "f1ap_common.h"
+
+#if defined(EMIT_ASN_DEBUG_EXTERN)
+int asn_debug = 0;
+int asn1_xer_print = 0;
+
+inline void ASN_DEBUG(const char *fmt, ...)
+{
+  if (asn_debug) {
+    int adi = asn_debug_indent;
+    va_list ap;
+    va_start(ap, fmt);
+    fprintf(stderr, "[ASN1]");
+
+    while(adi--) fprintf(stderr, " ");
+
+    vfprintf(stderr, fmt, ap);
+    fprintf(stderr, "\n");
+    va_end(ap);
+  }
+}
+#endif
+
+uint8_t F1AP_get_next_transaction_identifier(module_id_t enb_mod_idP, module_id_t cu_mod_idP)
+{
+  static uint8_t transaction_identifier[NUMBER_OF_eNB_MAX];
+  transaction_identifier[enb_mod_idP+cu_mod_idP] =
+      (transaction_identifier[enb_mod_idP+cu_mod_idP] + 1) % F1AP_TRANSACTION_IDENTIFIER_NUMBER;
+  //LOG_T(F1AP,"generated xid is %d\n",transaction_identifier[enb_mod_idP+cu_mod_idP]);
+  return transaction_identifier[enb_mod_idP+cu_mod_idP];
+}
+
+int f1ap_add_ue(f1ap_cudu_inst_t    *f1_inst,
+                module_id_t          module_idP,
+                int                  CC_idP,
+                int                  UE_id,
+                rnti_t               rntiP) {
+  for (int i = 0; i < MAX_MOBILES_PER_ENB; i++) {
+    if (f1_inst->f1ap_ue[i].rnti == rntiP) {
+      f1_inst->f1ap_ue[i].f1ap_uid = i;
+      f1_inst->f1ap_ue[i].mac_uid = UE_id;
+      LOG_I(F1AP, "Updating the index of UE with RNTI %x and du_ue_f1ap_id %d\n", f1_inst->f1ap_ue[i].rnti, f1_inst->f1ap_ue[i].du_ue_f1ap_id);
+      return i;
+    }
+  }
+  for (int i = 0; i < MAX_MOBILES_PER_ENB; i++) {
+    if (f1_inst->f1ap_ue[i].rnti == 0 ) {
+      f1_inst->f1ap_ue[i].rnti = rntiP;
+      f1_inst->f1ap_ue[i].f1ap_uid = i;
+      f1_inst->f1ap_ue[i].mac_uid = UE_id;
+      f1_inst->f1ap_ue[i].du_ue_f1ap_id = rntiP;
+      f1_inst->f1ap_ue[i].cu_ue_f1ap_id = rntiP;
+      f1_inst->num_ues++;
+      LOG_I(F1AP, "Adding a new UE with RNTI %x and cu/du ue_f1ap_id %d\n", f1_inst->f1ap_ue[i].rnti, f1_inst->f1ap_ue[i].du_ue_f1ap_id);
+      return i;
+    }
+  }
+  return -1;
+}
+
+
+int f1ap_remove_ue(f1ap_cudu_inst_t *f1_inst,
+                   rnti_t            rntiP) {
+  for (int i = 0; i < MAX_MOBILES_PER_ENB; i++) {
+    if (f1_inst->f1ap_ue[i].rnti == rntiP) {
+      f1_inst->f1ap_ue[i].rnti = 0;
+      break;
+    }
+  }
+  f1_inst->num_ues--;
+  return 0;
+}
+
+int f1ap_get_du_ue_f1ap_id(f1ap_cudu_inst_t *f1_inst,
+                            rnti_t            rntiP) {
+  for (int i = 0; i < MAX_MOBILES_PER_ENB; i++) {
+    if (f1_inst->f1ap_ue[i].rnti == rntiP) {
+      return f1_inst->f1ap_ue[i].du_ue_f1ap_id;
+    }
+  }
+  return -1;
+}
+
+int f1ap_get_cu_ue_f1ap_id(f1ap_cudu_inst_t *f1_inst,
+                            rnti_t            rntiP) {
+  for (int i = 0; i < MAX_MOBILES_PER_ENB; i++) {
+    if (f1_inst->f1ap_ue[i].rnti == rntiP) {
+      return f1_inst->f1ap_ue[i].cu_ue_f1ap_id;
+    }
+  }
+  return -1;
+}
+
+int f1ap_get_rnti_by_du_id(f1ap_cudu_inst_t *f1_inst,
+                           module_id_t       du_ue_f1ap_id ) {
+  for (int i = 0; i < MAX_MOBILES_PER_ENB; i++) {
+    if (f1_inst->f1ap_ue[i].du_ue_f1ap_id == du_ue_f1ap_id) {
+      return f1_inst->f1ap_ue[i].rnti;
+    }
+  }
+  return -1;
+}
+
+int f1ap_get_rnti_by_cu_id(f1ap_cudu_inst_t *f1_inst,
+                           module_id_t       cu_ue_f1ap_id ) {
+  for (int i = 0; i < MAX_MOBILES_PER_ENB; i++) {
+    if (f1_inst->f1ap_ue[i].cu_ue_f1ap_id == cu_ue_f1ap_id) {
+      return f1_inst->f1ap_ue[i].rnti;
+    }
+  }
+  return -1;
+}
+
+int f1ap_get_du_uid(f1ap_cudu_inst_t *f1_inst,
+                    module_id_t       du_ue_f1ap_id ) {
+  for (int i = 0; i < MAX_MOBILES_PER_ENB; i++) {
+    if (f1_inst->f1ap_ue[i].du_ue_f1ap_id == du_ue_f1ap_id) {
+      return i;
+    }
+  }
+  return -1;
+}
+
+int f1ap_get_cu_uid(f1ap_cudu_inst_t *f1_inst,
+                    module_id_t       cu_ue_f1ap_id ) {
+  for (int i = 0; i < MAX_MOBILES_PER_ENB; i++) {
+    if (f1_inst->f1ap_ue[i].cu_ue_f1ap_id == cu_ue_f1ap_id) {
+      return i;
+    }
+  }
+  return -1;
+}
+
+int f1ap_get_uid_by_rnti(f1ap_cudu_inst_t *f1_inst,
+                         rnti_t            rntiP ) {
+  for (int i = 0; i < MAX_MOBILES_PER_ENB; i++) {
+    if (f1_inst->f1ap_ue[i].rnti == rntiP) {
+      return i;
+    }
+  }
+  return -1;
+}
+
+int f1ap_du_add_cu_ue_id(f1ap_cudu_inst_t *f1_inst,
+                         module_id_t       du_ue_f1ap_id,
+                         module_id_t       cu_ue_f1ap_id) {
+  module_id_t f1ap_uid = f1ap_get_du_uid(f1_inst,du_ue_f1ap_id);
+  if (f1ap_uid < 0) return -1;
+  f1_inst->f1ap_ue[f1ap_uid].cu_ue_f1ap_id = cu_ue_f1ap_id;
+  LOG_I(F1AP, "Adding cu_ue_f1ap_id %d for UE with RNTI %x\n", cu_ue_f1ap_id, f1_inst->f1ap_ue[f1ap_uid].rnti);
+  return 0;
+}
+
+int f1ap_cu_add_du_ue_id(f1ap_cudu_inst_t *f1_inst,
+                         module_id_t       cu_ue_f1ap_id,
+                         module_id_t       du_ue_f1ap_id) {
+  module_id_t f1ap_uid = f1ap_get_cu_uid(f1_inst,cu_ue_f1ap_id);
+  if (f1ap_uid < 0) return -1;
+  f1_inst->f1ap_ue[f1ap_uid].du_ue_f1ap_id = du_ue_f1ap_id;
+  LOG_I(F1AP, "Adding du_ue_f1ap_id %d for UE with RNTI %x\n", du_ue_f1ap_id, f1_inst->f1ap_ue[f1ap_uid].rnti);
+  return 0;
+}
diff --git a/openair2/F1AP/f1ap_common.h b/openair2/F1AP/f1ap_common.h
new file mode 100644
index 0000000000000000000000000000000000000000..ee57a7ec838e41ca4374e03a1fc1e762b1a3f345
--- /dev/null
+++ b/openair2/F1AP/f1ap_common.h
@@ -0,0 +1,488 @@
+/*
+ * 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
+ */
+
+/*! \file f1ap_common.h
+ * \brief f1ap procedures for both CU and DU
+ * \author EURECOM/NTUST
+ * \date 2018
+ * \version 0.1
+ * \company Eurecom
+ * \email: navid.nikaein@eurecom.fr, bing-kai.hong@eurecom.fr
+ * \note
+ * \warning
+ */
+
+#if HAVE_CONFIG_H_
+# include "config.h"
+#endif
+
+#ifndef F1AP_COMMON_H_
+#define F1AP_COMMON_H_
+
+#include "openairinterface5g_limits.h"
+
+#define F1AP_UE_IDENTIFIER_NUMBER 3
+#define F1AP_TRANSACTION_IDENTIFIER_NUMBER 3
+
+#if defined(EMIT_ASN_DEBUG_EXTERN)
+inline void ASN_DEBUG(const char *fmt, ...);
+#endif
+
+#include "F1AP_Active-Cells-List.h"
+#include "F1AP_RAT-FrequencyPriorityInformation.h"
+#include "F1AP_DLUPTNLInformation-ToBeSetup-Item.h"
+#include "F1AP_PrivateMessage.h"
+#include "F1AP_Cause.h"
+#include "F1AP_Pre-emptionVulnerability.h"
+#include "F1AP_NRPCI.h"
+#include "F1AP_Transmission-Bandwidth.h"
+#include "F1AP_SIB1-message.h"
+#include "F1AP_GNBCUConfigurationUpdateAcknowledge.h"
+#include "F1AP_DRBs-Setup-Item.h"
+#include "F1AP_EUTRA-NR-CellResourceCoordinationReqAck-Container.h"
+#include "F1AP_NR-CGI-List-For-Restart-Item.h"
+#include "F1AP_GNB-CU-Name.h"
+#include "F1AP_PagingDRX.h"
+#include "F1AP_RepetitionPeriod.h"
+#include "F1AP_DRBs-ToBeModified-List.h"
+#include "F1AP_ExecuteDuplication.h"
+#include "F1AP_SCell-FailedtoSetupMod-List.h"
+#include "F1AP_NRNRB.h"
+#include "F1AP_SCell-ToBeSetup-List.h"
+#include "F1AP_F1AP-PDU.h"
+#include "F1AP_MaskedIMEISV.h"
+#include "F1AP_ProtocolIE-Container.h"
+#include "F1AP_GNB-CU-TNL-Association-To-Update-Item.h"
+#include "F1AP_Cells-to-be-Activated-List-Item.h"
+#include "F1AP_DRBs-Required-ToBeModified-Item.h"
+#include "F1AP_BitRate.h"
+#include "F1AP_SRBs-ToBeSetup-List.h"
+#include "F1AP_ConcurrentWarningMessageIndicator.h"
+#include "F1AP_CriticalityDiagnostics-IE-Item.h"
+#include "F1AP_GNB-CU-TNL-Association-To-Update-List.h"
+#include "F1AP_DRB-Notify-List.h"
+#include "F1AP_UEContextReleaseCommand.h"
+#include "F1AP_ProtocolIE-SingleContainer.h"
+#include "F1AP_DRBs-ToBeReleased-List.h"
+#include "F1AP_PWS-Failed-NR-CGI-List.h"
+#include "F1AP_InitialULRRCMessageTransfer.h"
+#include "F1AP_Served-Cell-Information.h"
+#include "F1AP_Served-EUTRA-Cells-Information.h"
+#include "F1AP_Cells-Broadcast-Cancelled-Item.h"
+#include "F1AP_F1SetupRequest.h"
+#include "F1AP_Served-Cells-To-Add-Item.h"
+#include "F1AP_F1SetupFailure.h"
+#include "F1AP_ULUPTNLInformation-ToBeSetup-Item.h"
+#include "F1AP_GNB-CU-TNL-Association-To-Add-Item.h"
+#include "F1AP_DUtoCURRCContainer.h"
+#include "F1AP_GNBDUResourceCoordinationRequest.h"
+#include "F1AP_DRBs-FailedToBeSetup-List.h"
+#include "F1AP_UPTransportLayerInformation.h"
+#include "F1AP_RRCContainer.h"
+#include "F1AP_Notification-Cause.h"
+#include "F1AP_UEIdentityIndexValue.h"
+#include "F1AP_SRBs-ToBeSetupMod-List.h"
+#include "F1AP_GNB-DU-Served-Cells-Item.h"
+#include "F1AP_RLCMode.h"
+#include "F1AP_NRSCS.h"
+#include "F1AP_SliceSupportList.h"
+#include "F1AP_GTP-TEID.h"
+#include "F1AP_UEContextModificationRequest.h"
+#include "F1AP_MeasConfig.h"
+#include "F1AP_Flows-Mapped-To-DRB-List.h"
+#include "F1AP_Cells-to-be-Deactivated-List-Item.h"
+#include "F1AP_QoSFlowLevelQoSParameters.h"
+#include "F1AP_GNB-CU-UE-F1AP-ID.h"
+#include "F1AP_CauseTransport.h"
+#include "F1AP_DRBs-ToBeReleased-Item.h"
+#include "F1AP_SCell-ToBeSetupMod-Item.h"
+#include "F1AP_CellGroupConfig.h"
+#include "F1AP_PWSSystemInformation.h"
+#include "F1AP_DRBs-Modified-List.h"
+#include "F1AP_HandoverPreparationInformation.h"
+#include "F1AP_InactivityMonitoringResponse.h"
+#include "F1AP_Served-Cells-To-Delete-List.h"
+#include "F1AP_ProtocolExtensionField.h"
+#include "F1AP_GNB-CU-TNL-Association-To-Remove-List.h"
+#include "F1AP_SRBID.h"
+#include "F1AP_DRB-Activity-List.h"
+#include "F1AP_DRBs-FailedToBeModified-Item.h"
+#include "F1AP_TransactionID.h"
+#include "F1AP_AllocationAndRetentionPriority.h"
+#include "F1AP_ShortDRXCycleLength.h"
+#include "F1AP_BroadcastPLMNs-Item.h"
+#include "F1AP_DRB-Information.h"
+#include "F1AP_TimeToWait.h"
+#include "F1AP_NonDynamic5QIDescriptor.h"
+#include "F1AP_C-RNTI.h"
+#include "F1AP_MIB-message.h"
+#include "F1AP_SIBtype-Item.h"
+#include "F1AP_Served-Cells-To-Modify-List.h"
+#include "F1AP_NRCGI.h"
+#include "F1AP_DuplicationActivation.h"
+#include "F1AP_CauseProtocol.h"
+#include "F1AP_SCell-FailedtoSetup-Item.h"
+#include "F1AP_PagingIdentity.h"
+#include "F1AP_NGRANAllocationAndRetentionPriority.h"
+#include "F1AP_TypeOfError.h"
+#include "F1AP_GNB-CU-TNL-Association-To-Add-List.h"
+#include "F1AP_DRBs-Required-ToBeReleased-Item.h"
+#include "F1AP_EUTRA-Mode-Info.h"
+#include "F1AP_FiveGS-TAC.h"
+#include "F1AP_Cells-to-be-Activated-List.h"
+#include "F1AP_PagingCell-list.h"
+#include "F1AP_NotificationControl.h"
+#include "F1AP_ProtectedEUTRAResourceIndication.h"
+#include "F1AP_CUtoDURRCInformation.h"
+#include "F1AP_SystemInformationDeliveryCommand.h"
+#include "F1AP_AveragingWindow.h"
+#include "F1AP_SRBs-ToBeSetupMod-Item.h"
+#include "F1AP_NumberOfBroadcasts.h"
+#include "F1AP_Cells-Broadcast-Completed-List.h"
+#include "F1AP_GNB-CU-TNL-Association-Setup-Item.h"
+#include "F1AP_PWSCancelResponse.h"
+#include "F1AP_SpectrumSharingGroupID.h"
+#include "F1AP_RANUEPagingIdentity.h"
+#include "F1AP_CG-ConfigInfo.h"
+#include "F1AP_PagingCell-Item.h"
+#include "F1AP_GNB-CU-TNL-Association-To-Remove-Item.h"
+#include "F1AP_UE-CapabilityRAT-ContainerList.h"
+#include "F1AP_PWSCancelRequest.h"
+#include "F1AP_PriorityLevel.h"
+#include "F1AP_ProtocolIE-ContainerPair.h"
+#include "F1AP_FullConfiguration.h"
+#include "F1AP_NRCellIdentity.h"
+#include "F1AP_ProtocolExtensionContainer.h"
+#include "F1AP_PWSRestartIndication.h"
+#include "F1AP_DRBs-ModifiedConf-List.h"
+#include "F1AP_GNB-CU-TNL-Association-Failed-To-Setup-List.h"
+#include "F1AP_UEContextSetupRequest.h"
+#include "F1AP_PWSFailureIndication.h"
+#include "F1AP_UE-associatedLogicalF1-ConnectionListResAck.h"
+#include "F1AP_DRBs-ToBeSetupMod-Item.h"
+#include "F1AP_SRBs-FailedToBeSetup-List.h"
+#include "F1AP_Criticality.h"
+#include "F1AP_UEContextModificationConfirm.h"
+#include "F1AP_Broadcast-To-Be-Cancelled-List.h"
+#include "F1AP_UEContextReleaseComplete.h"
+#include "F1AP_PrivateIE-Container.h"
+#include "F1AP_CellULConfigured.h"
+#include "F1AP_DRB-Activity.h"
+#include "F1AP_GNB-CU-TNL-Association-Failed-To-Setup-Item.h"
+#include "F1AP_PrivateIE-ID.h"
+#include "F1AP_WriteReplaceWarningResponse.h"
+#include "F1AP_CauseMisc.h"
+#include "F1AP_SRBs-Required-ToBeReleased-Item.h"
+#include "F1AP_Cells-Broadcast-Cancelled-List.h"
+#include "F1AP_ULUEConfiguration.h"
+#include "F1AP_RAT-FrequencySelectionPriority.h"
+#include "F1AP_UEInactivityNotification.h"
+#include "F1AP_DLRRCMessageTransfer.h"
+#include "F1AP_TriggeringMessage.h"
+#include "F1AP_DRBs-ToBeSetup-List.h"
+#include "F1AP_Cells-to-be-Barred-Item.h"
+#include "F1AP_UE-associatedLogicalF1-ConnectionItem.h"
+#include "F1AP_Cancel-all-Warning-Messages-Indicator.h"
+#include "F1AP_SCell-FailedtoSetupMod-Item.h"
+#include "F1AP_DRBs-FailedToBeSetupMod-List.h"
+#include "F1AP_ProtocolIE-ID.h"
+#include "F1AP_TransportLayerAddress.h"
+#include "F1AP_GNB-DU-System-Information.h"
+#include "F1AP_PWS-Failed-NR-CGI-Item.h"
+#include "F1AP_Notify.h"
+#include "F1AP_UEContextModificationResponse.h"
+#include "F1AP_DRBID.h"
+#include "F1AP_GNBDUResourceCoordinationResponse.h"
+#include "F1AP_UEContextModificationRequired.h"
+#include "F1AP_InitiatingMessage.h"
+#include "F1AP_SliceSupportItem.h"
+#include "F1AP_ProtocolIE-FieldPair.h"
+#include "F1AP_EUTRA-TDD-Info.h"
+#include "F1AP_GNBDUConfigurationUpdateFailure.h"
+#include "F1AP_ULUPTNLInformation-ToBeSetup-List.h"
+#include "F1AP_WriteReplaceWarningRequest.h"
+#include "F1AP_ServCellIndex.h"
+#include "F1AP_ResetAcknowledge.h"
+#include "F1AP_SRBs-FailedToBeSetupMod-Item.h"
+#include "F1AP_OffsetToPointA.h"
+#include "F1AP_ProcedureCode.h"
+#include "F1AP_GTPTunnel.h"
+#include "F1AP_TDD-Info.h"
+#include "F1AP_Pre-emptionCapability.h"
+#include "F1AP_MaxDataBurstVolume.h"
+#include "F1AP_SUL-Information.h"
+#include "F1AP_CriticalityDiagnostics-IE-List.h"
+#include "F1AP_EUTRA-FDD-Info.h"
+#include "F1AP_BroadcastPLMNs-List.h"
+#include "F1AP_Served-Cells-To-Delete-Item.h"
+#include "F1AP_ListofEUTRACellsinGNBDUCoordination.h"
+#include "F1AP_Candidate-SpCell-Item.h"
+#include "F1AP_Cells-To-Be-Broadcast-List.h"
+#include "F1AP_ULRRCMessageTransfer.h"
+#include "F1AP_Cells-to-be-Deactivated-List.h"
+#include "F1AP_DRBs-Required-ToBeReleased-List.h"
+#include "F1AP_Served-Cells-To-Add-List.h"
+#include "F1AP_Potential-SpCell-List.h"
+#include "F1AP_EUTRANQoS.h"
+#include "F1AP_Dynamic5QIDescriptor.h"
+#include "F1AP_GNBCUConfigurationUpdateFailure.h"
+#include "F1AP_DuplicationIndication.h"
+#include "F1AP_GNB-DU-Served-Cells-List.h"
+#include "F1AP_QoS-Characteristics.h"
+#include "F1AP_UE-associatedLogicalF1-ConnectionListRes.h"
+#include "F1AP_ResourceCoordinationTransferContainer.h"
+#include "F1AP_DRXCycle.h"
+#include "F1AP_DRBs-FailedToBeSetup-Item.h"
+#include "F1AP_PrivateIE-Field.h"
+#include "F1AP_SRBs-ToBeReleased-List.h"
+#include "F1AP_MeasGapConfig.h"
+#include "F1AP_NR-Mode-Info.h"
+#include "F1AP_Active-Cells-Item.h"
+#include "F1AP_Protected-EUTRA-Resources-List.h"
+#include "F1AP_SRBs-FailedToBeSetup-Item.h"
+#include "F1AP_ResetAll.h"
+#include "F1AP_SCell-FailedtoSetup-List.h"
+#include "F1AP_UEContextModificationFailure.h"
+#include "F1AP_CNUEPagingIdentity.h"
+#include "F1AP_DRBs-ToBeSetupMod-List.h"
+#include "F1AP_GNBDUConfigurationUpdate.h"
+#include "F1AP_DRBs-ToBeSetup-Item.h"
+#include "F1AP_UnsuccessfulOutcome.h"
+#include "F1AP_SRBs-FailedToBeSetupMod-List.h"
+#include "F1AP_SCell-ToBeRemoved-Item.h"
+#include "F1AP_InactivityMonitoringRequest.h"
+#include "F1AP_Cells-Failed-to-be-Activated-List-Item.h"
+#include "F1AP_DRBs-Modified-Item.h"
+#include "F1AP_SRBs-Required-ToBeReleased-List.h"
+#include "F1AP_GBR-QosInformation.h"
+#include "F1AP_SCell-ToBeRemoved-List.h"
+#include "F1AP_RANAC.h"
+#include "F1AP_GNB-DU-UE-F1AP-ID.h"
+#include "F1AP_CauseRadioNetwork.h"
+#include "F1AP_DRB-Notify-Item.h"
+#include "F1AP_GNBDUConfigurationUpdateAcknowledge.h"
+#include "F1AP_GNB-CUSystemInformation.h"
+#include "F1AP_ProtocolIE-Field.h"
+#include "F1AP_Served-Cells-To-Modify-Item.h"
+#include "F1AP_Flows-Mapped-To-DRB-Item.h"
+#include "F1AP_SupportedSULFreqBandItem.h"
+#include "F1AP_UEContextReleaseRequest.h"
+#include "F1AP_GNB-DU-Name.h"
+#include "F1AP_DRBs-ToBeModified-Item.h"
+#include "F1AP_SIBtype-List.h"
+#include "F1AP_EUTRA-NR-CellResourceCoordinationReq-Container.h"
+#include "F1AP_DRBs-SetupMod-List.h"
+#include "F1AP_DRBs-Required-ToBeModified-List.h"
+#include "F1AP_DUtoCURRCInformation.h"
+#include "F1AP_MaxPacketLossRate.h"
+#include "F1AP_PacketDelayBudget.h"
+#include "F1AP_GNBCUConfigurationUpdate.h"
+#include "F1AP_Cells-Broadcast-Completed-Item.h"
+#include "F1AP_RRCRconfigurationCompleteIndicator.h"
+#include "F1AP_PagingPriority.h"
+#include "F1AP_Cells-Failed-to-be-Activated-List.h"
+#include "F1AP_Endpoint-IP-address-and-port.h"
+#include "F1AP_PacketErrorRate.h"
+#include "F1AP_PLMN-Identity.h"
+#include "F1AP_asn_constant.h"
+#include "F1AP_ResetType.h"
+#include "F1AP_FDD-Info.h"
+#include "F1AP_DLUPTNLInformation-ToBeSetup-List.h"
+#include "F1AP_QoSFlowIndicator.h"
+#include "F1AP_NR-CGI-List-For-Restart-List.h"
+#include "F1AP_F1SetupResponse.h"
+#include "F1AP_UEContextSetupResponse.h"
+#include "F1AP_CP-TransportLayerAddress.h"
+#include "F1AP_Broadcast-To-Be-Cancelled-Item.h"
+#include "F1AP_ErrorIndication.h"
+#include "F1AP_SubscriberProfileIDforRFP.h"
+#include "F1AP_SNSSAI.h"
+#include "F1AP_DRBs-ModifiedConf-Item.h"
+#include "F1AP_GNB-CU-TNL-Association-Setup-List.h"
+#include "F1AP_DRB-Activity-Item.h"
+#include "F1AP_LCID.h"
+#include "F1AP_ULConfiguration.h"
+#include "F1AP_ShortDRXCycleTimer.h"
+#include "F1AP_FreqBandNrItem.h"
+#include "F1AP_Cells-to-be-Barred-List.h"
+#include "F1AP_Presence.h"
+#include "F1AP_CellBarred.h"
+#include "F1AP_SIBtype.h"
+#include "F1AP_RequestType.h"
+#include "F1AP_NRFreqInfo.h"
+#include "F1AP_Potential-SpCell-Item.h"
+#include "F1AP_NumberofBroadcastRequest.h"
+#include "F1AP_TNLAssociationUsage.h"
+#include "F1AP_SCell-ToBeSetupMod-List.h"
+#include "F1AP_DRBs-Setup-List.h"
+#include "F1AP_Reset.h"
+#include "F1AP_CriticalityDiagnostics.h"
+#include "F1AP_Paging.h"
+#include "F1AP_LongDRXCycleLength.h"
+#include "F1AP_GNB-DU-ID.h"
+#include "F1AP_SuccessfulOutcome.h"
+#include "F1AP_Configured-EPS-TAC.h"
+#include "F1AP_Candidate-SpCell-List.h"
+#include "F1AP_SRBs-ToBeReleased-Item.h"
+#include "F1AP_QoSInformation.h"
+#include "F1AP_SCell-ToBeSetup-Item.h"
+#include "F1AP_SRBs-ToBeSetup-Item.h"
+#include "F1AP_GBR-QoSFlowInformation.h"
+#include "F1AP_SCellIndex.h"
+#include "F1AP_DRBs-SetupMod-Item.h"
+#include "F1AP_TransmissionStopIndicator.h"
+#include "F1AP_UEContextSetupFailure.h"
+#include "F1AP_DRBs-FailedToBeModified-List.h"
+#include "F1AP_DRBs-FailedToBeSetupMod-Item.h"
+#include "F1AP_ProtocolExtensionID.h"
+#include "F1AP_Cells-To-Be-Broadcast-Item.h"
+#include "F1AP_QCI.h"
+
+#include "conversions.h"
+#include "platform_types.h"
+#include "common/utils/LOG/log.h"
+#include "intertask_interface.h"
+#include "sctp_messages_types.h"
+#include "f1ap_messages_types.h"
+#include <arpa/inet.h>
+#include "T.h"
+#include "common/ran_context.h"
+#include "msc.h"
+
+/* Checking version of ASN1C compiler */
+#if (ASN1C_ENVIRONMENT_VERSION < ASN1C_MINIMUM_VERSION)
+# error "You are compiling f1ap with the wrong version of ASN1C"
+#endif
+
+#ifndef FALSE
+# define FALSE (0)
+#endif
+#ifndef TRUE
+# define TRUE  (!FALSE)
+#endif
+
+#define F1AP_UE_ID_FMT  "0x%06"PRIX32
+
+#include "assertions.h"
+
+#if defined(ENB_MODE)
+# include "common/utils/LOG/log.h"
+# include "f1ap_default_values.h"
+# define F1AP_ERROR(x, args...) LOG_E(F1AP, x, ##args)
+# define F1AP_WARN(x, args...)  LOG_W(F1AP, x, ##args)
+# define F1AP_TRAF(x, args...)  LOG_I(F1AP, x, ##args)
+# define F1AP_INFO(x, args...) LOG_I(F1AP, x, ##args)
+# define F1AP_DEBUG(x, args...) LOG_I(F1AP, x, ##args)
+#else
+//# include "mme_default_values.h"
+# define F1AP_ERROR(x, args...) do { fprintf(stdout, "[F1AP][E]"x, ##args); } while(0)
+# define F1AP_WARN(x, args...)  do { fprintf(stdout, "[F1AP][W]"x, ##args); } while(0)
+# define F1AP_TRAF(x, args...)  do { fprintf(stdout, "[F1AP][T]"x, ##args); } while(0)
+# define F1AP_INFO(x, args...) do { fprintf(stdout, "[F1AP][I]"x, ##args); } while(0)
+# define F1AP_DEBUG(x, args...) do { fprintf(stdout, "[F1AP][D]"x, ##args); } while(0)
+#endif
+
+//Forward declaration
+#define F1AP_FIND_PROTOCOLIE_BY_ID(IE_TYPE, ie, container, IE_ID, mandatory) \
+  do {\
+    IE_TYPE **ptr; \
+    ie = NULL; \
+    for (ptr = container->protocolIEs.list.array; \
+         ptr < &container->protocolIEs.list.array[container->protocolIEs.list.count]; \
+         ptr++) { \
+      if((*ptr)->id == IE_ID) { \
+        ie = *ptr; \
+        break; \
+      } \
+    } \
+    if (mandatory) DevAssert(ie != NULL); \
+  } while(0)
+
+/** \brief Function callback prototype.
+ **/
+typedef int (*f1ap_message_decoded_callback)(
+  instance_t             instance,
+  uint32_t               assoc_id,
+  uint32_t               stream,
+  F1AP_F1AP_PDU_t       *message_p
+);
+
+typedef struct f1ap_cudu_ue_inst_s {
+  // used for eNB stats generation
+  rnti_t      rnti;
+  module_id_t f1ap_uid;
+  module_id_t mac_uid;
+  module_id_t du_ue_f1ap_id;
+  module_id_t cu_ue_f1ap_id;
+} f1ap_cudu_ue_t;
+
+typedef struct f1ap_cudu_inst_s {
+  uint16_t num_ues;
+  f1ap_cudu_ue_t f1ap_ue[MAX_MOBILES_PER_ENB];
+} f1ap_cudu_inst_t;
+
+
+
+uint8_t F1AP_get_next_transaction_identifier(module_id_t enb_mod_idP, module_id_t cu_mod_idP);
+
+
+int f1ap_add_ue(f1ap_cudu_inst_t *f1_inst,
+                module_id_t     module_idP,
+                int             CC_idP,
+                int             UE_id,
+                rnti_t          rntiP);
+
+int f1ap_remove_ue(f1ap_cudu_inst_t *f1_inst,
+                   rnti_t            rntiP);
+
+int f1ap_get_du_ue_f1ap_id (f1ap_cudu_inst_t *f1_inst,
+                            rnti_t            rntiP);
+
+int f1ap_get_cu_ue_f1ap_id (f1ap_cudu_inst_t *f1_inst,
+                            rnti_t            rntiP);
+
+
+int f1ap_get_rnti_by_du_id(f1ap_cudu_inst_t *f1_inst,
+                           module_id_t       du_ue_f1ap_id );
+
+
+int f1ap_get_rnti_by_cu_id(f1ap_cudu_inst_t *f1_inst,
+                           module_id_t       cu_ue_f1ap_id );
+
+
+int f1ap_get_du_uid(f1ap_cudu_inst_t *f1_inst,
+                    module_id_t       du_ue_f1ap_id );
+
+int f1ap_get_cu_uid(f1ap_cudu_inst_t *f1_inst,
+                    module_id_t       cu_ue_f1ap_id );
+
+int f1ap_get_uid_by_rnti(f1ap_cudu_inst_t *f1_inst,
+                         rnti_t            rntiP );
+
+int f1ap_du_add_cu_ue_id(f1ap_cudu_inst_t *f1_inst,
+                         module_id_t       du_ue_f1ap_id,
+                         module_id_t       cu_ue_f1ap_id);
+
+int f1ap_cu_add_du_ue_id(f1ap_cudu_inst_t *f1_inst,
+                         module_id_t       cu_ue_f1ap_id,
+                         module_id_t       du_ue_f1ap_id);
+
+#endif /* F1AP_COMMON_H_ */
diff --git a/openair2/F1AP/f1ap_cu_interface_management.c b/openair2/F1AP/f1ap_cu_interface_management.c
new file mode 100644
index 0000000000000000000000000000000000000000..b451a0145769111bec434951ef44d1989887b7a7
--- /dev/null
+++ b/openair2/F1AP/f1ap_cu_interface_management.c
@@ -0,0 +1,905 @@
+/*
+ * 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
+ */
+
+/*! \file f1ap_cu_interface_management.c
+ * \brief f1ap interface management for CU
+ * \author EURECOM/NTUST
+ * \date 2018
+ * \version 0.1
+ * \company Eurecom
+ * \email: navid.nikaein@eurecom.fr, bing-kai.hong@eurecom.fr
+ * \note
+ * \warning
+ */
+
+#include "f1ap_common.h"
+#include "f1ap_encoder.h"
+#include "f1ap_decoder.h"
+#include "f1ap_itti_messaging.h"
+#include "f1ap_cu_interface_management.h"
+
+extern f1ap_setup_req_t *f1ap_du_data_from_du;
+
+int CU_send_RESET(instance_t instance, F1AP_Reset_t *Reset) {
+  AssertFatal(1==0,"Not implemented yet\n");
+}
+
+int CU_handle_RESET_ACKKNOWLEDGE(instance_t instance,
+                                  uint32_t assoc_id,
+                                  uint32_t stream,
+                                  F1AP_F1AP_PDU_t *pdu) {
+  AssertFatal(1==0,"Not implemented yet\n");
+}
+
+int CU_handle_RESET(instance_t instance,
+                     uint32_t assoc_id,
+                     uint32_t stream,
+                     F1AP_F1AP_PDU_t *pdu) {
+  AssertFatal(1==0,"Not implemented yet\n");
+}
+
+int CU_send_RESET_ACKNOWLEDGE(instance_t instance, F1AP_ResetAcknowledge_t *ResetAcknowledge) {
+  AssertFatal(1==0,"Not implemented yet\n");
+}
+
+
+/*
+    Error Indication
+*/
+int CU_handle_ERROR_INDICATION(instance_t instance,
+                                uint32_t assoc_id,
+                                uint32_t stream,
+                                F1AP_F1AP_PDU_t *pdu) {
+  AssertFatal(1==0,"Not implemented yet\n");
+}
+
+int CU_send_ERROR_INDICATION(instance_t instance, F1AP_ErrorIndication_t *ErrorIndication) {
+  AssertFatal(1==0,"Not implemented yet\n");
+}
+
+
+/*
+    F1 Setup
+*/
+int CU_handle_F1_SETUP_REQUEST(instance_t instance,
+                               uint32_t assoc_id,
+                               uint32_t stream,
+                               F1AP_F1AP_PDU_t *pdu)
+{
+  LOG_D(F1AP, "CU_handle_F1_SETUP_REQUEST\n");
+  
+  MessageDef                         *message_p;
+  F1AP_F1SetupRequest_t              *container;
+  F1AP_F1SetupRequestIEs_t           *ie;
+  int i = 0;
+   
+
+  DevAssert(pdu != NULL);
+
+  container = &pdu->choice.initiatingMessage->value.choice.F1SetupRequest;
+
+  /* F1 Setup Request == Non UE-related procedure -> stream 0 */
+  if (stream != 0) {
+    LOG_W(F1AP, "[SCTP %d] Received f1 setup request on stream != 0 (%d)\n",
+              assoc_id, stream);
+  }
+
+  message_p = itti_alloc_new_message(TASK_RRC_ENB, F1AP_SETUP_REQ); 
+  
+  /* assoc_id */
+  F1AP_SETUP_REQ(message_p).assoc_id = assoc_id;
+  
+  /* gNB_DU_id */
+  // this function exits if the ie is mandatory
+  F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_F1SetupRequestIEs_t, ie, container,
+                             F1AP_ProtocolIE_ID_id_gNB_DU_ID, true);
+  asn_INTEGER2ulong(&ie->value.choice.GNB_DU_ID, &F1AP_SETUP_REQ(message_p).gNB_DU_id);
+  LOG_D(F1AP, "F1AP_SETUP_REQ(message_p).gNB_DU_id %lu \n", F1AP_SETUP_REQ(message_p).gNB_DU_id);
+
+  /* gNB_DU_name */
+  F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_F1SetupRequestIEs_t, ie, container,
+                              F1AP_ProtocolIE_ID_id_gNB_DU_Name, true);
+  F1AP_SETUP_REQ(message_p).gNB_DU_name = calloc(ie->value.choice.GNB_DU_Name.size + 1, sizeof(char));
+  memcpy(F1AP_SETUP_REQ(message_p).gNB_DU_name, ie->value.choice.GNB_DU_Name.buf,
+         ie->value.choice.GNB_DU_Name.size);
+  /* Convert the mme name to a printable string */
+  F1AP_SETUP_REQ(message_p).gNB_DU_name[ie->value.choice.GNB_DU_Name.size] = '\0';
+  LOG_D(F1AP, "F1AP_SETUP_REQ(message_p).gNB_DU_name %s \n", F1AP_SETUP_REQ(message_p).gNB_DU_name);
+
+  /* GNB_DU_Served_Cells_List */
+  F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_F1SetupRequestIEs_t, ie, container,
+                              F1AP_ProtocolIE_ID_id_gNB_DU_Served_Cells_List, true);
+  F1AP_SETUP_REQ(message_p).num_cells_available = ie->value.choice.GNB_DU_Served_Cells_List.list.count;
+  LOG_D(F1AP, "F1AP_SETUP_REQ(message_p).num_cells_available %d \n",
+        F1AP_SETUP_REQ(message_p).num_cells_available);
+
+  int num_cells_available = F1AP_SETUP_REQ(message_p).num_cells_available;
+
+  for (i=0; i<num_cells_available; i++) {
+    F1AP_GNB_DU_Served_Cells_Item_t *served_celles_item_p;
+
+    served_celles_item_p = &(((F1AP_GNB_DU_Served_Cells_ItemIEs_t *)ie->value.choice.GNB_DU_Served_Cells_List.list.array[i])->value.choice.GNB_DU_Served_Cells_Item);
+    
+    /* tac */
+    OCTET_STRING_TO_INT16(&(served_celles_item_p->served_Cell_Information.fiveGS_TAC), F1AP_SETUP_REQ(message_p).tac[i]);
+    LOG_D(F1AP, "F1AP_SETUP_REQ(message_p).tac[%d] %d \n",
+          i, F1AP_SETUP_REQ(message_p).tac[i]);
+
+    /* - nRCGI */
+    TBCD_TO_MCC_MNC(&(served_celles_item_p->served_Cell_Information.nRCGI.pLMN_Identity), F1AP_SETUP_REQ(message_p).mcc[i],
+                    F1AP_SETUP_REQ(message_p).mnc[i],
+                    F1AP_SETUP_REQ(message_p).mnc_digit_length[i]);
+    
+    
+    // NR cellID
+    BIT_STRING_TO_NR_CELL_IDENTITY(&served_celles_item_p->served_Cell_Information.nRCGI.nRCellIdentity,
+				   F1AP_SETUP_REQ(message_p).nr_cellid[i]);
+    LOG_D(F1AP, "[SCTP %d] Received nRCGI: MCC %d, MNC %d, CELL_ID %llu\n", assoc_id,
+          F1AP_SETUP_REQ(message_p).mcc[i],
+          F1AP_SETUP_REQ(message_p).mnc[i],
+          (long long unsigned int)F1AP_SETUP_REQ(message_p).nr_cellid[i]);
+    LOG_D(F1AP, "nr_cellId : %x %x %x %x %x\n",
+          served_celles_item_p->served_Cell_Information.nRCGI.nRCellIdentity.buf[0],
+          served_celles_item_p->served_Cell_Information.nRCGI.nRCellIdentity.buf[1],
+          served_celles_item_p->served_Cell_Information.nRCGI.nRCellIdentity.buf[2],
+          served_celles_item_p->served_Cell_Information.nRCGI.nRCellIdentity.buf[3],
+          served_celles_item_p->served_Cell_Information.nRCGI.nRCellIdentity.buf[4]);
+    /* - nRPCI */
+    F1AP_SETUP_REQ(message_p).nr_pci[i] = served_celles_item_p->served_Cell_Information.nRPCI;
+    LOG_D(F1AP, "F1AP_SETUP_REQ(message_p).nr_pci[%d] %d \n",
+          i, F1AP_SETUP_REQ(message_p).nr_pci[i]);
+  
+    // System Information
+    /* mib */
+    F1AP_SETUP_REQ(message_p).mib[i] = calloc(served_celles_item_p->gNB_DU_System_Information->mIB_message.size + 1, sizeof(char));
+    memcpy(F1AP_SETUP_REQ(message_p).mib[i], served_celles_item_p->gNB_DU_System_Information->mIB_message.buf,
+           served_celles_item_p->gNB_DU_System_Information->mIB_message.size);
+    /* Convert the mme name to a printable string */
+    F1AP_SETUP_REQ(message_p).mib[i][served_celles_item_p->gNB_DU_System_Information->mIB_message.size] = '\0';
+    F1AP_SETUP_REQ(message_p).mib_length[i] = served_celles_item_p->gNB_DU_System_Information->mIB_message.size;
+    LOG_D(F1AP, "F1AP_SETUP_REQ(message_p).mib[%d] %s , len = %d \n",
+          i, F1AP_SETUP_REQ(message_p).mib[i], F1AP_SETUP_REQ(message_p).mib_length[i]);
+
+    /* sib1 */
+    F1AP_SETUP_REQ(message_p).sib1[i] = calloc(served_celles_item_p->gNB_DU_System_Information->sIB1_message.size + 1, sizeof(char));
+    memcpy(F1AP_SETUP_REQ(message_p).sib1[i], served_celles_item_p->gNB_DU_System_Information->sIB1_message.buf,
+           served_celles_item_p->gNB_DU_System_Information->sIB1_message.size);
+    /* Convert the mme name to a printable string */
+    F1AP_SETUP_REQ(message_p).sib1[i][served_celles_item_p->gNB_DU_System_Information->sIB1_message.size] = '\0';
+    F1AP_SETUP_REQ(message_p).sib1_length[i] = served_celles_item_p->gNB_DU_System_Information->sIB1_message.size;
+    LOG_D(F1AP, "F1AP_SETUP_REQ(message_p).sib1[%d] %s , len = %d \n",
+          i, F1AP_SETUP_REQ(message_p).sib1[i], F1AP_SETUP_REQ(message_p).sib1_length[i]);
+  }
+
+  
+  *f1ap_du_data_from_du = F1AP_SETUP_REQ(message_p);
+  // char *measurement_timing_information[F1AP_MAX_NB_CELLS];
+  // uint8_t ranac[F1AP_MAX_NB_CELLS];
+
+  // int fdd_flag = f1ap_setup_req->fdd_flag;
+
+  // union {
+  //   struct {
+  //     uint32_t ul_nr_arfcn;
+  //     uint8_t ul_scs;
+  //     uint8_t ul_nrb;
+
+  //     uint32_t dl_nr_arfcn;
+  //     uint8_t dl_scs;
+  //     uint8_t dl_nrb;
+
+  //     uint32_t sul_active;
+  //     uint32_t sul_nr_arfcn;
+  //     uint8_t sul_scs;
+  //     uint8_t sul_nrb;
+
+  //     uint8_t num_frequency_bands;
+  //     uint16_t nr_band[32];
+  //     uint8_t num_sul_frequency_bands;
+  //     uint16_t nr_sul_band[32];
+  //   } fdd;
+  //   struct {
+
+  //     uint32_t nr_arfcn;
+  //     uint8_t scs;
+  //     uint8_t nrb;
+
+  //     uint32_t sul_active;
+  //     uint32_t sul_nr_arfcn;
+  //     uint8_t sul_scs;
+  //     uint8_t sul_nrb;
+
+  //     uint8_t num_frequency_bands;
+  //     uint16_t nr_band[32];
+  //     uint8_t num_sul_frequency_bands;
+  //     uint16_t nr_sul_band[32];
+
+  //   } tdd;
+  // } nr_mode_info[F1AP_MAX_NB_CELLS];
+
+  MSC_LOG_TX_MESSAGE(
+  MSC_F1AP_CU,
+  MSC_RRC_ENB,
+  0,
+  0,
+  MSC_AS_TIME_FMT" CU_handle_F1_SETUP_REQUEST",
+  0,0//MSC_AS_TIME_ARGS(ctxt_pP),
+  );
+
+  if (num_cells_available > 0) {
+    itti_send_msg_to_task(TASK_RRC_ENB, ENB_MODULE_ID_TO_INSTANCE(instance), message_p);
+  } else {
+    CU_send_F1_SETUP_FAILURE(instance);
+    return -1;
+  }
+  return 0;
+}
+
+int CU_send_F1_SETUP_RESPONSE(instance_t instance,
+                               f1ap_setup_resp_t *f1ap_setup_resp) {
+  
+  module_id_t enb_mod_idP;
+  module_id_t cu_mod_idP;
+
+  // This should be fixed
+  enb_mod_idP = (module_id_t)0;
+  cu_mod_idP  = (module_id_t)0;
+
+  F1AP_F1AP_PDU_t           pdu;
+  F1AP_F1SetupResponse_t    *out;
+  F1AP_F1SetupResponseIEs_t *ie;
+
+  uint8_t  *buffer;
+  uint32_t  len;
+  int       i = 0;
+
+  /* Create */
+  /* 0. Message Type */
+  memset(&pdu, 0, sizeof(pdu));
+  pdu.present = F1AP_F1AP_PDU_PR_successfulOutcome;
+  pdu.choice.successfulOutcome = (F1AP_SuccessfulOutcome_t *)calloc(1, sizeof(F1AP_SuccessfulOutcome_t));
+  pdu.choice.successfulOutcome->procedureCode = F1AP_ProcedureCode_id_F1Setup;
+  pdu.choice.successfulOutcome->criticality   = F1AP_Criticality_reject;
+  pdu.choice.successfulOutcome->value.present = F1AP_SuccessfulOutcome__value_PR_F1SetupResponse;
+  out = &pdu.choice.successfulOutcome->value.choice.F1SetupResponse;
+  
+  /* mandatory */
+  /* c1. Transaction ID (integer value)*/
+  ie = (F1AP_F1SetupResponseIEs_t *)calloc(1, sizeof(F1AP_F1SetupResponseIEs_t));
+  ie->id                        = F1AP_ProtocolIE_ID_id_TransactionID;
+  ie->criticality               = F1AP_Criticality_reject;
+  ie->value.present             = F1AP_F1SetupResponseIEs__value_PR_TransactionID;
+  ie->value.choice.TransactionID = F1AP_get_next_transaction_identifier(enb_mod_idP, cu_mod_idP);
+  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+ 
+  /* optional */
+  /* c2. GNB_CU_Name */
+  if (f1ap_setup_resp->gNB_CU_name != NULL) {
+    ie = (F1AP_F1SetupResponseIEs_t *)calloc(1, sizeof(F1AP_F1SetupResponseIEs_t));
+    ie->id                        = F1AP_ProtocolIE_ID_id_gNB_CU_Name;
+    ie->criticality               = F1AP_Criticality_ignore;
+    ie->value.present             = F1AP_F1SetupResponseIEs__value_PR_GNB_CU_Name;
+    OCTET_STRING_fromBuf(&ie->value.choice.GNB_CU_Name, f1ap_setup_resp->gNB_CU_name,
+                         strlen(f1ap_setup_resp->gNB_CU_name));
+    ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+  }
+
+  /* mandatory */
+  /* c3. cells to be Activated list */
+  ie = (F1AP_F1SetupResponseIEs_t *)calloc(1, sizeof(F1AP_F1SetupResponseIEs_t));
+  ie->id                        = F1AP_ProtocolIE_ID_id_Cells_to_be_Activated_List;
+  ie->criticality               = F1AP_Criticality_reject;
+  ie->value.present             = F1AP_F1SetupResponseIEs__value_PR_Cells_to_be_Activated_List;
+
+  int num_cells_to_activate = f1ap_setup_resp->num_cells_to_activate;
+  LOG_D(F1AP, "num_cells_to_activate = %d \n", num_cells_to_activate);
+  for (i=0;
+       i<num_cells_to_activate;
+       i++) {
+
+    F1AP_Cells_to_be_Activated_List_ItemIEs_t *cells_to_be_activated_list_item_ies;
+    cells_to_be_activated_list_item_ies = (F1AP_Cells_to_be_Activated_List_ItemIEs_t *)calloc(1, sizeof(F1AP_Cells_to_be_Activated_List_ItemIEs_t));
+    cells_to_be_activated_list_item_ies->id = F1AP_ProtocolIE_ID_id_Cells_to_be_Activated_List_Item;
+    cells_to_be_activated_list_item_ies->criticality = F1AP_Criticality_reject;
+    cells_to_be_activated_list_item_ies->value.present = F1AP_Cells_to_be_Activated_List_ItemIEs__value_PR_Cells_to_be_Activated_List_Item;
+
+    /* 3.1 cells to be Activated list item */
+    F1AP_Cells_to_be_Activated_List_Item_t cells_to_be_activated_list_item;
+    memset((void *)&cells_to_be_activated_list_item, 0, sizeof(F1AP_Cells_to_be_Activated_List_Item_t));
+
+    /* - nRCGI */
+    F1AP_NRCGI_t nRCGI;
+    MCC_MNC_TO_PLMNID(f1ap_setup_resp->mcc[i], f1ap_setup_resp->mnc[i], f1ap_setup_resp->mnc_digit_length[i],
+                                     &nRCGI.pLMN_Identity);
+    NR_CELL_ID_TO_BIT_STRING(f1ap_setup_resp->nr_cellid[i], &nRCGI.nRCellIdentity);
+    cells_to_be_activated_list_item.nRCGI = nRCGI;
+
+    /* optional */
+    /* - nRPCI */
+    if (1) {
+      cells_to_be_activated_list_item.nRPCI = (F1AP_NRPCI_t *)calloc(1, sizeof(F1AP_NRPCI_t));
+      *cells_to_be_activated_list_item.nRPCI = f1ap_setup_resp->nrpci[i];  // int 0..1007
+    }
+
+    /* optional */
+    /* - gNB-CU System Information */
+    if (1) {
+      /* 3.1.2 gNB-CUSystem Information */
+      F1AP_Cells_to_be_Activated_List_ItemExtIEs_t *cells_to_be_activated_list_itemExtIEs;
+      cells_to_be_activated_list_itemExtIEs = (F1AP_Cells_to_be_Activated_List_ItemExtIEs_t *)calloc(1, sizeof(F1AP_Cells_to_be_Activated_List_ItemExtIEs_t));
+      cells_to_be_activated_list_itemExtIEs->id                     = F1AP_ProtocolIE_ID_id_gNB_CUSystemInformation;
+      cells_to_be_activated_list_itemExtIEs->criticality            = F1AP_Criticality_reject;
+      cells_to_be_activated_list_itemExtIEs->extensionValue.present = F1AP_Cells_to_be_Activated_List_ItemExtIEs__extensionValue_PR_GNB_CUSystemInformation;
+
+      F1AP_GNB_CUSystemInformation_t *gNB_CUSystemInformation = (F1AP_GNB_CUSystemInformation_t *)calloc(1, sizeof(F1AP_GNB_CUSystemInformation_t));
+      //LOG_I(F1AP, "%s() SI %d size %d: ", __func__, i, f1ap_setup_resp->SI_container_length[i][0]);
+      //for (int n = 0; n < f1ap_setup_resp->SI_container_length[i][0]; n++)
+      //  printf("%02x ", f1ap_setup_resp->SI_container[i][0][n]);
+      //printf("\n");
+      OCTET_STRING_fromBuf(&gNB_CUSystemInformation->sImessage,
+                           (const char*)f1ap_setup_resp->SI_container[i][0], 
+                           f1ap_setup_resp->SI_container_length[i][0]);
+
+      LOG_D(F1AP, "f1ap_setup_resp->SI_container_length = %d \n", f1ap_setup_resp->SI_container_length[0][0]);
+      cells_to_be_activated_list_itemExtIEs->extensionValue.choice.GNB_CUSystemInformation = *gNB_CUSystemInformation;
+
+
+      F1AP_ProtocolExtensionContainer_160P9_t p_160P9_t;
+      memset((void *)&p_160P9_t, 0, sizeof(F1AP_ProtocolExtensionContainer_160P9_t));
+
+      ASN_SEQUENCE_ADD(&p_160P9_t.list,
+                      cells_to_be_activated_list_itemExtIEs);
+      cells_to_be_activated_list_item.iE_Extensions = (struct F1AP_ProtocolExtensionContainer*)&p_160P9_t;
+
+    }
+    /* ADD */
+    cells_to_be_activated_list_item_ies->value.choice.Cells_to_be_Activated_List_Item = cells_to_be_activated_list_item;
+    ASN_SEQUENCE_ADD(&ie->value.choice.Cells_to_be_Activated_List.list,
+                  cells_to_be_activated_list_item_ies);
+  }
+  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+
+  /* encode */
+  if (f1ap_encode_pdu(&pdu, &buffer, &len) < 0) {
+    LOG_E(F1AP, "Failed to encode F1 setup request\n");
+    return -1;
+  }
+
+  cu_f1ap_itti_send_sctp_data_req(instance, f1ap_du_data_from_du->assoc_id, buffer, len, 0);
+
+  return 0;
+}
+
+int CU_send_F1_SETUP_FAILURE(instance_t instance) {
+  LOG_D(F1AP, "CU_send_F1_SETUP_FAILURE\n");
+  
+  module_id_t enb_mod_idP;
+  module_id_t cu_mod_idP;
+
+  // This should be fixed
+  enb_mod_idP = (module_id_t)0;
+  cu_mod_idP  = (module_id_t)0;
+
+  F1AP_F1AP_PDU_t           pdu;
+  F1AP_F1SetupFailure_t    *out;
+  F1AP_F1SetupFailureIEs_t *ie;
+
+  uint8_t  *buffer;
+  uint32_t  len;
+
+  /* Create */
+  /* 0. Message Type */
+  memset(&pdu, 0, sizeof(pdu));
+  pdu.present = F1AP_F1AP_PDU_PR_unsuccessfulOutcome;
+  pdu.choice.unsuccessfulOutcome = (F1AP_UnsuccessfulOutcome_t *)calloc(1, sizeof(F1AP_UnsuccessfulOutcome_t));
+  pdu.choice.unsuccessfulOutcome->procedureCode = F1AP_ProcedureCode_id_F1Setup;
+  pdu.choice.unsuccessfulOutcome->criticality   = F1AP_Criticality_reject;
+  pdu.choice.unsuccessfulOutcome->value.present = F1AP_UnsuccessfulOutcome__value_PR_F1SetupFailure;
+  out = &pdu.choice.unsuccessfulOutcome->value.choice.F1SetupFailure;
+
+  /* mandatory */
+  /* c1. Transaction ID (integer value)*/
+  ie = (F1AP_F1SetupFailureIEs_t *)calloc(1, sizeof(F1AP_F1SetupFailureIEs_t));
+  ie->id                        = F1AP_ProtocolIE_ID_id_TransactionID;
+  ie->criticality               = F1AP_Criticality_reject;
+  ie->value.present             = F1AP_F1SetupFailureIEs__value_PR_TransactionID;
+  ie->value.choice.TransactionID = F1AP_get_next_transaction_identifier(enb_mod_idP, cu_mod_idP);
+  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+
+  /* mandatory */
+  /* c2. Cause */
+  ie = (F1AP_F1SetupFailureIEs_t *)calloc(1, sizeof(F1AP_F1SetupFailureIEs_t));
+  ie->id                        = F1AP_ProtocolIE_ID_id_Cause;
+  ie->criticality               = F1AP_Criticality_ignore;
+  ie->value.present             = F1AP_F1SetupFailureIEs__value_PR_Cause;
+  ie->value.choice.Cause.present = F1AP_Cause_PR_radioNetwork;
+  ie->value.choice.Cause.choice.radioNetwork = F1AP_CauseRadioNetwork_unspecified;
+  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+
+  /* optional */
+  /* c3. TimeToWait */
+  if (0) {
+    ie = (F1AP_F1SetupFailureIEs_t *)calloc(1, sizeof(F1AP_F1SetupFailureIEs_t));
+    ie->id                        = F1AP_ProtocolIE_ID_id_TimeToWait;
+    ie->criticality               = F1AP_Criticality_ignore;
+    ie->value.present             = F1AP_F1SetupFailureIEs__value_PR_TimeToWait;
+    ie->value.choice.TimeToWait = F1AP_TimeToWait_v10s;
+    ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+  }
+
+  /* optional */
+  /* c4. CriticalityDiagnostics*/
+  if (0) {
+    ie = (F1AP_F1SetupFailureIEs_t *)calloc(1, sizeof(F1AP_F1SetupFailureIEs_t));
+    ie->id                        = F1AP_ProtocolIE_ID_id_CriticalityDiagnostics;
+    ie->criticality               = F1AP_Criticality_ignore;
+    ie->value.present             = F1AP_F1SetupFailureIEs__value_PR_CriticalityDiagnostics;
+    ie->value.choice.CriticalityDiagnostics.procedureCode = (F1AP_ProcedureCode_t *)calloc(1, sizeof(F1AP_ProcedureCode_t));
+    *ie->value.choice.CriticalityDiagnostics.procedureCode = F1AP_ProcedureCode_id_UEContextSetup;
+    ie->value.choice.CriticalityDiagnostics.triggeringMessage = (F1AP_TriggeringMessage_t *)calloc(1, sizeof(F1AP_TriggeringMessage_t));
+    *ie->value.choice.CriticalityDiagnostics.triggeringMessage = F1AP_TriggeringMessage_initiating_message;
+    ie->value.choice.CriticalityDiagnostics.procedureCriticality = (F1AP_Criticality_t *)calloc(1, sizeof(F1AP_Criticality_t));
+    *ie->value.choice.CriticalityDiagnostics.procedureCriticality = F1AP_Criticality_reject;
+    ie->value.choice.CriticalityDiagnostics.transactionID = (F1AP_TransactionID_t *)calloc(1, sizeof(F1AP_TransactionID_t));
+    *ie->value.choice.CriticalityDiagnostics.transactionID = 0;
+    ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+  }
+
+  /* encode */
+  if (f1ap_encode_pdu(&pdu, &buffer, &len) < 0) {
+    LOG_E(F1AP, "Failed to encode F1 setup request\n");
+    return -1;
+  }
+
+  cu_f1ap_itti_send_sctp_data_req(instance, f1ap_du_data_from_du->assoc_id, buffer, len, 0);
+
+  return 0;
+}
+
+
+
+/*
+    gNB-DU Configuration Update
+*/
+
+int CU_handle_gNB_DU_CONFIGURATION_UPDATE(instance_t instance,
+                                           uint32_t assoc_id,
+                                           uint32_t stream,
+                                           F1AP_F1AP_PDU_t *pdu) {
+  AssertFatal(1==0,"Not implemented yet\n");
+}
+
+int CU_send_gNB_DU_CONFIGURATION_FAILURE(instance_t instance,
+                    F1AP_GNBDUConfigurationUpdateFailure_t *GNBDUConfigurationUpdateFailure) {
+  AssertFatal(1==0,"Not implemented yet\n");
+}
+
+int CU_send_gNB_DU_CONFIGURATION_UPDATE_ACKNOWLEDGE(instance_t instance,
+                    F1AP_GNBDUConfigurationUpdateAcknowledge_t *GNBDUConfigurationUpdateAcknowledge) {
+  AssertFatal(1==0,"Not implemented yet\n");
+}
+
+
+
+/*
+    gNB-CU Configuration Update
+*/
+
+//void CU_send_gNB_CU_CONFIGURATION_UPDATE(F1AP_GNBCUConfigurationUpdate_t *GNBCUConfigurationUpdate) {
+int CU_send_gNB_CU_CONFIGURATION_UPDATE(instance_t instance, module_id_t du_mod_idP) {
+  F1AP_F1AP_PDU_t                    pdu;
+  F1AP_GNBCUConfigurationUpdate_t    *out;
+  F1AP_GNBCUConfigurationUpdateIEs_t *ie;
+
+  uint8_t  *buffer;
+  uint32_t  len;
+  int       i = 0;
+
+  // for test
+  int mcc = 208;
+  int mnc = 93;
+  int mnc_digit_length = 8;
+
+  /* Create */
+  /* 0. Message Type */
+  memset(&pdu, 0, sizeof(pdu));
+  pdu.present = F1AP_F1AP_PDU_PR_initiatingMessage;
+  pdu.choice.initiatingMessage = (F1AP_InitiatingMessage_t *)calloc(1, sizeof(F1AP_InitiatingMessage_t));
+  pdu.choice.initiatingMessage->procedureCode = F1AP_ProcedureCode_id_gNBCUConfigurationUpdate;
+  pdu.choice.initiatingMessage->criticality   = F1AP_Criticality_ignore;
+  pdu.choice.initiatingMessage->value.present = F1AP_InitiatingMessage__value_PR_GNBCUConfigurationUpdate;
+  out = &pdu.choice.initiatingMessage->value.choice.GNBCUConfigurationUpdate;
+
+  /* mandatory */
+  /* c1. Transaction ID (integer value) */
+  ie = (F1AP_GNBCUConfigurationUpdateIEs_t *)calloc(1, sizeof(F1AP_GNBCUConfigurationUpdateIEs_t));
+  ie->id                        = F1AP_ProtocolIE_ID_id_TransactionID;
+  ie->criticality               = F1AP_Criticality_reject;
+  ie->value.present             = F1AP_GNBCUConfigurationUpdateIEs__value_PR_TransactionID;
+  ie->value.choice.TransactionID = F1AP_get_next_transaction_identifier(instance, du_mod_idP);
+  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+
+
+
+  /* mandatory */
+  /* c2. Cells_to_be_Activated_List */
+  ie = (F1AP_GNBCUConfigurationUpdateIEs_t *)calloc(1, sizeof(F1AP_GNBCUConfigurationUpdateIEs_t));
+  ie->id                        = F1AP_ProtocolIE_ID_id_Cells_to_be_Activated_List;
+  ie->criticality               = F1AP_Criticality_reject;
+  ie->value.present             = F1AP_GNBCUConfigurationUpdateIEs__value_PR_Cells_to_be_Activated_List;
+
+  for (i=0;
+       i<1;
+       i++) {
+
+       F1AP_Cells_to_be_Activated_List_ItemIEs_t *cells_to_be_activated_list_item_ies;
+       cells_to_be_activated_list_item_ies = (F1AP_Cells_to_be_Activated_List_ItemIEs_t *)calloc(1, sizeof(F1AP_Cells_to_be_Activated_List_ItemIEs_t));
+       cells_to_be_activated_list_item_ies->id = F1AP_ProtocolIE_ID_id_Cells_to_be_Activated_List_Item;
+       cells_to_be_activated_list_item_ies->criticality = F1AP_Criticality_reject;
+       cells_to_be_activated_list_item_ies->value.present = F1AP_Cells_to_be_Activated_List_ItemIEs__value_PR_Cells_to_be_Activated_List_Item;
+
+     /* 2.1 cells to be Activated list item */
+     F1AP_Cells_to_be_Activated_List_Item_t cells_to_be_activated_list_item;
+     memset((void *)&cells_to_be_activated_list_item, 0, sizeof(F1AP_Cells_to_be_Activated_List_Item_t));
+
+     /* - nRCGI */
+     F1AP_NRCGI_t nRCGI;
+     MCC_MNC_TO_PLMNID(mcc, mnc, mnc_digit_length,
+                                         &nRCGI.pLMN_Identity);
+     NR_CELL_ID_TO_BIT_STRING(123456, &nRCGI.nRCellIdentity);
+     cells_to_be_activated_list_item.nRCGI = nRCGI;
+
+     /* optional */
+     /* - nRPCI */
+     if (0) {
+       cells_to_be_activated_list_item.nRPCI = (F1AP_NRPCI_t *)calloc(1, sizeof(F1AP_NRPCI_t));
+       *cells_to_be_activated_list_item.nRPCI = 321L;  // int 0..1007
+     }
+
+     /* optional */
+     /* - gNB-CU System Information */
+     //if (1) {
+
+     //}
+     /* ADD */
+     cells_to_be_activated_list_item_ies->value.choice.Cells_to_be_Activated_List_Item = cells_to_be_activated_list_item;
+     ASN_SEQUENCE_ADD(&ie->value.choice.Cells_to_be_Activated_List.list,
+                      cells_to_be_activated_list_item_ies);
+  }  
+  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+
+
+
+  /* mandatory */
+  /* c3. Cells_to_be_Deactivated_List */
+  ie = (F1AP_GNBCUConfigurationUpdateIEs_t *)calloc(1, sizeof(F1AP_GNBCUConfigurationUpdateIEs_t));
+  ie->id                        = F1AP_ProtocolIE_ID_id_Cells_to_be_Deactivated_List;
+  ie->criticality               = F1AP_Criticality_reject;
+  ie->value.present             = F1AP_GNBCUConfigurationUpdateIEs__value_PR_Cells_to_be_Deactivated_List;
+
+  for (i=0;
+       i<1;
+       i++) {
+
+       F1AP_Cells_to_be_Deactivated_List_ItemIEs_t *cells_to_be_deactivated_list_item_ies;
+       cells_to_be_deactivated_list_item_ies = (F1AP_Cells_to_be_Deactivated_List_ItemIEs_t *)calloc(1, sizeof(F1AP_Cells_to_be_Deactivated_List_ItemIEs_t));
+       cells_to_be_deactivated_list_item_ies->id = F1AP_ProtocolIE_ID_id_Cells_to_be_Activated_List_Item;
+       cells_to_be_deactivated_list_item_ies->criticality = F1AP_Criticality_reject;
+       cells_to_be_deactivated_list_item_ies->value.present = F1AP_Cells_to_be_Deactivated_List_ItemIEs__value_PR_Cells_to_be_Deactivated_List_Item;
+
+       /* 3.1 cells to be Deactivated list item */
+       F1AP_Cells_to_be_Deactivated_List_Item_t cells_to_be_deactivated_list_item;
+       memset((void *)&cells_to_be_deactivated_list_item, 0, sizeof(F1AP_Cells_to_be_Deactivated_List_Item_t));
+
+       /* - nRCGI */
+       F1AP_NRCGI_t nRCGI;
+       MCC_MNC_TO_PLMNID(mcc, mnc, mnc_digit_length,
+                                           &nRCGI.pLMN_Identity);
+       NR_CELL_ID_TO_BIT_STRING(123456, &nRCGI.nRCellIdentity);
+       cells_to_be_deactivated_list_item.nRCGI = nRCGI;
+
+       //}
+       /* ADD */
+       cells_to_be_deactivated_list_item_ies->value.choice.Cells_to_be_Deactivated_List_Item = cells_to_be_deactivated_list_item;
+       ASN_SEQUENCE_ADD(&ie->value.choice.Cells_to_be_Deactivated_List.list,
+                        cells_to_be_deactivated_list_item_ies);
+  }  
+  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+
+
+  /* mandatory */
+  /* c4. GNB_CU_TNL_Association_To_Add_List */
+  ie = (F1AP_GNBCUConfigurationUpdateIEs_t *)calloc(1, sizeof(F1AP_GNBCUConfigurationUpdateIEs_t));
+  ie->id                        = F1AP_ProtocolIE_ID_id_GNB_CU_TNL_Association_To_Add_List;
+  ie->criticality               = F1AP_Criticality_reject;
+  ie->value.present             = F1AP_GNBCUConfigurationUpdateIEs__value_PR_GNB_CU_TNL_Association_To_Add_List;
+
+  for (i=0;
+       i<1;
+       i++) {
+
+       F1AP_GNB_CU_TNL_Association_To_Add_ItemIEs_t *gnb_cu_tnl_association_to_add_item_ies;
+       gnb_cu_tnl_association_to_add_item_ies = (F1AP_GNB_CU_TNL_Association_To_Add_ItemIEs_t *)calloc(1, sizeof(F1AP_GNB_CU_TNL_Association_To_Add_ItemIEs_t));
+       gnb_cu_tnl_association_to_add_item_ies->id = F1AP_ProtocolIE_ID_id_GNB_CU_TNL_Association_To_Add_Item;
+       gnb_cu_tnl_association_to_add_item_ies->criticality = F1AP_Criticality_reject;
+       gnb_cu_tnl_association_to_add_item_ies->value.present = F1AP_GNB_CU_TNL_Association_To_Add_ItemIEs__value_PR_GNB_CU_TNL_Association_To_Add_Item;
+
+       /* 4.1 GNB_CU_TNL_Association_To_Add_Item */
+       F1AP_GNB_CU_TNL_Association_To_Add_Item_t gnb_cu_tnl_association_to_add_item;
+       memset((void *)&gnb_cu_tnl_association_to_add_item, 0, sizeof(F1AP_GNB_CU_TNL_Association_To_Add_Item_t));
+
+
+       /* 4.1.1 tNLAssociationTransportLayerAddress */
+       F1AP_CP_TransportLayerAddress_t transportLayerAddress;
+       memset((void *)&transportLayerAddress, 0, sizeof(F1AP_CP_TransportLayerAddress_t));
+       transportLayerAddress.present = F1AP_CP_TransportLayerAddress_PR_endpoint_IP_address;
+       TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(1234, &transportLayerAddress.choice.endpoint_IP_address);
+       
+       // memset((void *)&transportLayerAddress, 0, sizeof(F1AP_CP_TransportLayerAddress_t));
+       // transportLayerAddress.present = F1AP_CP_TransportLayerAddress_PR_endpoint_IP_address_and_port;
+       // transportLayerAddress.choice.endpoint_IP_address_and_port = (F1AP_Endpoint_IP_address_and_port_t *)calloc(1, sizeof(F1AP_Endpoint_IP_address_and_port_t));
+       // TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(1234, &transportLayerAddress.choice.endpoint_IP_address_and_port.endpoint_IP_address);
+
+       gnb_cu_tnl_association_to_add_item.tNLAssociationTransportLayerAddress = transportLayerAddress;
+
+       /* 4.1.2 tNLAssociationUsage */
+       gnb_cu_tnl_association_to_add_item.tNLAssociationUsage = F1AP_TNLAssociationUsage_non_ue;
+       
+
+       /* ADD */
+       gnb_cu_tnl_association_to_add_item_ies->value.choice.GNB_CU_TNL_Association_To_Add_Item = gnb_cu_tnl_association_to_add_item;
+       ASN_SEQUENCE_ADD(&ie->value.choice.GNB_CU_TNL_Association_To_Add_List.list,
+                        gnb_cu_tnl_association_to_add_item_ies);
+  }  
+  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+
+
+
+  /* mandatory */
+  /* c5. GNB_CU_TNL_Association_To_Remove_List */
+  ie = (F1AP_GNBCUConfigurationUpdateIEs_t *)calloc(1, sizeof(F1AP_GNBCUConfigurationUpdateIEs_t));
+  ie->id                        = F1AP_ProtocolIE_ID_id_GNB_CU_TNL_Association_To_Remove_List;
+  ie->criticality               = F1AP_Criticality_reject;
+  ie->value.present             = F1AP_GNBCUConfigurationUpdateIEs__value_PR_GNB_CU_TNL_Association_To_Remove_List;
+  for (i=0;
+       i<1;
+       i++) {
+
+       F1AP_GNB_CU_TNL_Association_To_Remove_ItemIEs_t *gnb_cu_tnl_association_to_remove_item_ies;
+       gnb_cu_tnl_association_to_remove_item_ies = (F1AP_GNB_CU_TNL_Association_To_Remove_ItemIEs_t *)calloc(1, sizeof(F1AP_GNB_CU_TNL_Association_To_Remove_ItemIEs_t));
+       gnb_cu_tnl_association_to_remove_item_ies->id = F1AP_ProtocolIE_ID_id_GNB_CU_TNL_Association_To_Remove_Item;
+       gnb_cu_tnl_association_to_remove_item_ies->criticality = F1AP_Criticality_reject;
+       gnb_cu_tnl_association_to_remove_item_ies->value.present = F1AP_GNB_CU_TNL_Association_To_Remove_ItemIEs__value_PR_GNB_CU_TNL_Association_To_Remove_Item;
+
+       /* 4.1 GNB_CU_TNL_Association_To_Remove_Item */
+       F1AP_GNB_CU_TNL_Association_To_Remove_Item_t gnb_cu_tnl_association_to_remove_item;
+       memset((void *)&gnb_cu_tnl_association_to_remove_item, 0, sizeof(F1AP_GNB_CU_TNL_Association_To_Remove_Item_t));
+
+
+       /* 4.1.1 tNLAssociationTransportLayerAddress */
+       F1AP_CP_TransportLayerAddress_t transportLayerAddress;
+       memset((void *)&transportLayerAddress, 0, sizeof(F1AP_CP_TransportLayerAddress_t));
+       transportLayerAddress.present = F1AP_CP_TransportLayerAddress_PR_endpoint_IP_address;
+       TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(1234, &transportLayerAddress.choice.endpoint_IP_address);
+       
+       // memset((void *)&transportLayerAddress, 0, sizeof(F1AP_CP_TransportLayerAddress_t));
+       // transportLayerAddress.present = F1AP_CP_TransportLayerAddress_PR_endpoint_IP_address_and_port;
+       // transportLayerAddress.choice.endpoint_IP_address_and_port = (F1AP_Endpoint_IP_address_and_port_t *)calloc(1, sizeof(F1AP_Endpoint_IP_address_and_port_t));
+       // TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(1234, &transportLayerAddress.choice.endpoint_IP_address_and_port.endpoint_IP_address);
+
+       gnb_cu_tnl_association_to_remove_item.tNLAssociationTransportLayerAddress = transportLayerAddress;
+   
+
+       /* ADD */
+       gnb_cu_tnl_association_to_remove_item_ies->value.choice.GNB_CU_TNL_Association_To_Remove_Item = gnb_cu_tnl_association_to_remove_item;
+       ASN_SEQUENCE_ADD(&ie->value.choice.GNB_CU_TNL_Association_To_Remove_List.list,
+                        gnb_cu_tnl_association_to_remove_item_ies);
+  }  
+  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+
+  /* mandatory */
+  /* c6. GNB_CU_TNL_Association_To_Update_List */
+  ie = (F1AP_GNBCUConfigurationUpdateIEs_t *)calloc(1, sizeof(F1AP_GNBCUConfigurationUpdateIEs_t));
+  ie->id                        = F1AP_ProtocolIE_ID_id_GNB_CU_TNL_Association_To_Update_List;
+  ie->criticality               = F1AP_Criticality_reject;
+  ie->value.present             = F1AP_GNBCUConfigurationUpdateIEs__value_PR_GNB_CU_TNL_Association_To_Update_List;
+  for (i=0;
+       i<1;
+       i++) {
+
+       F1AP_GNB_CU_TNL_Association_To_Update_ItemIEs_t *gnb_cu_tnl_association_to_update_item_ies;
+       gnb_cu_tnl_association_to_update_item_ies = (F1AP_GNB_CU_TNL_Association_To_Update_ItemIEs_t *)calloc(1, sizeof(F1AP_GNB_CU_TNL_Association_To_Update_ItemIEs_t));
+       gnb_cu_tnl_association_to_update_item_ies->id = F1AP_ProtocolIE_ID_id_GNB_CU_TNL_Association_To_Update_Item;
+       gnb_cu_tnl_association_to_update_item_ies->criticality = F1AP_Criticality_reject;
+       gnb_cu_tnl_association_to_update_item_ies->value.present = F1AP_GNB_CU_TNL_Association_To_Update_ItemIEs__value_PR_GNB_CU_TNL_Association_To_Update_Item;
+
+       /* 4.1 GNB_CU_TNL_Association_To_Update_Item */
+       F1AP_GNB_CU_TNL_Association_To_Update_Item_t gnb_cu_tnl_association_to_update_item;
+       memset((void *)&gnb_cu_tnl_association_to_update_item, 0, sizeof(F1AP_GNB_CU_TNL_Association_To_Update_Item_t));
+
+
+       /* 4.1.1 tNLAssociationTransportLayerAddress */
+       F1AP_CP_TransportLayerAddress_t transportLayerAddress;
+       memset((void *)&transportLayerAddress, 0, sizeof(F1AP_CP_TransportLayerAddress_t));
+       transportLayerAddress.present = F1AP_CP_TransportLayerAddress_PR_endpoint_IP_address;
+       TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(1234, &transportLayerAddress.choice.endpoint_IP_address);
+       
+       // memset((void *)&transportLayerAddress, 0, sizeof(F1AP_CP_TransportLayerAddress_t));
+       // transportLayerAddress.present = F1AP_CP_TransportLayerAddress_PR_endpoint_IP_address_and_port;
+       // transportLayerAddress.choice.endpoint_IP_address_and_port = (F1AP_Endpoint_IP_address_and_port_t *)calloc(1, sizeof(F1AP_Endpoint_IP_address_and_port_t));
+       // TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(1234, &transportLayerAddress.choice.endpoint_IP_address_and_port.endpoint_IP_address);
+
+       gnb_cu_tnl_association_to_update_item.tNLAssociationTransportLayerAddress = transportLayerAddress;
+   
+
+       /* 4.1.2 tNLAssociationUsage */
+       if (1) {
+         gnb_cu_tnl_association_to_update_item.tNLAssociationUsage = (F1AP_TNLAssociationUsage_t *)calloc(1, sizeof(F1AP_TNLAssociationUsage_t));
+         *gnb_cu_tnl_association_to_update_item.tNLAssociationUsage = F1AP_TNLAssociationUsage_non_ue;
+       }
+       
+       /* ADD */
+       gnb_cu_tnl_association_to_update_item_ies->value.choice.GNB_CU_TNL_Association_To_Update_Item = gnb_cu_tnl_association_to_update_item;
+       ASN_SEQUENCE_ADD(&ie->value.choice.GNB_CU_TNL_Association_To_Update_List.list,
+                        gnb_cu_tnl_association_to_update_item_ies);
+  }  
+  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+
+
+
+  /* mandatory */
+  /* c7. Cells_to_be_Barred_List */
+  ie = (F1AP_GNBCUConfigurationUpdateIEs_t *)calloc(1, sizeof(F1AP_GNBCUConfigurationUpdateIEs_t));
+  ie->id                        = F1AP_ProtocolIE_ID_id_Cells_to_be_Barred_List;
+  ie->criticality               = F1AP_Criticality_reject;
+  ie->value.present             = F1AP_GNBCUConfigurationUpdateIEs__value_PR_Cells_to_be_Barred_List;
+  for (i=0;
+       i<1;
+       i++) {
+
+       F1AP_Cells_to_be_Barred_ItemIEs_t *cells_to_be_barred_item_ies;
+       cells_to_be_barred_item_ies = (F1AP_Cells_to_be_Barred_ItemIEs_t *)calloc(1, sizeof(F1AP_Cells_to_be_Barred_ItemIEs_t));
+       cells_to_be_barred_item_ies->id = F1AP_ProtocolIE_ID_id_Cells_to_be_Activated_List_Item;
+       cells_to_be_barred_item_ies->criticality = F1AP_Criticality_reject;
+       cells_to_be_barred_item_ies->value.present = F1AP_Cells_to_be_Barred_ItemIEs__value_PR_Cells_to_be_Barred_Item;
+
+       /* 7.1 cells to be Deactivated list item */
+       F1AP_Cells_to_be_Barred_Item_t cells_to_be_barred_item;
+       memset((void *)&cells_to_be_barred_item, 0, sizeof(F1AP_Cells_to_be_Barred_Item_t));
+
+       /* - nRCGI */
+       F1AP_NRCGI_t nRCGI;
+       MCC_MNC_TO_PLMNID(mcc, mnc, mnc_digit_length,
+                                           &nRCGI.pLMN_Identity);
+       NR_CELL_ID_TO_BIT_STRING(123456, &nRCGI.nRCellIdentity);
+       cells_to_be_barred_item.nRCGI = nRCGI;
+       
+       /* 7.2 cellBarred*/
+       cells_to_be_barred_item.cellBarred = F1AP_CellBarred_not_barred;
+
+       /* ADD */
+       cells_to_be_barred_item_ies->value.choice.Cells_to_be_Barred_Item = cells_to_be_barred_item;
+       ASN_SEQUENCE_ADD(&ie->value.choice.Cells_to_be_Barred_List.list,
+                        cells_to_be_barred_item_ies);
+  }
+  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+
+
+
+  /* mandatory */
+  /* c8. Protected_EUTRA_Resources_List */
+  ie = (F1AP_GNBCUConfigurationUpdateIEs_t *)calloc(1, sizeof(F1AP_GNBCUConfigurationUpdateIEs_t));
+  ie->id                        = F1AP_ProtocolIE_ID_id_Protected_EUTRA_Resources_List;
+  ie->criticality               = F1AP_Criticality_reject;
+  ie->value.present             = F1AP_GNBCUConfigurationUpdateIEs__value_PR_Protected_EUTRA_Resources_List;
+
+  for (i=0;
+       i<1;
+       i++) {
+
+
+       F1AP_Protected_EUTRA_Resources_ItemIEs_t *protected_eutra_resources_item_ies;
+
+       /* 8.1 SpectrumSharingGroupID */
+       protected_eutra_resources_item_ies = (F1AP_Protected_EUTRA_Resources_ItemIEs_t *)calloc(1, sizeof(F1AP_Protected_EUTRA_Resources_ItemIEs_t));
+       protected_eutra_resources_item_ies->id = F1AP_ProtocolIE_ID_id_Protected_EUTRA_Resources_List;
+       protected_eutra_resources_item_ies->criticality = F1AP_Criticality_reject;
+       protected_eutra_resources_item_ies->value.present = F1AP_Protected_EUTRA_Resources_ItemIEs__value_PR_SpectrumSharingGroupID;
+       protected_eutra_resources_item_ies->value.choice.SpectrumSharingGroupID = 1L;
+
+       ASN_SEQUENCE_ADD(&ie->value.choice.Protected_EUTRA_Resources_List.list, protected_eutra_resources_item_ies);
+
+       /* 8.2 ListofEUTRACellsinGNBDUCoordination */
+       protected_eutra_resources_item_ies = (F1AP_Protected_EUTRA_Resources_ItemIEs_t *)calloc(1, sizeof(F1AP_Protected_EUTRA_Resources_ItemIEs_t));
+       protected_eutra_resources_item_ies->id = F1AP_ProtocolIE_ID_id_Protected_EUTRA_Resources_List;
+       protected_eutra_resources_item_ies->criticality = F1AP_Criticality_reject;
+       protected_eutra_resources_item_ies->value.present = F1AP_Protected_EUTRA_Resources_ItemIEs__value_PR_ListofEUTRACellsinGNBDUCoordination;
+
+       F1AP_Served_EUTRA_Cells_Information_t served_eutra_cells_information;
+       memset((void *)&served_eutra_cells_information, 0, sizeof(F1AP_Served_EUTRA_Cells_Information_t));
+
+       F1AP_EUTRA_Mode_Info_t eUTRA_Mode_Info;
+       memset((void *)&eUTRA_Mode_Info, 0, sizeof(F1AP_EUTRA_Mode_Info_t));
+
+       // eUTRAFDD
+       eUTRA_Mode_Info.present = F1AP_EUTRA_Mode_Info_PR_eUTRAFDD;
+       F1AP_EUTRA_FDD_Info_t *eutra_fdd_info;
+       eutra_fdd_info = (F1AP_EUTRA_FDD_Info_t *)calloc(1, sizeof(F1AP_EUTRA_FDD_Info_t));
+       eutra_fdd_info->uL_offsetToPointA = 123L;
+       eutra_fdd_info->dL_offsetToPointA = 456L;
+       eUTRA_Mode_Info.choice.eUTRAFDD = eutra_fdd_info;
+
+       // eUTRATDD
+       // eUTRA_Mode_Info.present = F1AP_EUTRA_Mode_Info_PR_eUTRATDD;
+       // F1AP_EUTRA_TDD_Info_t *eutra_tdd_info;
+       // eutra_tdd_info = (F1AP_EUTRA_TDD_Info_t *)calloc(1, sizeof(F1AP_EUTRA_TDD_Info_t));
+       // eutra_tdd_info->uL_offsetToPointA = 123L;
+       // eutra_tdd_info->dL_offsetToPointA = 456L;
+       // eUTRA_Mode_Info.choice.eUTRATDD = eutra_tdd_info;
+
+       served_eutra_cells_information.eUTRA_Mode_Info = eUTRA_Mode_Info;
+
+       OCTET_STRING_fromBuf(&served_eutra_cells_information.protectedEUTRAResourceIndication, "asdsa1d32sa1d31asd31as",
+                       strlen("asdsa1d32sa1d31asd31as"));
+
+       ASN_SEQUENCE_ADD(&protected_eutra_resources_item_ies->value.choice.ListofEUTRACellsinGNBDUCoordination.list, &served_eutra_cells_information);
+
+       ASN_SEQUENCE_ADD(&ie->value.choice.Protected_EUTRA_Resources_List.list, protected_eutra_resources_item_ies);
+  }
+  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+
+
+  /* encode */
+  if (f1ap_encode_pdu(&pdu, &buffer, &len) < 0) {
+    LOG_E(F1AP, "Failed to encode F1 setup request\n");
+    return -1;
+  }
+
+  cu_f1ap_itti_send_sctp_data_req(instance, f1ap_du_data_from_du->assoc_id, buffer, len, 0);
+  return 0;
+}
+
+int CU_handle_gNB_CU_CONFIGURATION_UPDATE_FAILURE(instance_t instance,
+                                                   uint32_t assoc_id,
+                                                   uint32_t stream,
+                                                   F1AP_F1AP_PDU_t *pdu) {
+  AssertFatal(1==0,"Not implemented yet\n");
+}
+
+int CU_handle_gNB_CU_CONFIGURATION_UPDATE_ACKNOWLEDGE(instance_t instance,
+                                                       uint32_t assoc_id,
+                                                       uint32_t stream,
+                                                       F1AP_F1AP_PDU_t *pdu) {
+  AssertFatal(1==0,"Not implemented yet\n");
+}
+
+
+int CU_handle_gNB_DU_RESOURCE_COORDINATION_REQUEST(instance_t instance,
+                                                    uint32_t assoc_id,
+                                                    uint32_t stream,
+                                                    F1AP_F1AP_PDU_t *pdu) {
+  AssertFatal(0, "Not implemented yet\n");
+}
+
+int CU_send_gNB_DU_RESOURCE_COORDINATION_RESPONSE(instance_t instance,
+                    F1AP_GNBDUResourceCoordinationResponse_t *GNBDUResourceCoordinationResponse) {
+  AssertFatal(0, "Not implemented yet\n");
+}
diff --git a/openair2/F1AP/f1ap_cu_interface_management.h b/openair2/F1AP/f1ap_cu_interface_management.h
new file mode 100644
index 0000000000000000000000000000000000000000..acad13836dea4e8043791945cb853fa3551d30ec
--- /dev/null
+++ b/openair2/F1AP/f1ap_cu_interface_management.h
@@ -0,0 +1,111 @@
+/*
+ * 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
+ */
+
+/*! \file f1ap_cu_interface_management.h
+ * \brief f1ap interface management for CU
+ * \author EURECOM/NTUST
+ * \date 2018
+ * \version 0.1
+ * \company Eurecom
+ * \email: navid.nikaein@eurecom.fr, bing-kai.hong@eurecom.fr
+ * \note
+ * \warning
+ */
+
+#ifndef F1AP_CU_INTERFACE_MANAGEMENT_H_
+#define F1AP_CU_INTERFACE_MANAGEMENT_H_
+
+/*
+ * Reset
+ */
+int CU_send_RESET(instance_t instance, F1AP_Reset_t *Reset);
+int CU_handle_RESET_ACKKNOWLEDGE(instance_t instance,
+                                 uint32_t assoc_id,
+                                 uint32_t stream,
+                                 F1AP_F1AP_PDU_t *pdu);
+int CU_handle_RESET(instance_t instance,
+                    uint32_t assoc_id,
+                    uint32_t stream,
+                    F1AP_F1AP_PDU_t *pdu);
+int CU_send_RESET_ACKNOWLEDGE(instance_t instance, F1AP_ResetAcknowledge_t *ResetAcknowledge);
+
+/*
+ * Error Indication
+ */
+int CU_handle_ERROR_INDICATION(instance_t instance,
+                               uint32_t assoc_id,
+                               uint32_t stream,
+                               F1AP_F1AP_PDU_t *pdu);
+int CU_send_ERROR_INDICATION(instance_t instance, F1AP_ErrorIndication_t *ErrorIndication);
+
+/*
+ * F1 Setup
+ */
+int CU_handle_F1_SETUP_REQUEST(instance_t instance,
+                               uint32_t assoc_id,
+                               uint32_t stream,
+                               F1AP_F1AP_PDU_t *pdu);
+
+int CU_send_F1_SETUP_RESPONSE(instance_t instance, f1ap_setup_resp_t *f1ap_setup_resp);
+
+int CU_send_F1_SETUP_FAILURE(instance_t instance);
+
+/*
+ * gNB-DU Configuration Update
+ */
+int CU_handle_gNB_DU_CONFIGURATION_UPDATE(instance_t instance,
+                                          uint32_t assoc_id,
+                                          uint32_t stream,
+                                          F1AP_F1AP_PDU_t *pdu);
+
+int CU_send_gNB_DU_CONFIGURATION_FAILURE(instance_t instance,
+                    F1AP_GNBDUConfigurationUpdateFailure_t *GNBDUConfigurationUpdateFailure);
+
+int CU_send_gNB_DU_CONFIGURATION_UPDATE_ACKNOWLEDGE(instance_t instance,
+                    F1AP_GNBDUConfigurationUpdateAcknowledge_t *GNBDUConfigurationUpdateAcknowledge);
+
+/*
+ * gNB-CU Configuration Update
+ */
+int CU_send_gNB_CU_CONFIGURATION_UPDATE(instance_t instance, module_id_t du_mod_idP);
+
+int CU_handle_gNB_CU_CONFIGURATION_UPDATE_FAILURE(instance_t instance,
+                                                  uint32_t assoc_id,
+                                                  uint32_t stream,
+                                                  F1AP_F1AP_PDU_t *pdu);
+
+int CU_handle_gNB_CU_CONFIGURATION_UPDATE_ACKNOWLEDGE(instance_t instance,
+                                                      uint32_t assoc_id,
+                                                      uint32_t stream,
+                                                      F1AP_F1AP_PDU_t *pdu);
+
+/*
+ * gNB-DU Resource Coordination
+ */
+int CU_handle_gNB_DU_RESOURCE_COORDINATION_REQUEST(instance_t instance,
+                                                   uint32_t assoc_id,
+                                                   uint32_t stream,
+                                                   F1AP_F1AP_PDU_t *pdu);
+
+int CU_send_gNB_DU_RESOURCE_COORDINATION_RESPONSE(instance_t instance,
+                    F1AP_GNBDUResourceCoordinationResponse_t *GNBDUResourceCoordinationResponse);
+
+#endif /* F1AP_CU_INTERFACE_MANAGEMENT_H_ */
diff --git a/openair2/F1AP/f1ap_cu_paging.c b/openair2/F1AP/f1ap_cu_paging.c
new file mode 100644
index 0000000000000000000000000000000000000000..b6bbedba2f0ed9c62704a0f9fdcf52c3e182ed60
--- /dev/null
+++ b/openair2/F1AP/f1ap_cu_paging.c
@@ -0,0 +1,31 @@
+/*
+ * 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
+ */
+
+/*! \file f1ap_du_interface_management.h
+ * \brief f1ap interface management for DU
+ * \author EURECOM/NTUST
+ * \date 2018
+ * \version 0.1
+ * \company Eurecom
+ * \email: navid.nikaein@eurecom.fr, bing-kai.hong@eurecom.fr
+ * \note
+ * \warning
+ */
\ No newline at end of file
diff --git a/openair2/F1AP/f1ap_cu_paging.h b/openair2/F1AP/f1ap_cu_paging.h
new file mode 100644
index 0000000000000000000000000000000000000000..b6bbedba2f0ed9c62704a0f9fdcf52c3e182ed60
--- /dev/null
+++ b/openair2/F1AP/f1ap_cu_paging.h
@@ -0,0 +1,31 @@
+/*
+ * 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
+ */
+
+/*! \file f1ap_du_interface_management.h
+ * \brief f1ap interface management for DU
+ * \author EURECOM/NTUST
+ * \date 2018
+ * \version 0.1
+ * \company Eurecom
+ * \email: navid.nikaein@eurecom.fr, bing-kai.hong@eurecom.fr
+ * \note
+ * \warning
+ */
\ No newline at end of file
diff --git a/openair2/F1AP/f1ap_cu_rrc_message_transfer.c b/openair2/F1AP/f1ap_cu_rrc_message_transfer.c
new file mode 100644
index 0000000000000000000000000000000000000000..f32d5c8ed06b5717c6ea21c9772b5021901ba9e5
--- /dev/null
+++ b/openair2/F1AP/f1ap_cu_rrc_message_transfer.c
@@ -0,0 +1,388 @@
+/*
+ * 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
+ */
+
+/*! \file f1ap_cu_rrc_message_transfer.c
+ * \brief f1ap rrc message transfer for CU
+ * \author EURECOM/NTUST
+ * \date 2018
+ * \version 0.1
+ * \company Eurecom
+ * \email: navid.nikaein@eurecom.fr, bing-kai.hong@eurecom.fr
+ * \note
+ * \warning
+ */
+
+#include "f1ap_common.h"
+#include "f1ap_encoder.h"
+#include "f1ap_decoder.h"
+#include "f1ap_itti_messaging.h"
+#include "f1ap_cu_rrc_message_transfer.h"
+#include "common/ran_context.h"
+#include "openair3/UTILS/conversions.h"
+
+// undefine C_RNTI from
+// openair1/PHY/LTE_TRANSPORT/transport_common.h which
+// replaces in ie->value.choice.C_RNTI, causing
+// a compile error
+#undef C_RNTI 
+
+
+// Bing Kai: create CU and DU context, and put all the information there.
+uint64_t        du_ue_f1ap_id = 0;
+uint32_t        f1ap_assoc_id = 0;
+uint32_t        f1ap_stream = 0;
+
+
+extern f1ap_cudu_inst_t f1ap_cu_inst[MAX_eNB];
+
+/*
+    Initial UL RRC Message Transfer
+*/
+
+extern RAN_CONTEXT_t RC;
+
+int CU_handle_INITIAL_UL_RRC_MESSAGE_TRANSFER(instance_t             instance,
+                                              uint32_t               assoc_id,
+                                              uint32_t               stream,
+                                              F1AP_F1AP_PDU_t       *pdu) {
+
+  LOG_D(F1AP, "CU_handle_INITIAL_UL_RRC_MESSAGE_TRANSFER\n");
+  // decode the F1 message
+  // get the rrc message from the contauiner 
+  // call func rrc_eNB_decode_ccch: <-- needs some update here
+  MessageDef                            *message_p;
+  F1AP_InitialULRRCMessageTransfer_t    *container;
+  F1AP_InitialULRRCMessageTransferIEs_t *ie;
+  
+  rnti_t          rnti;
+  sdu_size_t      ccch_sdu_len;
+  int             CC_id =0;
+  
+
+  DevAssert(pdu != NULL);
+  
+  if (stream != 0) {
+    LOG_E(F1AP, "[SCTP %d] Received F1 on stream != 0 (%d)\n",
+          assoc_id, stream);
+    return -1;
+  }
+  // TODO: use context 
+  f1ap_stream    = stream;
+  f1ap_assoc_id = assoc_id;
+
+  container = &pdu->choice.initiatingMessage->value.choice.InitialULRRCMessageTransfer;
+
+  /* GNB_DU_UE_F1AP_ID */
+  F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_InitialULRRCMessageTransferIEs_t, ie, container,
+                             F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID, true);
+  du_ue_f1ap_id = ie->value.choice.GNB_DU_UE_F1AP_ID;
+  LOG_D(F1AP, "du_ue_f1ap_id %lu \n", du_ue_f1ap_id);
+
+  /* NRCGI 
+  * TODO: process NRCGI
+  */
+  F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_InitialULRRCMessageTransferIEs_t, ie, container,
+                             F1AP_ProtocolIE_ID_id_NRCGI, true);
+
+
+  uint64_t nr_cellid;
+  BIT_STRING_TO_NR_CELL_IDENTITY(&ie->value.choice.NRCGI.nRCellIdentity,nr_cellid);
+					       
+  /* RNTI */
+  F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_InitialULRRCMessageTransferIEs_t, ie, container,
+                             F1AP_ProtocolIE_ID_id_C_RNTI, true);
+  BUFFER_TO_INT16(ie->value.choice.C_RNTI.buf, rnti);
+
+  /* RRC Container */
+  F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_InitialULRRCMessageTransferIEs_t, ie, container,
+                             F1AP_ProtocolIE_ID_id_RRCContainer, true);
+
+  // create an ITTI message and copy SDU
+  message_p = itti_alloc_new_message (TASK_CU_F1, RRC_MAC_CCCH_DATA_IND);
+  memset (RRC_MAC_CCCH_DATA_IND (message_p).sdu, 0, CCCH_SDU_SIZE);
+  ccch_sdu_len = ie->value.choice.RRCContainer.size;
+  memcpy(RRC_MAC_CCCH_DATA_IND (message_p).sdu, ie->value.choice.RRCContainer.buf,
+         ccch_sdu_len);
+
+  //LOG_I(F1AP, "%s() RRCContainer (CCCH) size %ld: ", __func__,
+  //      ie->value.choice.RRCContainer.size);
+  //for (int i = 0; i < ie->value.choice.RRCContainer.size; i++)
+  //  printf("%02x ", RRC_MAC_CCCH_DATA_IND (message_p).sdu[i]);
+  //printf("\n");
+
+  // Find instance from nr_cellid
+  int rrc_inst = -1;
+  for (int i=0;i<RC.nb_inst;i++) {
+          // first get RRC instance (note, no the ITTI instance)
+    eNB_RRC_INST *rrc = RC.rrc[i];
+    if (rrc->nr_cellid == nr_cellid) {
+      rrc_inst = i; 
+      break;
+    }
+  }
+  AssertFatal(rrc_inst>=0,"couldn't find an RRC instance for nr_cell %llu\n",(unsigned long long int)nr_cellid);
+
+  int f1ap_uid = f1ap_add_ue(&f1ap_cu_inst[rrc_inst], rrc_inst, CC_id, 0, rnti);
+  if (f1ap_uid  < 0 ) {
+    LOG_E(F1AP, "Failed to add UE \n");
+    return -1;
+  }
+  f1ap_cu_inst[rrc_inst].f1ap_ue[f1ap_uid].du_ue_f1ap_id = du_ue_f1ap_id;
+
+
+  RRC_MAC_CCCH_DATA_IND (message_p).frame     = 0; 
+  RRC_MAC_CCCH_DATA_IND (message_p).sub_frame = 0;
+  RRC_MAC_CCCH_DATA_IND (message_p).sdu_size  = ccch_sdu_len;
+  RRC_MAC_CCCH_DATA_IND (message_p).enb_index = rrc_inst; // CU instance 
+  RRC_MAC_CCCH_DATA_IND (message_p).rnti      = rnti;
+  RRC_MAC_CCCH_DATA_IND (message_p).CC_id      = CC_id; 
+  itti_send_msg_to_task (TASK_RRC_ENB, instance, message_p);
+
+
+  return 0;
+}
+
+
+/*
+    DL RRC Message Transfer.
+*/
+
+//void CU_send_DL_RRC_MESSAGE_TRANSFER(F1AP_DLRRCMessageTransfer_t *DLRRCMessageTransfer) {
+int CU_send_DL_RRC_MESSAGE_TRANSFER(instance_t                instance,
+                                    f1ap_dl_rrc_message_t    *f1ap_dl_rrc)
+                                    {
+
+  F1AP_F1AP_PDU_t                 pdu; 
+  F1AP_DLRRCMessageTransfer_t    *out;
+  F1AP_DLRRCMessageTransferIEs_t *ie;
+
+  uint8_t  *buffer;
+  uint32_t  len;
+
+  /* Create */
+  /* 0. Message Type */ 
+  memset(&pdu, 0, sizeof(pdu));
+  pdu.present = F1AP_F1AP_PDU_PR_initiatingMessage;
+  pdu.choice.initiatingMessage = (F1AP_InitiatingMessage_t *)calloc(1, sizeof(F1AP_InitiatingMessage_t));
+  pdu.choice.initiatingMessage->procedureCode = F1AP_ProcedureCode_id_DLRRCMessageTransfer;
+  pdu.choice.initiatingMessage->criticality   = F1AP_Criticality_ignore;
+  pdu.choice.initiatingMessage->value.present = F1AP_InitiatingMessage__value_PR_DLRRCMessageTransfer;
+  out = &pdu.choice.initiatingMessage->value.choice.DLRRCMessageTransfer;
+  
+  /* mandatory */
+  /* c1. GNB_CU_UE_F1AP_ID */
+
+  ie = (F1AP_DLRRCMessageTransferIEs_t *)calloc(1, sizeof(F1AP_DLRRCMessageTransferIEs_t));
+  ie->id                             = F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID;
+  ie->criticality                    = F1AP_Criticality_reject;
+  ie->value.present                  = F1AP_DLRRCMessageTransferIEs__value_PR_GNB_CU_UE_F1AP_ID;
+  ie->value.choice.GNB_CU_UE_F1AP_ID = f1ap_get_cu_ue_f1ap_id(&f1ap_cu_inst[instance], f1ap_dl_rrc->rnti);
+  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+  LOG_I(F1AP, "Setting GNB_CU_UE_F1AP_ID %llu associated with UE RNTI %x (instance %d)\n",
+        (unsigned long long int)ie->value.choice.GNB_CU_UE_F1AP_ID, f1ap_dl_rrc->rnti, instance);
+
+
+  /* mandatory */
+  /* c2. GNB_DU_UE_F1AP_ID */
+  ie = (F1AP_DLRRCMessageTransferIEs_t *)calloc(1, sizeof(F1AP_DLRRCMessageTransferIEs_t));
+  ie->id                             = F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID;
+  ie->criticality                    = F1AP_Criticality_reject;
+  ie->value.present                  = F1AP_DLRRCMessageTransferIEs__value_PR_GNB_DU_UE_F1AP_ID;
+  ie->value.choice.GNB_DU_UE_F1AP_ID = f1ap_get_du_ue_f1ap_id(&f1ap_cu_inst[instance], f1ap_dl_rrc->rnti);
+  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+  LOG_I(F1AP, "GNB_DU_UE_F1AP_ID %llu associated with UE RNTI %x \n", (unsigned long long int)ie->value.choice.GNB_DU_UE_F1AP_ID, f1ap_dl_rrc->rnti);
+
+  /* optional */
+  /* c3. oldgNB_DU_UE_F1AP_ID */
+ /* if (f1ap_dl_rrc->old_gNB_DU_ue_id != 0xFFFFFFFF) {
+    ie = (F1AP_DLRRCMessageTransferIEs_t *)calloc(1, sizeof(F1AP_DLRRCMessageTransferIEs_t));
+    ie->id                                = F1AP_ProtocolIE_ID_id_oldgNB_DU_UE_F1AP_ID;
+    ie->criticality                       = F1AP_Criticality_reject;
+    ie->value.present                     = F1AP_DLRRCMessageTransferIEs__value_PR_NOTHING;
+    ie->value.choice.oldgNB_DU_UE_F1AP_ID = f1ap_dl_rrc->old_gNB_DU_ue_id;
+    ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+  }*/ 
+
+  /* mandatory */
+  /* c4. SRBID */
+  ie = (F1AP_DLRRCMessageTransferIEs_t *)calloc(1, sizeof(F1AP_DLRRCMessageTransferIEs_t));
+  ie->id                            = F1AP_ProtocolIE_ID_id_SRBID;
+  ie->criticality                   = F1AP_Criticality_reject;
+  ie->value.present                 = F1AP_DLRRCMessageTransferIEs__value_PR_SRBID;
+  ie->value.choice.SRBID            = f1ap_dl_rrc->srb_id;
+  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+
+  /* optional */
+  /* c5. ExecuteDuplication */
+  if (f1ap_dl_rrc->execute_duplication) {
+    ie = (F1AP_DLRRCMessageTransferIEs_t *)calloc(1, sizeof(F1AP_DLRRCMessageTransferIEs_t));
+    ie->id                            = F1AP_ProtocolIE_ID_id_ExecuteDuplication;
+    ie->criticality                   = F1AP_Criticality_ignore;
+    ie->value.present                 = F1AP_DLRRCMessageTransferIEs__value_PR_ExecuteDuplication;
+    ie->value.choice.ExecuteDuplication = F1AP_ExecuteDuplication_true;
+    ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+  }
+
+  // issue in here
+  /* mandatory */
+  /* c6. RRCContainer */
+  ie = (F1AP_DLRRCMessageTransferIEs_t *)calloc(1, sizeof(F1AP_DLRRCMessageTransferIEs_t));
+  ie->id                            = F1AP_ProtocolIE_ID_id_RRCContainer;
+  ie->criticality                   = F1AP_Criticality_reject;
+  ie->value.present                 = F1AP_DLRRCMessageTransferIEs__value_PR_RRCContainer;
+  OCTET_STRING_fromBuf(&ie->value.choice.RRCContainer, (const char*)f1ap_dl_rrc->rrc_container, f1ap_dl_rrc->rrc_container_length);
+  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+
+  //LOG_I(F1AP, "%s() RRCContainer size %d: ", __func__, f1ap_dl_rrc->rrc_container_length);
+  //for (int i = 0; i < ie->value.choice.RRCContainer.size; i++)
+  //  printf("%02x ", f1ap_dl_rrc->rrc_container[i]);
+  //printf("\n");
+
+  /* optional */
+  /* c7. RAT_FrequencyPriorityInformation */
+  /* TODO */ 
+  if (0) {
+    ie = (F1AP_DLRRCMessageTransferIEs_t *)calloc(1, sizeof(F1AP_DLRRCMessageTransferIEs_t));
+    ie->id                            = F1AP_ProtocolIE_ID_id_RAT_FrequencyPriorityInformation;
+    ie->criticality                   = F1AP_Criticality_reject;
+    ie->value.present                 = F1AP_DLRRCMessageTransferIEs__value_PR_RAT_FrequencyPriorityInformation;
+
+    ie->value.choice.RAT_FrequencyPriorityInformation.present = F1AP_RAT_FrequencyPriorityInformation_PR_subscriberProfileIDforRFP;
+    ie->value.choice.RAT_FrequencyPriorityInformation.choice.subscriberProfileIDforRFP = 123L;
+
+    //ie->value.choice.RAT_FrequencyPriorityInformation.present = F1AP_RAT_FrequencyPriorityInformation_PR_rAT_FrequencySelectionPriority;
+    //ie->value.choice.RAT_FrequencyPriorityInformation.choice.rAT_FrequencySelectionPriority = 123L;
+    ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+  }
+ 
+  /* encode */
+  if (f1ap_encode_pdu(&pdu, &buffer, &len) < 0) {
+    LOG_E(F1AP, "Failed to encode F1 setup request\n");
+    return -1;
+  }
+
+  cu_f1ap_itti_send_sctp_data_req(instance, f1ap_assoc_id /* BK: fix me*/ , buffer, len, 0 /* BK: fix me*/);
+
+  return 0;
+}
+
+/*
+    UL RRC Message Transfer
+*/
+
+int CU_handle_UL_RRC_MESSAGE_TRANSFER(instance_t       instance,
+                                      uint32_t         assoc_id,
+                                      uint32_t         stream,
+                                      F1AP_F1AP_PDU_t *pdu) {
+
+  LOG_D(F1AP, "CU_handle_UL_RRC_MESSAGE_TRANSFER \n");
+  
+  F1AP_ULRRCMessageTransfer_t    *container;
+  F1AP_ULRRCMessageTransferIEs_t *ie;
+
+  
+  uint64_t        cu_ue_f1ap_id;
+  uint64_t        du_ue_f1ap_id;
+  uint64_t        srb_id;
+
+  DevAssert(pdu != NULL);
+  
+  if (stream != 0) {
+    LOG_E(F1AP, "[SCTP %d] Received F1 on stream != 0 (%d)\n",
+               assoc_id, stream);
+    return -1;
+  }
+
+  container = &pdu->choice.initiatingMessage->value.choice.ULRRCMessageTransfer;
+
+
+  /* GNB_CU_UE_F1AP_ID */
+  F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_ULRRCMessageTransferIEs_t, ie, container,
+                             F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID, true);
+  cu_ue_f1ap_id = ie->value.choice.GNB_CU_UE_F1AP_ID;
+  LOG_D(F1AP, "cu_ue_f1ap_id %lu associated with RNTI %x\n", cu_ue_f1ap_id, f1ap_get_rnti_by_cu_id(&f1ap_cu_inst[instance], cu_ue_f1ap_id));
+
+
+  /* GNB_DU_UE_F1AP_ID */
+  F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_ULRRCMessageTransferIEs_t, ie, container,
+                             F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID, true);
+  du_ue_f1ap_id = ie->value.choice.GNB_DU_UE_F1AP_ID;
+  LOG_D(F1AP, "du_ue_f1ap_id %lu associated with RNTI %x\n", du_ue_f1ap_id, f1ap_get_rnti_by_cu_id(&f1ap_cu_inst[instance], du_ue_f1ap_id));
+
+
+  /* mandatory */
+  /* SRBID */
+  F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_ULRRCMessageTransferIEs_t, ie, container,
+                             F1AP_ProtocolIE_ID_id_SRBID, true);
+  srb_id = ie->value.choice.SRBID;
+  if (srb_id < 1 ) 
+    LOG_E(F1AP, "Unexpected UL RRC MESSAGE for srb_id %lu \n", srb_id);
+  else  
+    LOG_D(F1AP, "UL RRC MESSAGE for srb_id %lu in DCCH \n", srb_id);
+
+
+  // issue in here
+  /* mandatory */
+  /* RRC Container */
+  F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_ULRRCMessageTransferIEs_t, ie, container,
+                             F1AP_ProtocolIE_ID_id_RRCContainer, true);
+  // print message in debug mode 
+
+  // create an ITTI message and copy SDU
+  /*
+  
+  message_p = itti_alloc_new_message (TASK_CU_F1, RRC_DCCH_DATA_IND);
+
+  RRC_DCCH_DATA_IND (message_p).sdu_p = malloc(ie->value.choice.RRCContainer.size);
+
+  RRC_DCCH_DATA_IND (message_p).sdu_size = ie->value.choice.RRCContainer.size;
+  memcpy(RRC_DCCH_DATA_IND (message_p).sdu_p, ie->value.choice.RRCContainer.buf,
+         ie->value.choice.RRCContainer.size);
+
+  RRC_DCCH_DATA_IND (message_p).dcch_index = srb_id;
+  RRC_DCCH_DATA_IND (message_p).rnti = f1ap_get_rnti_by_cu_id(&f1ap_cu_inst[instance], cu_ue_f1ap_id);
+  RRC_DCCH_DATA_IND (message_p).module_id = instance;
+  RRC_DCCH_DATA_IND (message_p).eNB_index = instance; // not needed for CU
+
+  itti_send_msg_to_task(TASK_RRC_ENB, instance, message_p);
+  */
+  protocol_ctxt_t ctxt;
+  ctxt.module_id = instance;
+  ctxt.instance = instance;
+  ctxt.rnti = f1ap_get_rnti_by_cu_id(&f1ap_cu_inst[instance], cu_ue_f1ap_id);
+  ctxt.enb_flag = 1;
+  mem_block_t *mb = get_free_mem_block(ie->value.choice.RRCContainer.size,__func__);
+  memcpy((void*)mb->data,(void*)ie->value.choice.RRCContainer.buf,ie->value.choice.RRCContainer.size);
+  LOG_I(F1AP, "Calling pdcp_data_ind for UE RNTI %x srb_id %lu with size %ld (DCCH) \n", ctxt.rnti, srb_id, ie->value.choice.RRCContainer.size);
+
+  //LOG_I(F1AP, "%s() RRCContainer size %lu: ", __func__, ie->value.choice.RRCContainer.size);
+  //for (int i = 0; i < ie->value.choice.RRCContainer.size; i++)
+  //  printf("%02x ", mb->data[i]);
+  //printf("\n");
+
+  pdcp_data_ind (&ctxt,
+     1, // srb_flag
+     0, // embms_flag
+     srb_id,
+     ie->value.choice.RRCContainer.size,
+     mb);
+  return 0;
+}
diff --git a/openair2/F1AP/f1ap_cu_rrc_message_transfer.h b/openair2/F1AP/f1ap_cu_rrc_message_transfer.h
new file mode 100644
index 0000000000000000000000000000000000000000..68ebbfe41e81ad2704fd44733943cde85dd62cab
--- /dev/null
+++ b/openair2/F1AP/f1ap_cu_rrc_message_transfer.h
@@ -0,0 +1,50 @@
+/*
+ * 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
+ */
+
+/*! \file f1ap_cu_rrc_message_transfer.h
+ * \brief f1ap rrc message transfer for CU
+ * \author EURECOM/NTUST
+ * \date 2018
+ * \version 0.1
+ * \company Eurecom
+ * \email: navid.nikaein@eurecom.fr, bing-kai.hong@eurecom.fr
+ * \note
+ * \warning
+ */
+
+#ifndef F1AP_CU_RRC_MESSAGE_TRANSFER_H_
+#define F1AP_CU_RRC_MESSAGE_TRANSFER_H_
+
+int CU_handle_INITIAL_UL_RRC_MESSAGE_TRANSFER(instance_t       instance,
+                                              uint32_t         assoc_id,
+                                              uint32_t         stream,
+                                              F1AP_F1AP_PDU_t *pdu);
+
+int CU_send_DL_RRC_MESSAGE_TRANSFER(instance_t                instance,
+                                    f1ap_dl_rrc_message_t    *f1ap_dl_rrc);
+
+int CU_handle_UL_RRC_MESSAGE_TRANSFER(instance_t       instance,
+                                      uint32_t         assoc_id,
+                                      uint32_t         stream,
+                                      F1AP_F1AP_PDU_t *pdu);
+
+
+#endif /* F1AP_CU_RRC_MESSAGE_TRANSFER_H_ */
diff --git a/openair2/F1AP/f1ap_cu_system_information.c b/openair2/F1AP/f1ap_cu_system_information.c
new file mode 100644
index 0000000000000000000000000000000000000000..b6bbedba2f0ed9c62704a0f9fdcf52c3e182ed60
--- /dev/null
+++ b/openair2/F1AP/f1ap_cu_system_information.c
@@ -0,0 +1,31 @@
+/*
+ * 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
+ */
+
+/*! \file f1ap_du_interface_management.h
+ * \brief f1ap interface management for DU
+ * \author EURECOM/NTUST
+ * \date 2018
+ * \version 0.1
+ * \company Eurecom
+ * \email: navid.nikaein@eurecom.fr, bing-kai.hong@eurecom.fr
+ * \note
+ * \warning
+ */
\ No newline at end of file
diff --git a/openair2/F1AP/f1ap_cu_system_information.h b/openair2/F1AP/f1ap_cu_system_information.h
new file mode 100644
index 0000000000000000000000000000000000000000..b6bbedba2f0ed9c62704a0f9fdcf52c3e182ed60
--- /dev/null
+++ b/openair2/F1AP/f1ap_cu_system_information.h
@@ -0,0 +1,31 @@
+/*
+ * 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
+ */
+
+/*! \file f1ap_du_interface_management.h
+ * \brief f1ap interface management for DU
+ * \author EURECOM/NTUST
+ * \date 2018
+ * \version 0.1
+ * \company Eurecom
+ * \email: navid.nikaein@eurecom.fr, bing-kai.hong@eurecom.fr
+ * \note
+ * \warning
+ */
\ No newline at end of file
diff --git a/openair2/F1AP/f1ap_cu_task.c b/openair2/F1AP/f1ap_cu_task.c
new file mode 100644
index 0000000000000000000000000000000000000000..9ab84e6bc918e9d764664e86181c6454bd614398
--- /dev/null
+++ b/openair2/F1AP/f1ap_cu_task.c
@@ -0,0 +1,206 @@
+/*
+ * 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
+ */
+
+/*! \file openair2/F1AP/f1ap_cu_task.c
+* \brief data structures for F1 interface modules
+* \author EURECOM/NTUST
+* \date 2018
+* \version 0.1
+* \company Eurecom
+* \email: navid.nikaein@eurecom.fr, raymond.knopp@eurecom.fr, bing-kai.hong@eurecom.fr
+* \note
+* \warning
+*/
+
+#include "f1ap_common.h"
+#include "f1ap_handlers.h"
+#include "f1ap_cu_interface_management.h"
+#include "f1ap_cu_rrc_message_transfer.h"
+#include "f1ap_cu_ue_context_management.h"
+#include "f1ap_cu_task.h"
+#include "proto_agent.h"
+
+extern RAN_CONTEXT_t RC;
+
+f1ap_setup_req_t *f1ap_du_data_from_du;
+f1ap_cudu_inst_t f1ap_cu_inst[MAX_eNB];
+
+void cu_task_handle_sctp_association_ind(instance_t instance, sctp_new_association_ind_t *sctp_new_association_ind) {
+  // Nothing
+}
+
+void cu_task_handle_sctp_association_resp(instance_t instance, sctp_new_association_resp_t *sctp_new_association_resp) {
+
+  DevAssert(sctp_new_association_resp != NULL);
+
+  if (sctp_new_association_resp->sctp_state != SCTP_STATE_ESTABLISHED) {
+    LOG_W(F1AP, "Received unsuccessful result for SCTP association (%u), instance %d, cnx_id %u\n",
+              sctp_new_association_resp->sctp_state,
+              instance,
+              sctp_new_association_resp->ulp_cnx_id);
+
+    if (sctp_new_association_resp->sctp_state == SCTP_STATE_SHUTDOWN)
+      proto_agent_stop(instance);
+      //f1ap_handle_setup_message(instance, sctp_new_association_resp->sctp_state == SCTP_STATE_SHUTDOWN);
+    return; // exit -1 for debugging 
+  }
+
+  // go to an init func
+  f1ap_du_data_from_du = (f1ap_setup_req_t *)calloc(1, sizeof(f1ap_setup_req_t));
+  // save the assoc id 
+  f1ap_du_data_from_du->assoc_id         = sctp_new_association_resp->assoc_id;
+  f1ap_du_data_from_du->sctp_in_streams  = sctp_new_association_resp->in_streams;
+  f1ap_du_data_from_du->sctp_out_streams = sctp_new_association_resp->out_streams;
+
+  /* setup parameters for F1U and start the server */
+  const cudu_params_t params = {
+    .local_ipv4_address  = RC.rrc[instance]->eth_params_s.my_addr,
+    .local_port          = RC.rrc[instance]->eth_params_s.my_portd,
+    .remote_ipv4_address = RC.rrc[instance]->eth_params_s.remote_addr,
+    .remote_port         = RC.rrc[instance]->eth_params_s.remote_portd
+  };
+  AssertFatal(proto_agent_start(instance, &params) == 0,
+              "could not start PROTO_AGENT for F1U on instance %d!\n", instance);
+}
+
+void cu_task_handle_sctp_data_ind(instance_t instance, sctp_data_ind_t *sctp_data_ind) {
+  int result;
+
+  DevAssert(sctp_data_ind != NULL);
+
+  f1ap_handle_message(instance, sctp_data_ind->assoc_id, sctp_data_ind->stream,
+                          sctp_data_ind->buffer, sctp_data_ind->buffer_length);
+
+  result = itti_free(TASK_UNKNOWN, sctp_data_ind->buffer);
+  AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
+}
+
+void cu_task_send_sctp_init_req(instance_t enb_id) {
+  // 1. get the itti msg, and retrive the enb_id from the message
+  // 2. use RC.rrc[enb_id] to fill the sctp_init_t with the ip, port
+  // 3. creat an itti message to init
+
+  LOG_I(F1AP, "F1AP_CU_SCTP_REQ(create socket)\n");
+  MessageDef  *message_p = NULL;
+
+  message_p = itti_alloc_new_message (TASK_CU_F1, SCTP_INIT_MSG);
+  message_p->ittiMsg.sctp_init.port = F1AP_PORT_NUMBER;
+  message_p->ittiMsg.sctp_init.ppid = F1AP_SCTP_PPID;
+  message_p->ittiMsg.sctp_init.ipv4 = 1;
+  message_p->ittiMsg.sctp_init.ipv6 = 0;
+  message_p->ittiMsg.sctp_init.nb_ipv4_addr = 1;
+  message_p->ittiMsg.sctp_init.ipv4_address[0] = inet_addr(RC.rrc[enb_id]->eth_params_s.my_addr);
+  /*
+   * SR WARNING: ipv6 multi-homing fails sometimes for localhost.
+   * * * * Disable it for now.
+   */
+  message_p->ittiMsg.sctp_init.nb_ipv6_addr = 0;
+  message_p->ittiMsg.sctp_init.ipv6_address[0] = "0:0:0:0:0:0:0:1";
+
+  itti_send_msg_to_task(TASK_SCTP, enb_id, message_p);
+}
+
+
+void *F1AP_CU_task(void *arg) {
+
+  MessageDef *received_msg = NULL;
+  int         result;
+
+  LOG_I(F1AP, "Starting F1AP at CU\n");
+
+  // no RLC in CU, initialize mem pool for PDCP
+  pool_buffer_init();
+
+  itti_mark_task_ready(TASK_CU_F1);
+
+  cu_task_send_sctp_init_req(0);
+
+  while (1) {
+    itti_receive_msg(TASK_CU_F1, &received_msg);
+    switch (ITTI_MSG_ID(received_msg)) {
+
+      case SCTP_NEW_ASSOCIATION_IND:
+        LOG_I(F1AP, "CU Task Received SCTP_NEW_ASSOCIATION_IND for instance %d\n",
+              ITTI_MESSAGE_GET_INSTANCE(received_msg));
+        cu_task_handle_sctp_association_ind(ITTI_MESSAGE_GET_INSTANCE(received_msg),
+                                         &received_msg->ittiMsg.sctp_new_association_ind);
+        break;
+
+      case SCTP_NEW_ASSOCIATION_RESP:
+        LOG_I(F1AP, "CU Task Received SCTP_NEW_ASSOCIATION_RESP for instance %d\n",
+              ITTI_MESSAGE_GET_INSTANCE(received_msg));
+        cu_task_handle_sctp_association_resp(ITTI_MESSAGE_GET_INSTANCE(received_msg),
+                                         &received_msg->ittiMsg.sctp_new_association_resp);
+        break;
+
+      case SCTP_DATA_IND:
+        LOG_I(F1AP, "CU Task Received SCTP_DATA_IND for Instance %d\n",
+              ITTI_MESSAGE_GET_INSTANCE(received_msg));
+        cu_task_handle_sctp_data_ind(ITTI_MESSAGE_GET_INSTANCE(received_msg),
+                                        &received_msg->ittiMsg.sctp_data_ind);
+        break;
+
+      case F1AP_SETUP_RESP: // from rrc
+        LOG_I(F1AP, "CU Task Received F1AP_SETUP_RESP\n");
+        // CU_send_f1setup_resp(ITTI_MESSAGE_GET_INSTANCE(received_msg),
+        //                                       &F1AP_SETUP_RESP(received_msg));
+        CU_send_F1_SETUP_RESPONSE(ITTI_MESSAGE_GET_INSTANCE(received_msg),
+                                               &F1AP_SETUP_RESP(received_msg));
+        break;
+
+     case F1AP_DL_RRC_MESSAGE: // from rrc
+        LOG_I(F1AP, "CU Task Received F1AP_DL_RRC_MESSAGE\n");
+        CU_send_DL_RRC_MESSAGE_TRANSFER(ITTI_MESSAGE_GET_INSTANCE(received_msg),
+                                               &F1AP_DL_RRC_MESSAGE(received_msg));
+        break;
+
+     case F1AP_UE_CONTEXT_RELEASE_CMD: // from rrc
+        LOG_I(F1AP, "CU Task Received F1AP_UE_CONTEXT_RELEASE_CMD\n");
+        CU_send_UE_CONTEXT_RELEASE_COMMAND(ITTI_MESSAGE_GET_INSTANCE(received_msg),
+                                           &F1AP_UE_CONTEXT_RELEASE_CMD(received_msg));
+        break;
+
+//    case F1AP_SETUP_RESPONSE: // This is from RRC
+//    CU_send_F1_SETUP_RESPONSE(instance, *f1ap_setup_ind, &(F1AP_SETUP_RESP) f1ap_setup_resp)   
+//        break;
+        
+//    case F1AP_SETUP_FAILURE: // This is from RRC
+//    CU_send_F1_SETUP_FAILURE(instance, *f1ap_setup_ind, &(F1AP_SETUP_FAILURE) f1ap_setup_failure)   
+//       break;
+
+      case TERMINATE_MESSAGE:
+        LOG_W(F1AP, " *** Exiting F1AP thread\n");
+        itti_exit_task();
+        break;
+
+      default:
+        LOG_E(F1AP, "CU Received unhandled message: %d:%s\n",
+              ITTI_MSG_ID(received_msg), ITTI_MSG_NAME(received_msg));
+        break;
+    } // switch
+    result = itti_free (ITTI_MSG_ORIGIN_ID(received_msg), received_msg);
+    AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
+
+    received_msg = NULL;
+  } // while
+
+  return NULL;
+}
diff --git a/openair2/F1AP/f1ap_cu_task.h b/openair2/F1AP/f1ap_cu_task.h
new file mode 100644
index 0000000000000000000000000000000000000000..dec844accfb0f00d840ff630cc0a6bcf94a66752
--- /dev/null
+++ b/openair2/F1AP/f1ap_cu_task.h
@@ -0,0 +1,32 @@
+/*
+ * 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
+ */
+
+#ifndef F1AP_CU_TASK_H_
+#define F1AP_CU_TASK_H_
+
+void cu_task_handle_sctp_association_ind(instance_t instance, sctp_new_association_ind_t *sctp_new_association_ind);
+void cu_task_handle_sctp_association_resp(instance_t instance, sctp_new_association_resp_t *sctp_new_association_resp);
+void cu_task_handle_sctp_data_ind(instance_t instance, sctp_data_ind_t *sctp_data_ind);
+void cu_task_send_sctp_init_req(instance_t enb_id);
+
+void *F1AP_CU_task(void *arg);
+
+#endif /* F1AP_CU_TASK_H_ */
diff --git a/openair2/F1AP/f1ap_cu_ue_context_management.c b/openair2/F1AP/f1ap_cu_ue_context_management.c
new file mode 100644
index 0000000000000000000000000000000000000000..6f6a84e40436dec5bf91b33d782db0d66c52d29d
--- /dev/null
+++ b/openair2/F1AP/f1ap_cu_ue_context_management.c
@@ -0,0 +1,1504 @@
+/*
+ * 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
+ */
+
+/*! \file f1ap_cu_ue_context_management.c
+ * \brief F1AP UE Context Management, CU side
+ * \author EURECOM/NTUST
+ * \date 2018
+ * \version 0.1
+ * \company Eurecom
+ * \email: navid.nikaein@eurecom.fr, bing-kai.hong@eurecom.fr
+ * \note
+ * \warning
+ */
+
+#include "f1ap_common.h"
+#include "f1ap_encoder.h"
+#include "f1ap_decoder.h"
+#include "f1ap_itti_messaging.h"
+#include "f1ap_cu_ue_context_management.h"
+#include <string.h>
+
+#include "openair2/LAYER2/MAC/mac_proto.h"
+#include "rrc_extern.h"
+#include "rrc_eNB_UE_context.h"
+#include "rrc_eNB_S1AP.h"
+#include "rrc_eNB_GTPV1U.h"
+
+extern f1ap_setup_req_t *f1ap_du_data_from_du;
+extern f1ap_cudu_inst_t f1ap_cu_inst[MAX_eNB];
+extern RAN_CONTEXT_t RC;
+
+int CU_send_UE_CONTEXT_SETUP_REQUEST(instance_t instance,
+                                     f1ap_ue_context_setup_req_t *f1ap_ue_context_setup_req) {
+  F1AP_F1AP_PDU_t                 pdu;
+  F1AP_UEContextSetupRequest_t    *out;
+  F1AP_UEContextSetupRequestIEs_t *ie;
+
+  uint8_t  *buffer;
+  uint32_t  len;
+  int       i = 0, j = 0;
+
+  /* Create */
+  /* 0. Message Type */
+  memset(&pdu, 0, sizeof(pdu));
+  pdu.present = F1AP_F1AP_PDU_PR_initiatingMessage;
+  pdu.choice.initiatingMessage = (F1AP_InitiatingMessage_t *)calloc(1, sizeof(F1AP_InitiatingMessage_t));
+  pdu.choice.initiatingMessage->procedureCode = F1AP_ProcedureCode_id_UEContextSetup;
+  pdu.choice.initiatingMessage->criticality   = F1AP_Criticality_reject;
+  pdu.choice.initiatingMessage->value.present = F1AP_InitiatingMessage__value_PR_UEContextSetupRequest;
+  out = &pdu.choice.initiatingMessage->value.choice.UEContextSetupRequest;
+  
+  /* mandatory */
+  /* c1. GNB_CU_UE_F1AP_ID */
+  ie = (F1AP_UEContextSetupRequestIEs_t *)calloc(1, sizeof(F1AP_UEContextSetupRequestIEs_t));
+  ie->id                             = F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID;
+  ie->criticality                    = F1AP_Criticality_reject;
+  ie->value.present                  = F1AP_UEContextSetupRequestIEs__value_PR_GNB_CU_UE_F1AP_ID;
+  ie->value.choice.GNB_CU_UE_F1AP_ID = f1ap_ue_context_setup_req->gNB_CU_ue_id;
+  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+
+  /* optional */
+  /* c2. GNB_DU_UE_F1AP_ID */
+  if (f1ap_ue_context_setup_req->gNB_DU_ue_id) {
+    ie = (F1AP_UEContextSetupRequestIEs_t *)calloc(1, sizeof(F1AP_UEContextSetupRequestIEs_t));
+    ie->id                             = F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID;
+    ie->criticality                    = F1AP_Criticality_ignore;
+    ie->value.present                  = F1AP_UEContextSetupRequestIEs__value_PR_GNB_DU_UE_F1AP_ID;
+    ie->value.choice.GNB_DU_UE_F1AP_ID = *f1ap_ue_context_setup_req->gNB_DU_ue_id;
+    ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+  }
+
+  /* mandatory */
+  /* c3. SpCell_ID */
+  ie = (F1AP_UEContextSetupRequestIEs_t *)calloc(1, sizeof(F1AP_UEContextSetupRequestIEs_t));
+  ie->id                             = F1AP_ProtocolIE_ID_id_SpCell_ID;
+  ie->criticality                    = F1AP_Criticality_reject;
+  ie->value.present                  = F1AP_UEContextSetupRequestIEs__value_PR_NRCGI;
+  /* - nRCGI */
+  F1AP_NRCGI_t nRCGI;
+  MCC_MNC_TO_PLMNID(f1ap_ue_context_setup_req->mcc,
+                    f1ap_ue_context_setup_req->mnc,
+                    f1ap_ue_context_setup_req->mnc_digit_length,
+                    &nRCGI.pLMN_Identity);
+  NR_CELL_ID_TO_BIT_STRING(f1ap_ue_context_setup_req->nr_cellid, &nRCGI.nRCellIdentity);
+
+  ie->value.choice.NRCGI = nRCGI;
+
+  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+
+  /* mandatory */
+  /* c4. ServCellIndex */
+  ie = (F1AP_UEContextSetupRequestIEs_t *)calloc(1, sizeof(F1AP_UEContextSetupRequestIEs_t));
+  ie->id                             = F1AP_ProtocolIE_ID_id_ServCellndex;
+  ie->criticality                    = F1AP_Criticality_reject;
+  ie->value.present                  = F1AP_UEContextSetupRequestIEs__value_PR_ServCellIndex;
+  ie->value.choice.ServCellIndex = 2;
+  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+
+  /* optional */
+  /* c5. CellULConfigured */
+  if (0) {
+    ie = (F1AP_UEContextSetupRequestIEs_t *)calloc(1, sizeof(F1AP_UEContextSetupRequestIEs_t));
+    ie->id                             = F1AP_ProtocolIE_ID_id_SpCellULConfigured;
+    ie->criticality                    = F1AP_Criticality_ignore;
+    ie->value.present                  = F1AP_UEContextSetupRequestIEs__value_PR_CellULConfigured;
+    ie->value.choice.CellULConfigured = F1AP_CellULConfigured_ul;
+    ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+  }
+
+  /* mandatory */
+  /* c6. CUtoDURRCInformation */
+  ie = (F1AP_UEContextSetupRequestIEs_t *)calloc(1, sizeof(F1AP_UEContextSetupRequestIEs_t));
+  ie->id                             = F1AP_ProtocolIE_ID_id_CUtoDURRCInformation;
+  ie->criticality                    = F1AP_Criticality_reject;
+  ie->value.present                  = F1AP_UEContextSetupRequestIEs__value_PR_CUtoDURRCInformation;
+  
+  /* optional */
+  /* 6.1 cG_ConfigInfo */
+  ie->value.choice.CUtoDURRCInformation.cG_ConfigInfo = (F1AP_CG_ConfigInfo_t *)calloc(1, sizeof(F1AP_CG_ConfigInfo_t));
+  OCTET_STRING_fromBuf(ie->value.choice.CUtoDURRCInformation.cG_ConfigInfo, "asdsa1d32sa1d31asd31as",
+                       strlen("asdsa1d32sa1d31asd31as"));
+  /* optional */
+  /* 6.2 uE_CapabilityRAT_ContainerList */
+  ie->value.choice.CUtoDURRCInformation.uE_CapabilityRAT_ContainerList = (F1AP_UE_CapabilityRAT_ContainerList_t *)calloc(1, sizeof(F1AP_UE_CapabilityRAT_ContainerList_t));
+  OCTET_STRING_fromBuf(ie->value.choice.CUtoDURRCInformation.uE_CapabilityRAT_ContainerList, "asdsa1d32sa1d31asd31as",
+                       strlen("asdsa1d32sa1d31asd31as"));
+  /* optional */
+  /* 6.3 measConfig */
+  ie->value.choice.CUtoDURRCInformation.measConfig = (F1AP_MeasConfig_t *)calloc(1, sizeof(F1AP_MeasConfig_t));
+  OCTET_STRING_fromBuf(ie->value.choice.CUtoDURRCInformation.measConfig, "asdsa1d32sa1d31asd31as",
+                       strlen("asdsa1d32sa1d31asd31as"));
+
+  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+
+
+  /* mandatory */
+  /* c7. Candidate_SpCell_List */
+  ie = (F1AP_UEContextSetupRequestIEs_t *)calloc(1, sizeof(F1AP_UEContextSetupRequestIEs_t));
+  ie->id                             = F1AP_ProtocolIE_ID_id_Candidate_SpCell_List;  //90
+  ie->criticality                    = F1AP_Criticality_ignore;
+  ie->value.present                  = F1AP_UEContextSetupRequestIEs__value_PR_Candidate_SpCell_List;
+
+  for (i=0;
+       i<0;
+       i++) {
+
+    F1AP_Candidate_SpCell_ItemIEs_t *candidate_spCell_item_ies;
+    candidate_spCell_item_ies = (F1AP_Candidate_SpCell_ItemIEs_t *)calloc(1, sizeof(F1AP_Candidate_SpCell_ItemIEs_t));
+    candidate_spCell_item_ies->id            = F1AP_ProtocolIE_ID_id_Candidate_SpCell_Item; // 91
+    candidate_spCell_item_ies->criticality   = F1AP_Criticality_reject;
+    candidate_spCell_item_ies->value.present = F1AP_Candidate_SpCell_ItemIEs__value_PR_Candidate_SpCell_Item;
+
+    /* 7.1 Candidate_SpCell_Item */
+    F1AP_Candidate_SpCell_Item_t candidate_spCell_item;
+    memset((void *)&candidate_spCell_item, 0, sizeof(F1AP_Candidate_SpCell_Item_t));
+
+    /* - candidate_SpCell_ID */
+    F1AP_NRCGI_t nRCGI;
+    /* TODO add correct mcc/mnc */
+    MCC_MNC_TO_PLMNID(f1ap_ue_context_setup_req->mcc,
+                      f1ap_ue_context_setup_req->mnc,
+                      f1ap_ue_context_setup_req->mnc_digit_length,
+                      &nRCGI.pLMN_Identity);
+    NR_CELL_ID_TO_BIT_STRING(f1ap_ue_context_setup_req->nr_cellid, &nRCGI.nRCellIdentity);
+
+    candidate_spCell_item.candidate_SpCell_ID = nRCGI;
+
+    /* ADD */
+    candidate_spCell_item_ies->value.choice.Candidate_SpCell_Item = candidate_spCell_item;
+    ASN_SEQUENCE_ADD(&ie->value.choice.Candidate_SpCell_List.list,
+                    candidate_spCell_item_ies);
+  }
+  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+
+  /* optional */
+  /* c8. DRXCycle */
+  if (0) {
+    ie = (F1AP_UEContextSetupRequestIEs_t *)calloc(1, sizeof(F1AP_UEContextSetupRequestIEs_t));
+    ie->id                             = F1AP_ProtocolIE_ID_id_DRXCycle;
+    ie->criticality                    = F1AP_Criticality_ignore;
+    ie->value.present                  = F1AP_UEContextSetupRequestIEs__value_PR_DRXCycle;
+    /* 8.1 longDRXCycleLength */
+    ie->value.choice.DRXCycle.longDRXCycleLength = F1AP_LongDRXCycleLength_ms10; // enum
+
+    /* optional */
+    /* 8.2 shortDRXCycleLength */
+    if (0) {
+      ie->value.choice.DRXCycle.shortDRXCycleLength = (F1AP_ShortDRXCycleLength_t *)calloc(1, sizeof(F1AP_ShortDRXCycleLength_t));
+      *ie->value.choice.DRXCycle.shortDRXCycleLength = F1AP_ShortDRXCycleLength_ms2; // enum
+    }
+
+    /* optional */
+    /* 8.3 shortDRXCycleTimer */
+    if (0) {
+      ie->value.choice.DRXCycle.shortDRXCycleTimer = (F1AP_ShortDRXCycleTimer_t *)calloc(1, sizeof(F1AP_ShortDRXCycleTimer_t));
+      *ie->value.choice.DRXCycle.shortDRXCycleTimer = 123L;
+    }
+    ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+  }
+
+  /* optional */
+  /* c9. ResourceCoordinationTransferContainer */
+  if (0) {
+    ie = (F1AP_UEContextSetupRequestIEs_t *)calloc(1, sizeof(F1AP_UEContextSetupRequestIEs_t));
+    ie->id                             = F1AP_ProtocolIE_ID_id_ResourceCoordinationTransferContainer;
+    ie->criticality                    = F1AP_Criticality_ignore;
+    ie->value.present                  = F1AP_UEContextSetupRequestIEs__value_PR_ResourceCoordinationTransferContainer;
+    
+    ie->value.choice.ResourceCoordinationTransferContainer.buf = malloc(4);
+    ie->value.choice.ResourceCoordinationTransferContainer.size = 4;
+    strncpy((char *)ie->value.choice.ResourceCoordinationTransferContainer.buf, "123", 3);
+
+
+    OCTET_STRING_fromBuf(&ie->value.choice.ResourceCoordinationTransferContainer, "asdsa1d32sa1d31asd31as",
+                         strlen("asdsa1d32sa1d31asd31as"));
+
+    ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+  }
+
+  /* mandatory */
+  /* c10. SCell_ToBeSetup_List */
+  ie = (F1AP_UEContextSetupRequestIEs_t *)calloc(1, sizeof(F1AP_UEContextSetupRequestIEs_t));
+  ie->id                             = F1AP_ProtocolIE_ID_id_SCell_ToBeSetup_List;
+  ie->criticality                    = F1AP_Criticality_ignore;
+  ie->value.present                  = F1AP_UEContextSetupRequestIEs__value_PR_SCell_ToBeSetup_List;
+
+  for (i=0;
+       i<0;
+       i++) {
+     //
+     F1AP_SCell_ToBeSetup_ItemIEs_t *scell_toBeSetup_item_ies;
+     scell_toBeSetup_item_ies = (F1AP_SCell_ToBeSetup_ItemIEs_t *)calloc(1, sizeof(F1AP_SCell_ToBeSetup_ItemIEs_t));
+     scell_toBeSetup_item_ies->id            = F1AP_ProtocolIE_ID_id_SCell_ToBeSetup_Item; //53
+     scell_toBeSetup_item_ies->criticality   = F1AP_Criticality_ignore;
+     scell_toBeSetup_item_ies->value.present = F1AP_SCell_ToBeSetup_ItemIEs__value_PR_SCell_ToBeSetup_Item;
+
+     /* 10.1 SCell_ToBeSetup_Item */
+     F1AP_SCell_ToBeSetup_Item_t scell_toBeSetup_item;
+     memset((void *)&scell_toBeSetup_item, 0, sizeof(F1AP_SCell_ToBeSetup_Item_t));
+
+     /* 10.1.1 sCell_ID */
+     F1AP_NRCGI_t nRCGI;
+     /* TODO correct MCC/MNC */
+     MCC_MNC_TO_PLMNID(f1ap_ue_context_setup_req->mcc,
+                       f1ap_ue_context_setup_req->mnc,
+                       f1ap_ue_context_setup_req->mnc_digit_length,
+                       &nRCGI.pLMN_Identity);
+     NR_CELL_ID_TO_BIT_STRING(123456, &nRCGI.nRCellIdentity);
+     scell_toBeSetup_item.sCell_ID = nRCGI;
+
+     /* 10.1.2 sCellIndex */
+     scell_toBeSetup_item.sCellIndex = 3;  // issue here
+
+     /* OPTIONAL */
+     /* 10.1.3 sCellULConfigured*/
+     if (0) {
+       scell_toBeSetup_item.sCellULConfigured = (F1AP_CellULConfigured_t *)calloc(1, sizeof(F1AP_CellULConfigured_t));
+       *scell_toBeSetup_item.sCellULConfigured = F1AP_CellULConfigured_ul_and_sul; // enum
+     }
+
+     /* ADD */
+     scell_toBeSetup_item_ies->value.choice.SCell_ToBeSetup_Item = scell_toBeSetup_item;
+
+     ASN_SEQUENCE_ADD(&ie->value.choice.SCell_ToBeSetup_List.list,
+                     scell_toBeSetup_item_ies);
+  }
+  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+
+
+  /* mandatory */
+  /* c11. SRBs_ToBeSetup_List */
+  ie = (F1AP_UEContextSetupRequestIEs_t *)calloc(1, sizeof(F1AP_UEContextSetupRequestIEs_t));
+  ie->id                             = F1AP_ProtocolIE_ID_id_SRBs_ToBeSetup_List;
+  ie->criticality                    = F1AP_Criticality_reject;  // ?
+  ie->value.present                  = F1AP_UEContextSetupRequestIEs__value_PR_SRBs_ToBeSetup_List;
+
+  for (i=0;
+       i<0;
+       i++) {
+    //
+    F1AP_SRBs_ToBeSetup_ItemIEs_t *srbs_toBeSetup_item_ies;
+    srbs_toBeSetup_item_ies = (F1AP_SRBs_ToBeSetup_ItemIEs_t *)calloc(1, sizeof(F1AP_SRBs_ToBeSetup_ItemIEs_t));
+    srbs_toBeSetup_item_ies->id            = F1AP_ProtocolIE_ID_id_SRBs_ToBeSetup_Item; // 73
+    srbs_toBeSetup_item_ies->criticality   = F1AP_Criticality_ignore;
+    srbs_toBeSetup_item_ies->value.present = F1AP_SRBs_ToBeSetup_ItemIEs__value_PR_SRBs_ToBeSetup_Item;
+
+    /* 11.1 SRBs_ToBeSetup_Item */
+    F1AP_SRBs_ToBeSetup_Item_t srbs_toBeSetup_item;
+    memset((void *)&srbs_toBeSetup_item, 0, sizeof(F1AP_SRBs_ToBeSetup_Item_t));
+
+    /* 11.1.1 sRBID */
+    srbs_toBeSetup_item.sRBID = 2L;
+
+    /* OPTIONAL */
+    /* 11.1.2 duplicationIndication */
+    if (0) {
+      srbs_toBeSetup_item.duplicationIndication = (F1AP_DuplicationIndication_t *)calloc(1, sizeof(F1AP_DuplicationIndication_t));
+      srbs_toBeSetup_item.duplicationIndication = F1AP_DuplicationIndication_true; // enum
+    }
+
+    /* ADD */
+    srbs_toBeSetup_item_ies->value.choice.SRBs_ToBeSetup_Item = srbs_toBeSetup_item;
+    ASN_SEQUENCE_ADD(&ie->value.choice.SRBs_ToBeSetup_List.list,
+                    srbs_toBeSetup_item_ies);
+  }
+  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+
+  /* mandatory */
+  /* c12. DRBs_ToBeSetup_List */
+  ie = (F1AP_UEContextSetupRequestIEs_t *)calloc(1, sizeof(F1AP_UEContextSetupRequestIEs_t));
+  ie->id                             = F1AP_ProtocolIE_ID_id_DRBs_ToBeSetup_List;
+  ie->criticality                    = F1AP_Criticality_reject;
+  ie->value.present                  = F1AP_UEContextSetupRequestIEs__value_PR_DRBs_ToBeSetup_List;
+
+  for (i = 0; i < f1ap_ue_context_setup_req->drbs_to_be_setup_length; i++) {
+    //
+    F1AP_DRBs_ToBeSetup_ItemIEs_t *drbs_toBeSetup_item_ies;
+    drbs_toBeSetup_item_ies = (F1AP_DRBs_ToBeSetup_ItemIEs_t *)calloc(1, sizeof(F1AP_DRBs_ToBeSetup_ItemIEs_t));
+    drbs_toBeSetup_item_ies->id            = F1AP_ProtocolIE_ID_id_DRBs_ToBeSetup_Item;
+    drbs_toBeSetup_item_ies->criticality   = F1AP_Criticality_reject;
+    drbs_toBeSetup_item_ies->value.present = F1AP_DRBs_ToBeSetup_ItemIEs__value_PR_DRBs_ToBeSetup_Item;
+
+    /* 12.1 DRBs_ToBeSetup_Item */
+    F1AP_DRBs_ToBeSetup_Item_t drbs_toBeSetup_item;
+    memset((void *)&drbs_toBeSetup_item, 0, sizeof(F1AP_DRBs_ToBeSetup_Item_t));
+
+    /* 12.1.1 dRBID */
+    drbs_toBeSetup_item.dRBID = f1ap_ue_context_setup_req->drbs_to_be_setup[i].drb_id; // 9
+
+    /* 12.1.2 qoSInformation */
+    int some_decide_qos = 1; // BK: Need Check
+    if (some_decide_qos) {
+      drbs_toBeSetup_item.qoSInformation.present = F1AP_QoSInformation_PR_eUTRANQoS;
+
+      /*  12.1.2.1 eUTRANQoS */
+      drbs_toBeSetup_item.qoSInformation.choice.eUTRANQoS = (F1AP_EUTRANQoS_t *)calloc(1, sizeof(F1AP_EUTRANQoS_t));
+
+      /*  12.1.2.1.1 qCI */
+      drbs_toBeSetup_item.qoSInformation.choice.eUTRANQoS->qCI = 254L;
+
+      /*  12.1.2.1.2 allocationAndRetentionPriority */
+      {
+        /*  12.1.2.1.2.1 priorityLevel */
+        drbs_toBeSetup_item.qoSInformation.choice.eUTRANQoS->allocationAndRetentionPriority.priorityLevel = F1AP_PriorityLevel_highest; // enum
+        
+        /*  12.1.2.1.2.2 pre_emptionCapability */
+        drbs_toBeSetup_item.qoSInformation.choice.eUTRANQoS->allocationAndRetentionPriority.pre_emptionCapability = F1AP_Pre_emptionCapability_may_trigger_pre_emption; // enum
+
+        /*  12.1.2.1.2.2 pre_emptionVulnerability */
+        drbs_toBeSetup_item.qoSInformation.choice.eUTRANQoS->allocationAndRetentionPriority.pre_emptionVulnerability = F1AP_Pre_emptionVulnerability_not_pre_emptable; // enum
+      }
+
+      /* OPTIONAL */
+      /*  12.1.2.1.3 gbrQosInformation */
+      if (0) {
+        drbs_toBeSetup_item.qoSInformation.choice.eUTRANQoS->gbrQosInformation = (F1AP_GBR_QosInformation_t *)calloc(1, sizeof(F1AP_GBR_QosInformation_t));
+        asn_long2INTEGER(&drbs_toBeSetup_item.qoSInformation.choice.eUTRANQoS->gbrQosInformation->e_RAB_MaximumBitrateDL, 1L);
+        asn_long2INTEGER(&drbs_toBeSetup_item.qoSInformation.choice.eUTRANQoS->gbrQosInformation->e_RAB_MaximumBitrateUL, 1L);
+        asn_long2INTEGER(&drbs_toBeSetup_item.qoSInformation.choice.eUTRANQoS->gbrQosInformation->e_RAB_GuaranteedBitrateDL, 1L);
+        asn_long2INTEGER(&drbs_toBeSetup_item.qoSInformation.choice.eUTRANQoS->gbrQosInformation->e_RAB_GuaranteedBitrateUL, 1L);
+      }
+
+    } else { 
+      /* 12.1.2 dRB_Information */
+      drbs_toBeSetup_item.qoSInformation.present = F1AP_QoSInformation_PR_dRB_Information;
+      drbs_toBeSetup_item.qoSInformation.choice.dRB_Information = (F1AP_DRB_Information_t *)calloc(1, sizeof(F1AP_DRB_Information_t));
+      
+      /* 12.1.2.1 dRB_QoS */
+      {
+        /* qoS_Characteristics */
+        {
+          int some_decide_qoS_characteristics = 1; // BK: Need Check
+          if (some_decide_qoS_characteristics) {
+            drbs_toBeSetup_item.qoSInformation.choice.dRB_Information->dRB_QoS.qoS_Characteristics.present = F1AP_QoS_Characteristics_PR_non_Dynamic_5QI;
+            drbs_toBeSetup_item.qoSInformation.choice.dRB_Information->dRB_QoS.qoS_Characteristics.choice.non_Dynamic_5QI = (F1AP_NonDynamic5QIDescriptor_t *)calloc(1, sizeof(F1AP_NonDynamic5QIDescriptor_t));
+            
+            /* fiveQI */
+            drbs_toBeSetup_item.qoSInformation.choice.dRB_Information->dRB_QoS.qoS_Characteristics.choice.non_Dynamic_5QI->fiveQI = 1L;
+
+            /* OPTIONAL */
+            /* qoSPriorityLevel */
+            if (0) {
+              drbs_toBeSetup_item.qoSInformation.choice.dRB_Information->dRB_QoS.qoS_Characteristics.choice.non_Dynamic_5QI->qoSPriorityLevel = (long *)calloc(1, sizeof(long));
+              *drbs_toBeSetup_item.qoSInformation.choice.dRB_Information->dRB_QoS.qoS_Characteristics.choice.non_Dynamic_5QI->qoSPriorityLevel = 1L;
+            }
+
+            /* OPTIONAL */
+            /* averagingWindow */
+            if (0) {
+              drbs_toBeSetup_item.qoSInformation.choice.dRB_Information->dRB_QoS.qoS_Characteristics.choice.non_Dynamic_5QI->averagingWindow = (F1AP_AveragingWindow_t *)calloc(1, sizeof(F1AP_AveragingWindow_t));
+              *drbs_toBeSetup_item.qoSInformation.choice.dRB_Information->dRB_QoS.qoS_Characteristics.choice.non_Dynamic_5QI->averagingWindow = 1L;
+            }
+
+            /* OPTIONAL */
+            /* maxDataBurstVolume */
+            if (0) {
+              drbs_toBeSetup_item.qoSInformation.choice.dRB_Information->dRB_QoS.qoS_Characteristics.choice.non_Dynamic_5QI->maxDataBurstVolume = (F1AP_MaxDataBurstVolume_t *)calloc(1, sizeof(F1AP_MaxDataBurstVolume_t));
+              *drbs_toBeSetup_item.qoSInformation.choice.dRB_Information->dRB_QoS.qoS_Characteristics.choice.non_Dynamic_5QI->maxDataBurstVolume = 1L;
+            }
+
+          } else {
+            drbs_toBeSetup_item.qoSInformation.choice.dRB_Information->dRB_QoS.qoS_Characteristics.present = F1AP_QoS_Characteristics_PR_dynamic_5QI;
+            drbs_toBeSetup_item.qoSInformation.choice.dRB_Information->dRB_QoS.qoS_Characteristics.choice.dynamic_5QI = (F1AP_Dynamic5QIDescriptor_t *)calloc(1, sizeof(F1AP_Dynamic5QIDescriptor_t));
+            
+            /* qoSPriorityLevel */
+            drbs_toBeSetup_item.qoSInformation.choice.dRB_Information->dRB_QoS.qoS_Characteristics.choice.dynamic_5QI->qoSPriorityLevel = 1L;
+
+            /* packetDelayBudget */
+            drbs_toBeSetup_item.qoSInformation.choice.dRB_Information->dRB_QoS.qoS_Characteristics.choice.dynamic_5QI->packetDelayBudget = 1L;
+
+            /* packetErrorRate */
+            drbs_toBeSetup_item.qoSInformation.choice.dRB_Information->dRB_QoS.qoS_Characteristics.choice.dynamic_5QI->packetErrorRate = 1L;
+
+            /* OPTIONAL */
+            /* delayCritical */
+            if (0) {
+              drbs_toBeSetup_item.qoSInformation.choice.dRB_Information->dRB_QoS.qoS_Characteristics.choice.dynamic_5QI->delayCritical = (long *)calloc(1, sizeof(long));
+              *drbs_toBeSetup_item.qoSInformation.choice.dRB_Information->dRB_QoS.qoS_Characteristics.choice.dynamic_5QI->delayCritical = 1L;
+            }
+
+            /* OPTIONAL */
+            /* averagingWindow */
+            if (0) {
+              drbs_toBeSetup_item.qoSInformation.choice.dRB_Information->dRB_QoS.qoS_Characteristics.choice.dynamic_5QI->averagingWindow = (F1AP_AveragingWindow_t *)calloc(1, sizeof(F1AP_AveragingWindow_t));
+              *drbs_toBeSetup_item.qoSInformation.choice.dRB_Information->dRB_QoS.qoS_Characteristics.choice.dynamic_5QI->averagingWindow = 1L;
+            }
+
+            /* OPTIONAL */
+            /* maxDataBurstVolume */
+            if (0) {
+              drbs_toBeSetup_item.qoSInformation.choice.dRB_Information->dRB_QoS.qoS_Characteristics.choice.dynamic_5QI->maxDataBurstVolume = (F1AP_MaxDataBurstVolume_t *)calloc(1, sizeof(F1AP_MaxDataBurstVolume_t));
+              *drbs_toBeSetup_item.qoSInformation.choice.dRB_Information->dRB_QoS.qoS_Characteristics.choice.dynamic_5QI->maxDataBurstVolume = 1L;
+            }
+
+          } // if some_decide_qoS_characteristics
+
+        } // qoS_Characteristics
+
+        /* nGRANallocationRetentionPriority */
+        {
+            drbs_toBeSetup_item.qoSInformation.choice.dRB_Information->dRB_QoS.nGRANallocationRetentionPriority.priorityLevel = F1AP_PriorityLevel_highest; // enum
+            drbs_toBeSetup_item.qoSInformation.choice.dRB_Information->dRB_QoS.nGRANallocationRetentionPriority.pre_emptionCapability = F1AP_Pre_emptionCapability_shall_not_trigger_pre_emption; // enum
+            drbs_toBeSetup_item.qoSInformation.choice.dRB_Information->dRB_QoS.nGRANallocationRetentionPriority.pre_emptionVulnerability = F1AP_Pre_emptionVulnerability_not_pre_emptable; // enum
+        } // nGRANallocationRetentionPriority
+
+        /* OPTIONAL */
+        /* gBR_QoS_Flow_Information */
+        if (0) {
+          drbs_toBeSetup_item.qoSInformation.choice.dRB_Information->dRB_QoS.gBR_QoS_Flow_Information = (F1AP_GBR_QoSFlowInformation_t *)calloc(1, sizeof(F1AP_GBR_QoSFlowInformation_t)); 
+          asn_long2INTEGER(&drbs_toBeSetup_item.qoSInformation.choice.dRB_Information->dRB_QoS.gBR_QoS_Flow_Information->maxFlowBitRateDownlink, 1L);
+          asn_long2INTEGER(&drbs_toBeSetup_item.qoSInformation.choice.dRB_Information->dRB_QoS.gBR_QoS_Flow_Information->maxFlowBitRateUplink, 1L);
+          asn_long2INTEGER(&drbs_toBeSetup_item.qoSInformation.choice.dRB_Information->dRB_QoS.gBR_QoS_Flow_Information->guaranteedFlowBitRateDownlink, 1L);
+          asn_long2INTEGER(&drbs_toBeSetup_item.qoSInformation.choice.dRB_Information->dRB_QoS.gBR_QoS_Flow_Information->guaranteedFlowBitRateUplink, 1L);
+
+          /* OPTIONAL */
+          /* maxPacketLossRateDownlink */
+          if (0) {
+            drbs_toBeSetup_item.qoSInformation.choice.dRB_Information->dRB_QoS.gBR_QoS_Flow_Information->maxPacketLossRateDownlink = (F1AP_MaxPacketLossRate_t *)calloc(1, sizeof(F1AP_MaxPacketLossRate_t)); 
+            *drbs_toBeSetup_item.qoSInformation.choice.dRB_Information->dRB_QoS.gBR_QoS_Flow_Information->maxPacketLossRateDownlink = 1L;
+          }
+
+          /* OPTIONAL */
+          /* maxPacketLossRateUplink */
+          if (0) {
+            drbs_toBeSetup_item.qoSInformation.choice.dRB_Information->dRB_QoS.gBR_QoS_Flow_Information->maxPacketLossRateUplink = (F1AP_MaxPacketLossRate_t *)calloc(1, sizeof(F1AP_MaxPacketLossRate_t)); 
+            *drbs_toBeSetup_item.qoSInformation.choice.dRB_Information->dRB_QoS.gBR_QoS_Flow_Information->maxPacketLossRateUplink = 1L;
+          }
+
+        }
+
+        /* OPTIONAL */
+        /* reflective_QoS_Attribute */
+        if (0) {
+          drbs_toBeSetup_item.qoSInformation.choice.dRB_Information->dRB_QoS.reflective_QoS_Attribute = (long *)calloc(1, sizeof(long)); 
+          *drbs_toBeSetup_item.qoSInformation.choice.dRB_Information->dRB_QoS.reflective_QoS_Attribute = 1L;
+        }
+
+      } // dRB_QoS
+
+      /* 12.1.2.2 sNSSAI */
+      {
+        /* sST */
+        OCTET_STRING_fromBuf(&drbs_toBeSetup_item.qoSInformation.choice.dRB_Information->sNSSAI.sST, "asdsa1d32sa1d31asd31as",
+                           strlen("asdsa1d32sa1d31asd31as"));
+        /* OPTIONAL */
+        /* sD */
+        if (0) {
+          drbs_toBeSetup_item.qoSInformation.choice.dRB_Information->sNSSAI.sD = (OCTET_STRING_t *)calloc(1, sizeof(OCTET_STRING_t));
+          OCTET_STRING_fromBuf(drbs_toBeSetup_item.qoSInformation.choice.dRB_Information->sNSSAI.sD, "asdsa1d32sa1d31asd31as",
+                           strlen("asdsa1d32sa1d31asd31as"));
+        }
+      }
+      /* OPTIONAL */
+      /* 12.1.2.3 notificationControl */
+      if (0) {
+        drbs_toBeSetup_item.qoSInformation.choice.dRB_Information->notificationControl = (F1AP_NotificationControl_t *)calloc(1, sizeof(F1AP_NotificationControl_t));
+        *drbs_toBeSetup_item.qoSInformation.choice.dRB_Information->notificationControl = F1AP_NotificationControl_active; // enum
+      }
+
+      /* 12.1.2.4 flows_Mapped_To_DRB_List */  // BK: need verifiy
+      int k;
+      for (k = 0; k < 1; k ++) {
+        
+        F1AP_Flows_Mapped_To_DRB_Item_t flows_mapped_to_drb_item;
+        memset((void *)&flows_mapped_to_drb_item, 0, sizeof(F1AP_Flows_Mapped_To_DRB_Item_t));
+        
+        /* qoSFlowIndicator */
+        flows_mapped_to_drb_item.qoSFlowIndicator = 1L;
+
+        /* qoSFlowLevelQoSParameters */
+        {  
+          /* qoS_Characteristics */
+          {
+            int some_decide_qoS_characteristics = 1; // BK: Need Check
+            if (some_decide_qoS_characteristics) {
+              flows_mapped_to_drb_item.qoSFlowLevelQoSParameters.qoS_Characteristics.present = F1AP_QoS_Characteristics_PR_non_Dynamic_5QI;
+              flows_mapped_to_drb_item.qoSFlowLevelQoSParameters.qoS_Characteristics.choice.non_Dynamic_5QI = (F1AP_NonDynamic5QIDescriptor_t *)calloc(1, sizeof(F1AP_NonDynamic5QIDescriptor_t));
+              
+              /* fiveQI */
+              flows_mapped_to_drb_item.qoSFlowLevelQoSParameters.qoS_Characteristics.choice.non_Dynamic_5QI->fiveQI = 1L;
+
+              /* OPTIONAL */
+              /* qoSPriorityLevel */
+              if (0) {
+                flows_mapped_to_drb_item.qoSFlowLevelQoSParameters.qoS_Characteristics.choice.non_Dynamic_5QI->qoSPriorityLevel = (long *)calloc(1, sizeof(long));
+                *flows_mapped_to_drb_item.qoSFlowLevelQoSParameters.qoS_Characteristics.choice.non_Dynamic_5QI->qoSPriorityLevel = 1L;
+              }
+
+              /* OPTIONAL */
+              /* averagingWindow */
+              if (0) {
+                flows_mapped_to_drb_item.qoSFlowLevelQoSParameters.qoS_Characteristics.choice.non_Dynamic_5QI->averagingWindow = (F1AP_AveragingWindow_t *)calloc(1, sizeof(F1AP_AveragingWindow_t));
+                *flows_mapped_to_drb_item.qoSFlowLevelQoSParameters.qoS_Characteristics.choice.non_Dynamic_5QI->averagingWindow = 1L;
+              }
+
+              /* OPTIONAL */
+              /* maxDataBurstVolume */
+              if (0) {
+                flows_mapped_to_drb_item.qoSFlowLevelQoSParameters.qoS_Characteristics.choice.non_Dynamic_5QI->maxDataBurstVolume = (F1AP_MaxDataBurstVolume_t *)calloc(1, sizeof(F1AP_MaxDataBurstVolume_t));
+                *flows_mapped_to_drb_item.qoSFlowLevelQoSParameters.qoS_Characteristics.choice.non_Dynamic_5QI->maxDataBurstVolume = 1L;
+              }
+
+            } else {
+              flows_mapped_to_drb_item.qoSFlowLevelQoSParameters.qoS_Characteristics.present = F1AP_QoS_Characteristics_PR_dynamic_5QI;
+              flows_mapped_to_drb_item.qoSFlowLevelQoSParameters.qoS_Characteristics.choice.dynamic_5QI = (F1AP_Dynamic5QIDescriptor_t *)calloc(1, sizeof(F1AP_Dynamic5QIDescriptor_t));
+              
+              /* qoSPriorityLevel */
+              flows_mapped_to_drb_item.qoSFlowLevelQoSParameters.qoS_Characteristics.choice.dynamic_5QI->qoSPriorityLevel = 1L;
+
+              /* packetDelayBudget */
+              flows_mapped_to_drb_item.qoSFlowLevelQoSParameters.qoS_Characteristics.choice.dynamic_5QI->packetDelayBudget = 1L;
+
+              /* packetErrorRate */
+              flows_mapped_to_drb_item.qoSFlowLevelQoSParameters.qoS_Characteristics.choice.dynamic_5QI->packetErrorRate = 1L;
+
+              /* OPTIONAL */
+              /* delayCritical */
+              if (0) {
+                flows_mapped_to_drb_item.qoSFlowLevelQoSParameters.qoS_Characteristics.choice.dynamic_5QI->delayCritical = (long *)calloc(1, sizeof(long));
+                *flows_mapped_to_drb_item.qoSFlowLevelQoSParameters.qoS_Characteristics.choice.dynamic_5QI->delayCritical = 1L;
+              }
+
+              /* OPTIONAL */
+              /* averagingWindow */
+              if (0) {
+                flows_mapped_to_drb_item.qoSFlowLevelQoSParameters.qoS_Characteristics.choice.dynamic_5QI->averagingWindow = (F1AP_AveragingWindow_t *)calloc(1, sizeof(F1AP_AveragingWindow_t));
+                *flows_mapped_to_drb_item.qoSFlowLevelQoSParameters.qoS_Characteristics.choice.dynamic_5QI->averagingWindow = 1L;
+              }
+
+              /* OPTIONAL */
+              /* maxDataBurstVolume */
+              if (0) {
+                flows_mapped_to_drb_item.qoSFlowLevelQoSParameters.qoS_Characteristics.choice.dynamic_5QI->maxDataBurstVolume = (F1AP_MaxDataBurstVolume_t *)calloc(1, sizeof(F1AP_MaxDataBurstVolume_t));
+                *flows_mapped_to_drb_item.qoSFlowLevelQoSParameters.qoS_Characteristics.choice.dynamic_5QI->maxDataBurstVolume = 1L;
+              }
+
+            } // if some_decide_qoS_characteristics
+
+          } // qoS_Characteristics
+
+          /* nGRANallocationRetentionPriority */
+          {
+              flows_mapped_to_drb_item.qoSFlowLevelQoSParameters.nGRANallocationRetentionPriority.priorityLevel = F1AP_PriorityLevel_highest; // enum
+              flows_mapped_to_drb_item.qoSFlowLevelQoSParameters.nGRANallocationRetentionPriority.pre_emptionCapability = F1AP_Pre_emptionCapability_shall_not_trigger_pre_emption; // enum
+              flows_mapped_to_drb_item.qoSFlowLevelQoSParameters.nGRANallocationRetentionPriority.pre_emptionVulnerability = F1AP_Pre_emptionVulnerability_not_pre_emptable; // enum
+          } // nGRANallocationRetentionPriority
+
+          /* OPTIONAL */
+          /* gBR_QoS_Flow_Information */
+          if (0) {
+            flows_mapped_to_drb_item.qoSFlowLevelQoSParameters.gBR_QoS_Flow_Information = (F1AP_GBR_QoSFlowInformation_t *)calloc(1, sizeof(F1AP_GBR_QoSFlowInformation_t)); 
+            asn_long2INTEGER(&flows_mapped_to_drb_item.qoSFlowLevelQoSParameters.gBR_QoS_Flow_Information->maxFlowBitRateDownlink, 1L);
+            asn_long2INTEGER(&flows_mapped_to_drb_item.qoSFlowLevelQoSParameters.gBR_QoS_Flow_Information->maxFlowBitRateUplink, 1L);
+            asn_long2INTEGER(&flows_mapped_to_drb_item.qoSFlowLevelQoSParameters.gBR_QoS_Flow_Information->guaranteedFlowBitRateDownlink, 1L);
+            asn_long2INTEGER(&flows_mapped_to_drb_item.qoSFlowLevelQoSParameters.gBR_QoS_Flow_Information->guaranteedFlowBitRateUplink, 1L);
+
+            /* OPTIONAL */
+            /* maxPacketLossRateDownlink */
+            if (0) {
+              flows_mapped_to_drb_item.qoSFlowLevelQoSParameters.gBR_QoS_Flow_Information->maxPacketLossRateDownlink = (F1AP_MaxPacketLossRate_t *)calloc(1, sizeof(F1AP_MaxPacketLossRate_t)); 
+              *flows_mapped_to_drb_item.qoSFlowLevelQoSParameters.gBR_QoS_Flow_Information->maxPacketLossRateDownlink = 1L;
+            }
+
+            /* OPTIONAL */
+            /* maxPacketLossRateUplink */
+            if (0) {
+              flows_mapped_to_drb_item.qoSFlowLevelQoSParameters.gBR_QoS_Flow_Information->maxPacketLossRateUplink = (F1AP_MaxPacketLossRate_t *)calloc(1, sizeof(F1AP_MaxPacketLossRate_t)); 
+              *flows_mapped_to_drb_item.qoSFlowLevelQoSParameters.gBR_QoS_Flow_Information->maxPacketLossRateUplink = 1L;
+            }
+
+          }
+
+          /* OPTIONAL */
+          /* reflective_QoS_Attribute */
+          if (0) {
+            flows_mapped_to_drb_item.qoSFlowLevelQoSParameters.reflective_QoS_Attribute = (long *)calloc(1, sizeof(long)); 
+            *flows_mapped_to_drb_item.qoSFlowLevelQoSParameters.reflective_QoS_Attribute = 1L;
+          }
+
+        } // qoSFlowLevelQoSParameters
+        // BK: need check
+        ASN_SEQUENCE_ADD(&drbs_toBeSetup_item.qoSInformation.choice.dRB_Information->flows_Mapped_To_DRB_List.list, &flows_mapped_to_drb_item);
+      }
+
+    } // if some_decide_qos
+
+    /* 12.1.3 uLUPTNLInformation_ToBeSetup_List */
+    for (j = 0; j < f1ap_ue_context_setup_req->drbs_to_be_setup[i].up_ul_tnl_length; j++) {
+      f1ap_up_tnl_t *up_tnl = &f1ap_ue_context_setup_req->drbs_to_be_setup[i].up_ul_tnl[j];
+
+      /*  12.3.1 ULTunnels_ToBeSetup_Item */
+      F1AP_ULUPTNLInformation_ToBeSetup_Item_t *uLUPTNLInformation_ToBeSetup_Item;
+
+      /* 12.3.1.1 gTPTunnel */
+      uLUPTNLInformation_ToBeSetup_Item = calloc(1, sizeof(F1AP_ULUPTNLInformation_ToBeSetup_Item_t));
+      uLUPTNLInformation_ToBeSetup_Item->uLUPTNLInformation.present = F1AP_UPTransportLayerInformation_PR_gTPTunnel;
+      F1AP_GTPTunnel_t *gTPTunnel = (F1AP_GTPTunnel_t *)calloc(1, sizeof(F1AP_GTPTunnel_t));
+
+      /* 12.3.1.1.1 transportLayerAddress */
+      TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(up_tnl->tl_address, &gTPTunnel->transportLayerAddress);
+
+      /* 12.3.1.1.2 gTP_TEID */
+      INT32_TO_OCTET_STRING(up_tnl->gtp_teid, &gTPTunnel->gTP_TEID);
+
+      // Add
+      uLUPTNLInformation_ToBeSetup_Item->uLUPTNLInformation.choice.gTPTunnel = gTPTunnel;
+      ASN_SEQUENCE_ADD(&drbs_toBeSetup_item.uLUPTNLInformation_ToBeSetup_List.list, uLUPTNLInformation_ToBeSetup_Item);
+    }
+
+    /* 12.1.4 rLCMode */
+    /* TODO use rlc_mode from f1ap_drb_to_be_setup */
+    switch (f1ap_ue_context_setup_req->drbs_to_be_setup[i].rlc_mode) {
+      case RLC_MODE_AM:
+        drbs_toBeSetup_item.rLCMode = F1AP_RLCMode_rlc_am;
+        break;
+      default:
+        drbs_toBeSetup_item.rLCMode = F1AP_RLCMode_rlc_um;
+    }
+
+    /* OPTIONAL */
+    /* 12.1.5 ULConfiguration */
+    if (0) {
+       drbs_toBeSetup_item.uLConfiguration = (F1AP_ULConfiguration_t *)calloc(1, sizeof(F1AP_ULConfiguration_t));
+       drbs_toBeSetup_item.uLConfiguration->uLUEConfiguration = F1AP_ULUEConfiguration_no_data;
+    }
+
+    /* OPTIONAL */
+    /* 12.1.6 duplicationActivation */
+    if (0) {
+       drbs_toBeSetup_item.duplicationActivation = (F1AP_DuplicationActivation_t *)calloc(1, sizeof(F1AP_DuplicationActivation_t));
+       drbs_toBeSetup_item.duplicationActivation = F1AP_DuplicationActivation_active;  // enum
+    }
+
+    /* ADD */
+    drbs_toBeSetup_item_ies->value.choice.DRBs_ToBeSetup_Item = drbs_toBeSetup_item;
+    ASN_SEQUENCE_ADD(&ie->value.choice.DRBs_ToBeSetup_List.list,
+                   drbs_toBeSetup_item_ies);
+
+  }
+  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+
+  /* OPTIONAL */
+  /* InactivityMonitoringRequest */
+  if (0) {
+    ie = (F1AP_UEContextSetupRequestIEs_t *)calloc(1, sizeof(F1AP_UEContextSetupRequestIEs_t));
+    ie->id                             = F1AP_ProtocolIE_ID_id_InactivityMonitoringRequest;
+    ie->criticality                    = F1AP_Criticality_reject;
+    ie->value.present                  = F1AP_UEContextSetupRequestIEs__value_PR_InactivityMonitoringRequest;
+    ie->value.choice.InactivityMonitoringRequest = F1AP_InactivityMonitoringRequest_true; // 0
+    ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+  }
+
+  /* OPTIONAL */
+  /* RAT_FrequencyPriorityInformation */
+  if (0) {
+    ie = (F1AP_UEContextSetupRequestIEs_t *)calloc(1, sizeof(F1AP_UEContextSetupRequestIEs_t));
+    ie->id                             = F1AP_ProtocolIE_ID_id_RAT_FrequencyPriorityInformation;
+    ie->criticality                    = F1AP_Criticality_reject;
+    ie->value.present                  = F1AP_UEContextSetupRequestIEs__value_PR_RAT_FrequencyPriorityInformation;
+
+    int some_decide_rat = 1; // BK: Need Check
+    if (some_decide_rat) {
+      ie->value.choice.RAT_FrequencyPriorityInformation.present = F1AP_RAT_FrequencyPriorityInformation_PR_subscriberProfileIDforRFP;
+      ie->value.choice.RAT_FrequencyPriorityInformation.choice.subscriberProfileIDforRFP = 11L;
+    } else {
+      ie->value.choice.RAT_FrequencyPriorityInformation.present = F1AP_RAT_FrequencyPriorityInformation_PR_rAT_FrequencySelectionPriority;
+      ie->value.choice.RAT_FrequencyPriorityInformation.choice.rAT_FrequencySelectionPriority = 11L;
+    }
+    ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+  }
+
+  /* OPTIONAL */
+  /* RRCContainer */
+  if (0) {
+    ie = (F1AP_UEContextSetupRequestIEs_t *)calloc(1, sizeof(F1AP_UEContextSetupRequestIEs_t));
+    ie->id                             = F1AP_ProtocolIE_ID_id_RRCContainer;
+    ie->criticality                    = F1AP_Criticality_reject;
+    ie->value.present                  = F1AP_UEContextSetupRequestIEs__value_PR_RRCContainer;
+    OCTET_STRING_fromBuf(&ie->value.choice.RRCContainer, "asdsa1d32sa1d31asd31as",
+                         strlen("asdsa1d32sa1d31asd31as"));
+    ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+  }
+
+  /* OPTIONAL */
+  /* MaskedIMEISV */
+  if (0) {
+    ie = (F1AP_UEContextSetupRequestIEs_t *)calloc(1, sizeof(F1AP_UEContextSetupRequestIEs_t));
+    ie->id                             = F1AP_ProtocolIE_ID_id_MaskedIMEISV;
+    ie->criticality                    = F1AP_Criticality_reject;
+    ie->value.present                  = F1AP_UEContextSetupRequestIEs__value_PR_MaskedIMEISV;
+    MaskedIMEISV_TO_BIT_STRING(12340000l, &ie->value.choice.MaskedIMEISV); // size (64)
+    ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+  }
+
+  /* encode */
+  if (f1ap_encode_pdu(&pdu, &buffer, &len) < 0) {
+    LOG_E(F1AP, "Failed to encode F1 setup request\n");
+    return -1;
+  }
+
+  return 0;
+}
+
+int CU_handle_UE_CONTEXT_SETUP_RESPONSE(instance_t       instance,
+                                        uint32_t         assoc_id,
+                                        uint32_t         stream,
+                                        F1AP_F1AP_PDU_t *pdu) {
+  AssertFatal(1==0,"Not implemented yet\n");
+}
+
+int CU_handle_UE_CONTEXT_SETUP_FAILURE(instance_t       instance,
+                                       uint32_t         assoc_id,
+                                       uint32_t         stream,
+                                       F1AP_F1AP_PDU_t *pdu) {
+  AssertFatal(1==0,"Not implemented yet\n");
+}
+
+
+int CU_handle_UE_CONTEXT_RELEASE_REQUEST(instance_t       instance,
+                                         uint32_t         assoc_id,
+                                         uint32_t         stream,
+                                         F1AP_F1AP_PDU_t *pdu) {
+  F1AP_UEContextReleaseRequest_t    *container;
+  F1AP_UEContextReleaseRequestIEs_t *ie;
+
+  DevAssert(pdu);
+
+  container = &pdu->choice.initiatingMessage->value.choice.UEContextReleaseRequest;
+  /* GNB_CU_UE_F1AP_ID */
+  F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextReleaseRequestIEs_t, ie, container,
+                             F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID, true);
+  const rnti_t rnti = f1ap_get_rnti_by_cu_id(&f1ap_cu_inst[instance],
+                                             ie->value.choice.GNB_CU_UE_F1AP_ID);
+
+  /* GNB_DU_UE_F1AP_ID */
+  F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextReleaseRequestIEs_t, ie, container,
+                             F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID, true);
+  const rnti_t rnti2 = f1ap_get_rnti_by_du_id(&f1ap_cu_inst[instance],
+                                              ie->value.choice.GNB_DU_UE_F1AP_ID);
+  AssertFatal(rnti == rnti2, "RNTI obtained through DU ID (%x) is different from CU ID (%x)\n",
+              rnti2, rnti);
+
+  /* Cause */
+  /* We don't care for the moment
+  F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextReleaseRequestIEs_t, ie, container,
+                             F1AP_ProtocolIE_ID_id_Cause, true);
+
+  switch(ie->value.choice.Cause.present)
+  {
+    case F1AP_Cause_PR_radioNetwork:
+      //ie->value.choice.Cause.choice.radioNetwork
+      break;
+    case F1AP_Cause_PR_transport:
+      //ie->value.choice.Cause.choice.transport
+      break;
+    case F1AP_Cause_PR_protocol:
+      //ie->value.choice.Cause.choice.protocol
+      break;
+    case F1AP_Cause_PR_misc:
+      //ie->value.choice.Cause.choice.misc
+      break;
+    case F1AP_Cause_PR_NOTHING:
+    default:
+      break;
+  }
+  */
+
+  LOG_I(F1AP, "Received UE CONTEXT RELEASE REQUEST: Trigger RRC for RNTI %x\n", rnti);
+  struct rrc_eNB_ue_context_s *ue_context_pP;
+  ue_context_pP = rrc_eNB_get_ue_context(RC.rrc[instance], rnti);
+  rrc_eNB_send_S1AP_UE_CONTEXT_RELEASE_REQ(
+      instance,
+      ue_context_pP,
+      S1AP_CAUSE_RADIO_NETWORK,
+      21); // send cause 21: connection with ue lost
+
+  return 0;
+}
+
+
+int CU_send_UE_CONTEXT_RELEASE_COMMAND(instance_t instance,
+                                       f1ap_ue_context_release_cmd_t *cmd) {
+  F1AP_F1AP_PDU_t                   pdu;
+  F1AP_UEContextReleaseCommand_t    *out;
+  F1AP_UEContextReleaseCommandIEs_t *ie;
+
+  uint8_t  *buffer;
+  uint32_t  len;
+
+  /* Create */
+  /* 0. Message Type */
+  memset(&pdu, 0, sizeof(pdu));
+  pdu.present = F1AP_F1AP_PDU_PR_initiatingMessage;
+  pdu.choice.initiatingMessage = (F1AP_InitiatingMessage_t *)calloc(1, sizeof(F1AP_InitiatingMessage_t));
+  pdu.choice.initiatingMessage->procedureCode = F1AP_ProcedureCode_id_UEContextRelease;
+  pdu.choice.initiatingMessage->criticality   = F1AP_Criticality_reject;
+  pdu.choice.initiatingMessage->value.present = F1AP_InitiatingMessage__value_PR_UEContextReleaseCommand;
+  out = &pdu.choice.initiatingMessage->value.choice.UEContextReleaseCommand;
+  
+  /* mandatory */
+  /* c1. GNB_CU_UE_F1AP_ID */
+  ie = (F1AP_UEContextReleaseCommandIEs_t *)calloc(1, sizeof(F1AP_UEContextReleaseCommandIEs_t));
+  ie->id                             = F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID;
+  ie->criticality                    = F1AP_Criticality_reject;
+  ie->value.present                  = F1AP_UEContextReleaseCommandIEs__value_PR_GNB_CU_UE_F1AP_ID;
+  ie->value.choice.GNB_CU_UE_F1AP_ID = f1ap_get_cu_ue_f1ap_id(&f1ap_cu_inst[instance], cmd->rnti);
+  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+
+  /* mandatory */
+  /* c2. GNB_DU_UE_F1AP_ID */
+  ie = (F1AP_UEContextReleaseCommandIEs_t *)calloc(1, sizeof(F1AP_UEContextReleaseCommandIEs_t));
+  ie->id                             = F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID;
+  ie->criticality                    = F1AP_Criticality_reject;
+  ie->value.present                  = F1AP_UEContextReleaseCommandIEs__value_PR_GNB_DU_UE_F1AP_ID;
+  ie->value.choice.GNB_DU_UE_F1AP_ID = f1ap_get_du_ue_f1ap_id(&f1ap_cu_inst[instance], cmd->rnti);
+  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+
+  /* mandatory */
+  /* c3. Cause */
+  ie = (F1AP_UEContextReleaseCommandIEs_t *)calloc(1, sizeof(F1AP_UEContextReleaseCommandIEs_t));
+  ie->id                             = F1AP_ProtocolIE_ID_id_Cause;
+  ie->criticality                    = F1AP_Criticality_ignore;
+  ie->value.present                  = F1AP_UEContextReleaseCommandIEs__value_PR_Cause;
+
+  switch (cmd->cause) {
+    case F1AP_CAUSE_RADIO_NETWORK:
+      ie->value.choice.Cause.present = F1AP_Cause_PR_radioNetwork;
+      ie->value.choice.Cause.choice.radioNetwork = cmd->cause_value;
+      break;
+    case F1AP_CAUSE_TRANSPORT:
+      ie->value.choice.Cause.present = F1AP_Cause_PR_transport;
+      ie->value.choice.Cause.choice.transport = cmd->cause_value;
+      break;
+    case F1AP_CAUSE_PROTOCOL:
+      ie->value.choice.Cause.present = F1AP_Cause_PR_protocol;
+      ie->value.choice.Cause.choice.protocol = cmd->cause_value;
+      break;
+    case F1AP_CAUSE_MISC:
+      ie->value.choice.Cause.present = F1AP_Cause_PR_misc;
+      ie->value.choice.Cause.choice.misc = cmd->cause_value;
+      break;
+    case F1AP_CAUSE_NOTHING:
+    default:
+      ie->value.choice.Cause.present = F1AP_Cause_PR_NOTHING;
+      break;
+  }
+  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+
+  /* optional */
+  /* c4. RRCContainer */
+  ie = (F1AP_UEContextReleaseCommandIEs_t *)calloc(1, sizeof(F1AP_UEContextReleaseCommandIEs_t));
+  ie->id                             = F1AP_ProtocolIE_ID_id_RRCContainer;
+  ie->criticality                    = F1AP_Criticality_ignore;
+  ie->value.present                  = F1AP_UEContextReleaseCommandIEs__value_PR_RRCContainer;
+
+  OCTET_STRING_fromBuf(&ie->value.choice.RRCContainer, (const char *)cmd->rrc_container,
+                       cmd->rrc_container_length);
+  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+
+  /* encode */
+  if (f1ap_encode_pdu(&pdu, &buffer, &len) < 0) {
+    LOG_E(F1AP, "Failed to encode F1 context release command\n");
+    return -1;
+  }
+
+  cu_f1ap_itti_send_sctp_data_req(instance, f1ap_du_data_from_du->assoc_id, buffer, len, 0);
+
+  return 0;
+}
+
+int CU_handle_UE_CONTEXT_RELEASE_COMPLETE(instance_t       instance,
+                                         uint32_t         assoc_id,
+                                         uint32_t         stream,
+                                         F1AP_F1AP_PDU_t *pdu) {
+  F1AP_UEContextReleaseComplete_t    *container;
+  F1AP_UEContextReleaseCompleteIEs_t *ie;
+
+  DevAssert(pdu);
+
+  container = &pdu->choice.successfulOutcome->value.choice.UEContextReleaseComplete;
+  /* GNB_CU_UE_F1AP_ID */
+  F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextReleaseCompleteIEs_t, ie, container,
+                             F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID, true);
+  const rnti_t rnti = f1ap_get_rnti_by_cu_id(&f1ap_cu_inst[instance],
+                                             ie->value.choice.GNB_CU_UE_F1AP_ID);
+
+  /* GNB_DU_UE_F1AP_ID */
+  F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextReleaseCompleteIEs_t, ie, container,
+                             F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID, true);
+  const rnti_t rnti2 = f1ap_get_rnti_by_du_id(&f1ap_cu_inst[instance],
+                                              ie->value.choice.GNB_DU_UE_F1AP_ID);
+  AssertFatal(rnti == rnti2, "RNTI obtained through DU ID (%x) is different from CU ID (%x)\n",
+              rnti2, rnti);
+
+  /* Optional*/
+  /* CriticalityDiagnostics */
+  F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextReleaseCompleteIEs_t, ie, container,
+                             F1AP_ProtocolIE_ID_id_CriticalityDiagnostics, false);
+  if (ie) {
+    // ie->value.choice.CriticalityDiagnostics.procedureCode
+    // ie->value.choice.CriticalityDiagnostics.triggeringMessage
+    // ie->value.choice.CriticalityDiagnostics.procedureCriticality
+    // ie->value.choice.CriticalityDiagnostics.transactionID
+
+    // F1AP_CriticalityDiagnostics_IE_List
+  }
+
+  struct rrc_eNB_ue_context_s *ue_context_p =
+      rrc_eNB_get_ue_context(RC.rrc[instance], rnti);
+  protocol_ctxt_t ctxt;
+  PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, instance, ENB_FLAG_YES, rnti, 0, 0, instance);
+
+  if (ue_context_p) {
+    /* The following is normally done in the function rrc_rx_tx() */
+    rrc_eNB_send_S1AP_UE_CONTEXT_RELEASE_CPLT(instance,
+        ue_context_p->ue_context.eNB_ue_s1ap_id);
+
+    rrc_eNB_send_GTPV1U_ENB_DELETE_TUNNEL_REQ(instance, ue_context_p);
+    // erase data of GTP tunnels in UE context
+    for (int e_rab = 0; e_rab < ue_context_p->ue_context.nb_of_e_rabs; e_rab++) {
+      ue_context_p->ue_context.enb_gtp_teid[e_rab] = 0;
+      memset(&ue_context_p->ue_context.enb_gtp_addrs[e_rab],
+             0, sizeof(ue_context_p->ue_context.enb_gtp_addrs[e_rab]));
+      ue_context_p->ue_context.enb_gtp_ebi[e_rab]  = 0;
+    }
+
+    struct rrc_ue_s1ap_ids_s *rrc_ue_s1ap_ids =
+        rrc_eNB_S1AP_get_ue_ids(RC.rrc[instance], 0,
+                                ue_context_p->ue_context.eNB_ue_s1ap_id);
+    if (rrc_ue_s1ap_ids)
+        rrc_eNB_S1AP_remove_ue_ids(RC.rrc[instance], rrc_ue_s1ap_ids);
+
+    /* trigger UE release in RRC */
+    rrc_eNB_remove_ue_context(&ctxt, RC.rrc[instance], ue_context_p);
+  } else {
+    LOG_E(F1AP, "could not find ue_context of UE RNTI %x\n", rnti);
+  }
+
+  pdcp_remove_UE(&ctxt);
+
+  /* notify the agent */
+  if (flexran_agent_get_rrc_xface(instance))
+    flexran_agent_get_rrc_xface(instance)->flexran_agent_notify_ue_state_change(
+        instance, rnti, PROTOCOL__FLEX_UE_STATE_CHANGE_TYPE__FLUESC_DEACTIVATED);
+
+  LOG_I(F1AP, "Received UE CONTEXT RELEASE COMPLETE: Removing CU UE entry for RNTI %x\n", rnti);
+  f1ap_remove_ue(&f1ap_cu_inst[instance], rnti);
+  return 0;
+}
+
+
+//void CU_send_UE_CONTEXT_MODIFICATION_REQUEST(F1AP_UEContextModificationRequest_t *UEContextModificationRequest) {
+int CU_send_UE_CONTEXT_MODIFICATION_REQUEST(instance_t instance) {
+  F1AP_F1AP_PDU_t                        pdu;
+  F1AP_UEContextModificationRequest_t    *out;
+  F1AP_UEContextModificationRequestIEs_t *ie;
+
+  uint8_t  *buffer;
+  uint32_t  len;
+  int       i = 0;
+
+  // for test
+  int mcc = 208;
+  int mnc = 93;
+  int mnc_digit_length = 8;
+
+  /* Create */
+  /* 0. Message Type */
+  memset(&pdu, 0, sizeof(pdu));
+  pdu.present = F1AP_F1AP_PDU_PR_initiatingMessage;
+  pdu.choice.initiatingMessage = (F1AP_InitiatingMessage_t *)calloc(1, sizeof(F1AP_InitiatingMessage_t));
+  pdu.choice.initiatingMessage->procedureCode = F1AP_ProcedureCode_id_UEContextModification;
+  pdu.choice.initiatingMessage->criticality   = F1AP_Criticality_reject;
+  pdu.choice.initiatingMessage->value.present = F1AP_InitiatingMessage__value_PR_UEContextModificationRequest;
+  out = &pdu.choice.initiatingMessage->value.choice.UEContextModificationRequest;
+  
+  /* mandatory */
+  /* c1. GNB_CU_UE_F1AP_ID */
+  ie = (F1AP_UEContextModificationRequestIEs_t *)calloc(1, sizeof(F1AP_UEContextModificationRequestIEs_t));
+  ie->id                             = F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID;
+  ie->criticality                    = F1AP_Criticality_reject;
+  ie->value.present                  = F1AP_UEContextModificationRequestIEs__value_PR_GNB_CU_UE_F1AP_ID;
+  ie->value.choice.GNB_CU_UE_F1AP_ID = 126L;
+  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+
+  /* mandatory */
+  /* c2. GNB_DU_UE_F1AP_ID */
+  ie = (F1AP_UEContextModificationRequestIEs_t *)calloc(1, sizeof(F1AP_UEContextModificationRequestIEs_t));
+  ie->id                             = F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID;
+  ie->criticality                    = F1AP_Criticality_reject;
+  ie->value.present                  = F1AP_UEContextModificationRequestIEs__value_PR_GNB_DU_UE_F1AP_ID;
+  ie->value.choice.GNB_DU_UE_F1AP_ID = 651L;
+  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+
+  /* optional */
+  /* c3. NRCGI */
+  if (0) {
+    ie = (F1AP_UEContextModificationRequestIEs_t *)calloc(1, sizeof(F1AP_UEContextModificationRequestIEs_t));
+    ie->id                             = F1AP_ProtocolIE_ID_id_SpCell_ID;
+    ie->criticality                    = F1AP_Criticality_ignore;
+    ie->value.present                  = F1AP_UEContextModificationRequestIEs__value_PR_NRCGI;
+    /* - nRCGI */
+    F1AP_NRCGI_t nRCGI;
+    MCC_MNC_TO_PLMNID(mcc, mnc, mnc_digit_length,
+                                         &nRCGI.pLMN_Identity);
+    NR_CELL_ID_TO_BIT_STRING(123456, &nRCGI.nRCellIdentity);
+    ie->value.choice.NRCGI = nRCGI;
+
+    ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+  }
+
+  /* mandatory */
+  /* c4. ServCellIndex */
+  ie = (F1AP_UEContextModificationRequestIEs_t *)calloc(1, sizeof(F1AP_UEContextModificationRequestIEs_t));
+  ie->id                             = F1AP_ProtocolIE_ID_id_ServCellndex;
+  ie->criticality                    = F1AP_Criticality_reject;
+  ie->value.present                  = F1AP_UEContextModificationRequestIEs__value_PR_ServCellIndex;
+  ie->value.choice.ServCellIndex     = 5L;
+  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+
+  /* optional */
+  /* c5. DRXCycle */
+  if (0) {
+    ie = (F1AP_UEContextModificationRequestIEs_t *)calloc(1, sizeof(F1AP_UEContextModificationRequestIEs_t));
+    ie->id                             = F1AP_ProtocolIE_ID_id_DRXCycle;
+    ie->criticality                    = F1AP_Criticality_ignore;
+    ie->value.present                  = F1AP_UEContextModificationRequestIEs__value_PR_DRXCycle;
+    ie->value.choice.DRXCycle.longDRXCycleLength = F1AP_LongDRXCycleLength_ms10; // enum
+    if (0) {
+      ie->value.choice.DRXCycle.shortDRXCycleLength = (F1AP_ShortDRXCycleLength_t *)calloc(1, sizeof(F1AP_ShortDRXCycleLength_t));
+      *ie->value.choice.DRXCycle.shortDRXCycleLength = F1AP_ShortDRXCycleLength_ms2; // enum
+    }
+    if (0) {
+      ie->value.choice.DRXCycle.shortDRXCycleTimer = (F1AP_ShortDRXCycleTimer_t *)calloc(1, sizeof(F1AP_ShortDRXCycleTimer_t));
+      *ie->value.choice.DRXCycle.shortDRXCycleTimer = 123L;
+    }
+    ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+  }
+
+  /* optional */
+  /* c5. CUtoDURRCInformation */
+  if (1) {
+    ie = (F1AP_UEContextModificationRequestIEs_t *)calloc(1, sizeof(F1AP_UEContextModificationRequestIEs_t));
+    ie->id                             = F1AP_ProtocolIE_ID_id_CUtoDURRCInformation;
+    ie->criticality                    = F1AP_Criticality_reject;
+    ie->value.present                  = F1AP_UEContextModificationRequestIEs__value_PR_CUtoDURRCInformation;
+    ie->value.choice.CUtoDURRCInformation.cG_ConfigInfo = (F1AP_CG_ConfigInfo_t *)calloc(1, sizeof(F1AP_CG_ConfigInfo_t));
+    /* optional */
+    OCTET_STRING_fromBuf(ie->value.choice.CUtoDURRCInformation.cG_ConfigInfo, "asdsa1d32sa1d31asd31as",
+                         strlen("asdsa1d32sa1d31asd31as"));
+    ie->value.choice.CUtoDURRCInformation.uE_CapabilityRAT_ContainerList = (F1AP_UE_CapabilityRAT_ContainerList_t *)calloc(1, sizeof(F1AP_UE_CapabilityRAT_ContainerList_t));
+    /* optional */
+    OCTET_STRING_fromBuf(ie->value.choice.CUtoDURRCInformation.uE_CapabilityRAT_ContainerList, "asdsa1d32sa1d31asd31as",
+                         strlen("asdsa1d32sa1d31asd31as"));
+    ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+  }
+
+  /* optional */
+  /* c6. TransmissionStopIndicator */
+  if (1) {
+    ie = (F1AP_UEContextModificationRequestIEs_t *)calloc(1, sizeof(F1AP_UEContextModificationRequestIEs_t));
+    ie->id                                     = F1AP_ProtocolIE_ID_id_TransmissionStopIndicator;
+    ie->criticality                            = F1AP_Criticality_ignore;
+    ie->value.present                          = F1AP_UEContextModificationRequestIEs__value_PR_TransmissionStopIndicator;
+    ie->value.choice.TransmissionStopIndicator = F1AP_TransmissionStopIndicator_true;
+    ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+  }
+
+  /* optional */
+  /* c7. ResourceCoordinationTransferContainer */
+  if (0) {
+    ie = (F1AP_UEContextModificationRequestIEs_t *)calloc(1, sizeof(F1AP_UEContextModificationRequestIEs_t));
+    ie->id                             = F1AP_ProtocolIE_ID_id_ResourceCoordinationTransferContainer;
+    ie->criticality                    = F1AP_Criticality_ignore;
+    ie->value.present                  = F1AP_UEContextModificationRequestIEs__value_PR_ResourceCoordinationTransferContainer;
+    OCTET_STRING_fromBuf(&ie->value.choice.ResourceCoordinationTransferContainer, "asdsa1d32sa1d31asd31as",
+                         strlen("asdsa1d32sa1d31asd31as"));
+    ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+  }
+
+  /* optional */
+  /* c7. RRCRconfigurationCompleteIndicator */
+  if (1) {
+    ie = (F1AP_UEContextModificationRequestIEs_t *)calloc(1, sizeof(F1AP_UEContextModificationRequestIEs_t));
+    ie->id                             = F1AP_ProtocolIE_ID_id_RRCRconfigurationCompleteIndicator;
+    ie->criticality                    = F1AP_Criticality_ignore;
+    ie->value.present                  = F1AP_UEContextModificationRequestIEs__value_PR_RRCRconfigurationCompleteIndicator;
+    ie->value.choice.RRCRconfigurationCompleteIndicator = F1AP_RRCRconfigurationCompleteIndicator_true;
+    ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+  }
+
+  /* optional */
+  /* c8. RRCContainer */
+  if (1) {
+    ie = (F1AP_UEContextModificationRequestIEs_t *)calloc(1, sizeof(F1AP_UEContextModificationRequestIEs_t));
+    ie->id                             = F1AP_ProtocolIE_ID_id_RRCContainer;
+    ie->criticality                    = F1AP_Criticality_ignore;
+    ie->value.present                  = F1AP_UEContextModificationRequestIEs__value_PR_RRCContainer;
+    OCTET_STRING_fromBuf(&ie->value.choice.RRCContainer, "asdsa1d32sa1d31asd31as",
+                         strlen("asdsa1d32sa1d31asd31as"));
+    ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+  }
+
+  /* mandatory */
+  /* c9. SCell_ToBeSetupMod_List */
+  ie = (F1AP_UEContextModificationRequestIEs_t *)calloc(1, sizeof(F1AP_UEContextModificationRequestIEs_t));
+  ie->id                             = F1AP_ProtocolIE_ID_id_SCell_ToBeSetupMod_List;
+  ie->criticality                    = F1AP_Criticality_ignore;
+  ie->value.present                  = F1AP_UEContextModificationRequestIEs__value_PR_SCell_ToBeSetupMod_List;
+
+  for (i=0;
+       i<1;
+       i++) {
+     //
+     F1AP_SCell_ToBeSetupMod_ItemIEs_t *scell_toBeSetupMod_item_ies;
+     scell_toBeSetupMod_item_ies = (F1AP_SCell_ToBeSetupMod_ItemIEs_t *)calloc(1, sizeof(F1AP_SCell_ToBeSetupMod_ItemIEs_t));
+     //memset((void *)&scell_toBeSetupMod_item_ies, 0, sizeof(F1AP_SCell_ToBeSetupMod_ItemIEs_t));
+     scell_toBeSetupMod_item_ies->id            = F1AP_ProtocolIE_ID_id_SCell_ToBeSetupMod_Item;
+     scell_toBeSetupMod_item_ies->criticality   = F1AP_Criticality_ignore;
+     scell_toBeSetupMod_item_ies->value.present = F1AP_SCell_ToBeSetupMod_ItemIEs__value_PR_SCell_ToBeSetupMod_Item;
+
+     /* 8.1 SCell_ToBeSetup_Item */
+     F1AP_SCell_ToBeSetupMod_Item_t scell_toBeSetupMod_item;
+     memset((void *)&scell_toBeSetupMod_item, 0, sizeof(F1AP_SCell_ToBeSetupMod_Item_t));
+
+  //   /* - sCell_ID */
+     F1AP_NRCGI_t nRCGI;
+     MCC_MNC_TO_PLMNID(mcc, mnc, mnc_digit_length,
+                                        &nRCGI.pLMN_Identity);
+     NR_CELL_ID_TO_BIT_STRING(123456, &nRCGI.nRCellIdentity);
+     scell_toBeSetupMod_item.sCell_ID = nRCGI;
+
+     /* sCellIndex */
+     scell_toBeSetupMod_item.sCellIndex = 6;  // issue here
+
+     //   /* ADD */
+     scell_toBeSetupMod_item_ies->value.choice.SCell_ToBeSetupMod_Item = scell_toBeSetupMod_item;
+     ASN_SEQUENCE_ADD(&ie->value.choice.SCell_ToBeSetupMod_List.list,
+                      scell_toBeSetupMod_item_ies);
+  }
+  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+
+  /* mandatory */
+  /* c10. SCell_ToBeRemoved_List */
+  ie = (F1AP_UEContextModificationRequestIEs_t *)calloc(1, sizeof(F1AP_UEContextModificationRequestIEs_t));
+  ie->id                             = F1AP_ProtocolIE_ID_id_SCell_ToBeRemoved_List;
+  ie->criticality                    = F1AP_Criticality_ignore;
+  ie->value.present                  = F1AP_UEContextModificationRequestIEs__value_PR_SCell_ToBeRemoved_List;
+
+  for (i=0;
+       i<1;
+       i++) {
+     //
+     F1AP_SCell_ToBeRemoved_ItemIEs_t *scell_toBeRemoved_item_ies;
+     scell_toBeRemoved_item_ies = (F1AP_SCell_ToBeRemoved_ItemIEs_t *)calloc(1, sizeof(F1AP_SCell_ToBeRemoved_ItemIEs_t));
+     //memset((void *)&scell_toBeRemoved_item_ies, 0, sizeof(F1AP_SCell_ToBeRemoved_ItemIEs_t));
+     scell_toBeRemoved_item_ies->id            = F1AP_ProtocolIE_ID_id_SCell_ToBeRemoved_Item;
+     scell_toBeRemoved_item_ies->criticality   = F1AP_Criticality_ignore;
+     scell_toBeRemoved_item_ies->value.present = F1AP_SCell_ToBeRemoved_ItemIEs__value_PR_SCell_ToBeRemoved_Item;
+
+     /* 10.1 SCell_ToBeRemoved_Item */
+     F1AP_SCell_ToBeRemoved_Item_t scell_toBeRemoved_item;
+     memset((void *)&scell_toBeRemoved_item, 0, sizeof(F1AP_SCell_ToBeRemoved_Item_t));
+
+     /* - sCell_ID */
+     F1AP_NRCGI_t nRCGI;
+     MCC_MNC_TO_PLMNID(mcc, mnc, mnc_digit_length,
+                                        &nRCGI.pLMN_Identity);
+     NR_CELL_ID_TO_BIT_STRING(123456, &nRCGI.nRCellIdentity);
+     scell_toBeRemoved_item.sCell_ID = nRCGI;
+
+     /* ADD */
+     scell_toBeRemoved_item_ies->value.choice.SCell_ToBeRemoved_Item = scell_toBeRemoved_item;
+     ASN_SEQUENCE_ADD(&ie->value.choice.SCell_ToBeRemoved_List.list,
+                      scell_toBeRemoved_item_ies);
+  }
+  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+
+  /* mandatory */
+  /* c11. SRBs_ToBeSetupMod_List */
+  ie = (F1AP_UEContextModificationRequestIEs_t *)calloc(1, sizeof(F1AP_UEContextModificationRequestIEs_t));
+  ie->id                             = F1AP_ProtocolIE_ID_id_SRBs_ToBeSetupMod_List;
+  ie->criticality                    = F1AP_Criticality_reject;
+  ie->value.present                  = F1AP_UEContextModificationRequestIEs__value_PR_SRBs_ToBeSetupMod_List;
+
+  for (i=0;
+       i<1;
+       i++) {
+    //
+    F1AP_SRBs_ToBeSetupMod_ItemIEs_t *srbs_toBeSetupMod_item_ies;
+    srbs_toBeSetupMod_item_ies = (F1AP_SRBs_ToBeSetupMod_ItemIEs_t *)calloc(1, sizeof(F1AP_SRBs_ToBeSetupMod_ItemIEs_t));
+    //memset((void *)&srbs_toBeSetupMod_item_ies, 0, sizeof(F1AP_SRBs_ToBeSetupMod_ItemIEs_t));
+    srbs_toBeSetupMod_item_ies->id            = F1AP_ProtocolIE_ID_id_SRBs_ToBeSetupMod_Item;
+    srbs_toBeSetupMod_item_ies->criticality   = F1AP_Criticality_ignore;
+    srbs_toBeSetupMod_item_ies->value.present = F1AP_SRBs_ToBeSetupMod_ItemIEs__value_PR_SRBs_ToBeSetupMod_Item;
+
+    /* 9.1 SRBs_ToBeSetupMod_Item */
+    F1AP_SRBs_ToBeSetupMod_Item_t srbs_toBeSetupMod_item;
+    memset((void *)&srbs_toBeSetupMod_item, 0, sizeof(F1AP_SRBs_ToBeSetupMod_Item_t));
+
+    /* - sRBID */
+    srbs_toBeSetupMod_item.sRBID = 3L;
+
+    /* ADD */
+    srbs_toBeSetupMod_item_ies->value.choice.SRBs_ToBeSetupMod_Item = srbs_toBeSetupMod_item;
+
+    ASN_SEQUENCE_ADD(&ie->value.choice.SRBs_ToBeSetupMod_List.list,
+                     srbs_toBeSetupMod_item_ies);
+  }
+  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+
+
+  /* mandatory */
+  /* c12. DRBs_ToBeSetupMod_List */
+  ie = (F1AP_UEContextModificationRequestIEs_t *)calloc(1, sizeof(F1AP_UEContextModificationRequestIEs_t));
+  ie->id                             = F1AP_ProtocolIE_ID_id_DRBs_ToBeSetupMod_List;
+  ie->criticality                    = F1AP_Criticality_reject;
+  ie->value.present                  = F1AP_UEContextModificationRequestIEs__value_PR_DRBs_ToBeSetupMod_List;
+
+  for (i=0;
+       i<1;
+       i++) {
+    //
+    F1AP_DRBs_ToBeSetupMod_ItemIEs_t *drbs_toBeSetupMod_item_ies;
+    drbs_toBeSetupMod_item_ies = (F1AP_DRBs_ToBeSetupMod_ItemIEs_t *)calloc(1, sizeof(F1AP_DRBs_ToBeSetupMod_ItemIEs_t));
+    drbs_toBeSetupMod_item_ies->id            = F1AP_ProtocolIE_ID_id_DRBs_ToBeSetupMod_Item;
+    drbs_toBeSetupMod_item_ies->criticality   = F1AP_Criticality_reject;
+    drbs_toBeSetupMod_item_ies->value.present = F1AP_DRBs_ToBeSetupMod_ItemIEs__value_PR_DRBs_ToBeSetupMod_Item;
+
+    /* 12.1 DRBs_ToBeSetupMod_Item */
+    F1AP_DRBs_ToBeSetupMod_Item_t drbs_toBeSetupMod_item;
+    memset((void *)&drbs_toBeSetupMod_item, 0, sizeof(F1AP_DRBs_ToBeSetupMod_Item_t));
+
+    /* dRBID */
+    drbs_toBeSetupMod_item.dRBID = 30L;
+
+    /* qoSInformation */
+    drbs_toBeSetupMod_item.qoSInformation.present = F1AP_QoSInformation_PR_eUTRANQoS;
+    drbs_toBeSetupMod_item.qoSInformation.choice.eUTRANQoS = (F1AP_EUTRANQoS_t *)calloc(1, sizeof(F1AP_EUTRANQoS_t));
+    drbs_toBeSetupMod_item.qoSInformation.choice.eUTRANQoS->qCI = 253L;
+
+    /* uLUPTNLInformation_ToBeSetup_List */
+    int j = 0;
+    int maxnoofULTunnels = 1; // 2;
+    for (j=0;
+            j<maxnoofULTunnels;
+            j++) {
+            /*  ULTunnels_ToBeSetup_Item */
+
+            F1AP_ULUPTNLInformation_ToBeSetup_Item_t *uLUPTNLInformation_ToBeSetup_Item;
+            uLUPTNLInformation_ToBeSetup_Item = (F1AP_ULUPTNLInformation_ToBeSetup_Item_t *)calloc(1, sizeof(F1AP_ULUPTNLInformation_ToBeSetup_Item_t));
+            uLUPTNLInformation_ToBeSetup_Item->uLUPTNLInformation.present = F1AP_UPTransportLayerInformation_PR_gTPTunnel;
+            F1AP_GTPTunnel_t *gTPTunnel = (F1AP_GTPTunnel_t *)calloc(1, sizeof(F1AP_GTPTunnel_t));
+
+            /* transportLayerAddress */
+            TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(1234, &gTPTunnel->transportLayerAddress);
+
+            /* gTP_TEID */
+            OCTET_STRING_fromBuf(&gTPTunnel->gTP_TEID, "4567",
+                             strlen("4567"));
+
+            // Add
+            uLUPTNLInformation_ToBeSetup_Item->uLUPTNLInformation.choice.gTPTunnel = gTPTunnel;
+            ASN_SEQUENCE_ADD(&drbs_toBeSetupMod_item.uLUPTNLInformation_ToBeSetup_List.list, uLUPTNLInformation_ToBeSetup_Item);
+    }
+
+    /* rLCMode */
+    drbs_toBeSetupMod_item.rLCMode = F1AP_RLCMode_rlc_um; // enum
+
+    /* OPTIONAL */
+    /* ULConfiguration */
+    if (0) {
+       drbs_toBeSetupMod_item.uLConfiguration = (F1AP_ULConfiguration_t *)calloc(1, sizeof(F1AP_ULConfiguration_t));
+    }
+
+    /* ADD */
+    drbs_toBeSetupMod_item_ies->value.choice.DRBs_ToBeSetupMod_Item = drbs_toBeSetupMod_item;
+    ASN_SEQUENCE_ADD(&ie->value.choice.DRBs_ToBeSetupMod_List.list,
+                   drbs_toBeSetupMod_item_ies);
+    
+  }
+  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+
+  /* mandatory */
+  /* c13. DRBs_ToBeModified_List */
+  ie = (F1AP_UEContextModificationRequestIEs_t *)calloc(1, sizeof(F1AP_UEContextModificationRequestIEs_t));
+  ie->id                             = F1AP_ProtocolIE_ID_id_DRBs_ToBeModified_List;
+  ie->criticality                    = F1AP_Criticality_reject;
+  ie->value.present                  = F1AP_UEContextModificationRequestIEs__value_PR_DRBs_ToBeModified_List;
+
+  for (i=0;
+       i<1;
+       i++) {
+    //
+    F1AP_DRBs_ToBeModified_ItemIEs_t *drbs_toBeModified_item_ies;
+    drbs_toBeModified_item_ies = (F1AP_DRBs_ToBeModified_ItemIEs_t *)calloc(1, sizeof(F1AP_DRBs_ToBeModified_ItemIEs_t));
+    drbs_toBeModified_item_ies->id            = F1AP_ProtocolIE_ID_id_DRBs_ToBeModified_Item;
+    drbs_toBeModified_item_ies->criticality   = F1AP_Criticality_reject;
+    drbs_toBeModified_item_ies->value.present = F1AP_DRBs_ToBeModified_ItemIEs__value_PR_DRBs_ToBeModified_Item;
+
+    /* 13.1 SRBs_ToBeModified_Item */
+    F1AP_DRBs_ToBeModified_Item_t drbs_toBeModified_item;
+    memset((void *)&drbs_toBeModified_item, 0, sizeof(F1AP_DRBs_ToBeModified_Item_t));
+
+    /* dRBID */
+    drbs_toBeModified_item.dRBID = 30L;
+
+    /* qoSInformation */
+    drbs_toBeModified_item.qoSInformation.present = F1AP_QoSInformation_PR_eUTRANQoS;
+    drbs_toBeModified_item.qoSInformation.choice.eUTRANQoS = (F1AP_EUTRANQoS_t *)calloc(1, sizeof(F1AP_EUTRANQoS_t));
+    drbs_toBeModified_item.qoSInformation.choice.eUTRANQoS->qCI = 254L;
+
+    /* ULTunnels_ToBeModified_List */
+    int j = 0;
+    int maxnoofULTunnels = 1; // 2;
+    for (j=0;
+            j<maxnoofULTunnels;
+            j++) {
+            /*  ULTunnels_ToBeModified_Item */
+            F1AP_ULUPTNLInformation_ToBeSetup_Item_t *uLUPTNLInformation_ToBeSetup_Item;
+            uLUPTNLInformation_ToBeSetup_Item = (F1AP_ULUPTNLInformation_ToBeSetup_Item_t *)calloc(1, sizeof(F1AP_ULUPTNLInformation_ToBeSetup_Item_t));
+            uLUPTNLInformation_ToBeSetup_Item->uLUPTNLInformation.present = F1AP_UPTransportLayerInformation_PR_gTPTunnel;
+            F1AP_GTPTunnel_t *gTPTunnel = (F1AP_GTPTunnel_t *)calloc(1, sizeof(F1AP_GTPTunnel_t));
+
+            TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(1234, &gTPTunnel->transportLayerAddress);
+
+            OCTET_STRING_fromBuf(&gTPTunnel->gTP_TEID, "1204",
+                                 strlen("1204"));
+
+            uLUPTNLInformation_ToBeSetup_Item->uLUPTNLInformation.choice.gTPTunnel = gTPTunnel;
+
+            ASN_SEQUENCE_ADD(&drbs_toBeModified_item.uLUPTNLInformation_ToBeSetup_List.list, uLUPTNLInformation_ToBeSetup_Item);
+    }
+
+    /* OPTIONAL */
+    /* ULConfiguration */
+    if (0) {
+       drbs_toBeModified_item.uLConfiguration = (F1AP_ULConfiguration_t *)calloc(1, sizeof(F1AP_ULConfiguration_t));
+    }
+
+    /* ADD */
+    drbs_toBeModified_item_ies->value.choice.DRBs_ToBeModified_Item = drbs_toBeModified_item;
+    ASN_SEQUENCE_ADD(&ie->value.choice.DRBs_ToBeModified_List.list,
+                   drbs_toBeModified_item_ies);
+
+  }
+  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+
+  /* mandatory */
+  /* c14. SRBs_ToBeReleased_List */
+  ie = (F1AP_UEContextModificationRequestIEs_t *)calloc(1, sizeof(F1AP_UEContextModificationRequestIEs_t));
+  ie->id                             = F1AP_ProtocolIE_ID_id_SRBs_ToBeReleased_List;
+  ie->criticality                    = F1AP_Criticality_reject;
+  ie->value.present                  = F1AP_UEContextModificationRequestIEs__value_PR_SRBs_ToBeReleased_List;
+
+  for (i=0;
+       i<1;
+       i++) {
+    //
+    F1AP_SRBs_ToBeReleased_ItemIEs_t *srbs_toBeReleased_item_ies;
+    srbs_toBeReleased_item_ies = (F1AP_SRBs_ToBeReleased_ItemIEs_t *)calloc(1, sizeof(F1AP_SRBs_ToBeReleased_ItemIEs_t));
+    //memset((void *)&srbs_toBeReleased_item_ies, 0, sizeof(F1AP_SRBs_ToBeReleased_ItemIEs_t));
+    srbs_toBeReleased_item_ies->id            = F1AP_ProtocolIE_ID_id_SRBs_ToBeReleased_Item;
+    srbs_toBeReleased_item_ies->criticality   = F1AP_Criticality_ignore;
+    srbs_toBeReleased_item_ies->value.present = F1AP_SRBs_ToBeReleased_ItemIEs__value_PR_SRBs_ToBeReleased_Item;
+
+    /* 9.1 SRBs_ToBeReleased_Item */
+    F1AP_SRBs_ToBeReleased_Item_t srbs_toBeReleased_item;
+    memset((void *)&srbs_toBeReleased_item, 0, sizeof(F1AP_SRBs_ToBeReleased_Item_t));
+
+    /* - sRBID */
+    srbs_toBeReleased_item.sRBID = 2L;
+
+    /* ADD */
+    srbs_toBeReleased_item_ies->value.choice.SRBs_ToBeReleased_Item = srbs_toBeReleased_item;
+    ASN_SEQUENCE_ADD(&ie->value.choice.SRBs_ToBeReleased_List.list,
+                    srbs_toBeReleased_item_ies);
+  }
+  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+
+  /* mandatory */
+  /* c15. DRBs_ToBeReleased_List */
+  ie = (F1AP_UEContextModificationRequestIEs_t *)calloc(1, sizeof(F1AP_UEContextModificationRequestIEs_t));
+  ie->id                             = F1AP_ProtocolIE_ID_id_DRBs_ToBeReleased_List;
+  ie->criticality                    = F1AP_Criticality_reject;
+  ie->value.present                  = F1AP_UEContextModificationRequestIEs__value_PR_DRBs_ToBeReleased_List;
+
+  for (i=0;
+       i<1;
+       i++) {
+    //
+    F1AP_DRBs_ToBeReleased_ItemIEs_t *drbs_toBeReleased_item_ies;
+    drbs_toBeReleased_item_ies = (F1AP_DRBs_ToBeReleased_ItemIEs_t *)calloc(1, sizeof(F1AP_DRBs_ToBeReleased_ItemIEs_t));
+    drbs_toBeReleased_item_ies->id            = F1AP_ProtocolIE_ID_id_DRBs_ToBeReleased_Item;
+    drbs_toBeReleased_item_ies->criticality   = F1AP_Criticality_reject;
+    drbs_toBeReleased_item_ies->value.present = F1AP_DRBs_ToBeReleased_ItemIEs__value_PR_DRBs_ToBeReleased_Item;
+
+    /* 14.1 SRBs_ToBeReleased_Item */
+    F1AP_DRBs_ToBeReleased_Item_t drbs_toBeReleased_item;
+    memset((void *)&drbs_toBeReleased_item, 0, sizeof(F1AP_DRBs_ToBeReleased_Item_t));
+
+    /* dRBID */
+    drbs_toBeReleased_item.dRBID = 30L;
+
+    /* ADD */
+    drbs_toBeReleased_item_ies->value.choice.DRBs_ToBeReleased_Item = drbs_toBeReleased_item;
+    ASN_SEQUENCE_ADD(&ie->value.choice.DRBs_ToBeReleased_List.list,
+                    drbs_toBeReleased_item_ies);
+
+  }
+  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+
+  /* encode */
+  if (f1ap_encode_pdu(&pdu, &buffer, &len) < 0) {
+    LOG_E(F1AP, "Failed to encode F1 setup request\n");
+    return -1;
+  }
+
+  return 0;
+}
+
+int CU_handle_UE_CONTEXT_MODIFICATION_RESPONSE(instance_t       instance,
+                                               uint32_t         assoc_id,
+                                               uint32_t         stream,
+                                               F1AP_F1AP_PDU_t *pdu) {
+  AssertFatal(1==0,"Not implemented yet\n");
+}
+
+int CU_handle_UE_CONTEXT_MODIFICATION_FAILURE(instance_t       instance,
+                                              uint32_t         assoc_id,
+                                              uint32_t         stream,
+                                              F1AP_F1AP_PDU_t *pdu) {
+  AssertFatal(1==0,"Not implemented yet\n");
+}
+
+int CU_handle_UE_CONTEXT_MODIFICATION_REQUIRED(instance_t       instance,
+                                               uint32_t         assoc_id,
+                                               uint32_t         stream,
+                                               F1AP_F1AP_PDU_t *pdu) {
+  AssertFatal(1==0,"Not implemented yet\n");
+}
+
+int CU_send_UE_CONTEXT_MODIFICATION_CONFIRM(instance_t instance,
+                                            F1AP_UEContextModificationConfirm_t UEContextModificationConfirm_t) {
+  AssertFatal(1==0,"Not implemented yet\n");
+}
diff --git a/openair2/F1AP/f1ap_cu_ue_context_management.h b/openair2/F1AP/f1ap_cu_ue_context_management.h
new file mode 100644
index 0000000000000000000000000000000000000000..cc4ca3e35f08cf768842e14a2410db6f4b828518
--- /dev/null
+++ b/openair2/F1AP/f1ap_cu_ue_context_management.h
@@ -0,0 +1,103 @@
+/*
+ * 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
+ */
+
+/*! \file f1ap_cu_ue_context_management.h
+ * \brief header file of CU UE Context management
+ * \author EURECOM/NTUST
+ * \date 2018
+ * \version 0.1
+ * \company Eurecom
+ * \email: navid.nikaein@eurecom.fr, bing-kai.hong@eurecom.fr
+ * \note
+ * \warning
+ */
+
+#ifndef F1AP_CU_UE_CONTEXT_MANAGEMENT_H_
+#define F1AP_CU_UE_CONTEXT_MANAGEMENT_H_
+
+/*
+ * UE Context Setup
+ */
+int CU_send_UE_CONTEXT_SETUP_REQUEST(instance_t instance,
+                                     f1ap_ue_context_setup_req_t *f1ap_ue_context_setup_req);
+
+int CU_handle_UE_CONTEXT_SETUP_RESPONSE(instance_t       instance,
+                                        uint32_t         assoc_id,
+                                        uint32_t         stream,
+                                        F1AP_F1AP_PDU_t *pdu);
+
+int CU_handle_UE_CONTEXT_SETUP_FAILURE(instance_t       instance,
+                                       uint32_t         assoc_id,
+                                       uint32_t         stream,
+                                       F1AP_F1AP_PDU_t *pdu);
+
+
+/*
+ * UE Context Release Request (gNB-DU initiated)
+ */
+int CU_handle_UE_CONTEXT_RELEASE_REQUEST(instance_t       instance,
+                                         uint32_t         assoc_id,
+                                         uint32_t         stream,
+                                         F1AP_F1AP_PDU_t *pdu);
+
+/*
+ * UE Context Release (gNB-CU initiated)
+ */
+int CU_send_UE_CONTEXT_RELEASE_COMMAND(instance_t instance,
+                                       f1ap_ue_context_release_cmd_t *cmd);
+
+int CU_handle_UE_CONTEXT_RELEASE_COMPLETE(instance_t       instance,
+                                         uint32_t         assoc_id,
+                                         uint32_t         stream,
+                                         F1AP_F1AP_PDU_t *pdu);
+
+/*
+ * UE Context Modification (gNB-CU initiated)
+ */
+int CU_send_UE_CONTEXT_MODIFICATION_REQUEST(instance_t instance);
+int CU_handle_UE_CONTEXT_MODIFICATION_RESPONSE(instance_t       instance,
+                                               uint32_t         assoc_id,
+                                               uint32_t         stream,
+                                               F1AP_F1AP_PDU_t *pdu);
+int CU_handle_UE_CONTEXT_MODIFICATION_FAILURE(instance_t       instance,
+                                              uint32_t         assoc_id,
+                                              uint32_t         stream,
+                                              F1AP_F1AP_PDU_t *pdu);
+
+/*
+ * UE Context Modification Required (gNB-DU initiated)
+ */
+int CU_handle_UE_CONTEXT_MODIFICATION_REQUIRED(instance_t       instance,
+                                               uint32_t         assoc_id,
+                                               uint32_t         stream,
+                                               F1AP_F1AP_PDU_t *pdu);
+int CU_send_UE_CONTEXT_MODIFICATION_CONFIRM(instance_t instance,
+                                            F1AP_UEContextModificationConfirm_t UEContextModificationConfirm_t);
+
+/*
+ * UE Inactivity Notification
+ */
+
+/*
+ * Notify
+ */
+
+#endif /* F1AP_CU_UE_CONTEXT_MANAGEMENT_H_ */
diff --git a/openair2/F1AP/f1ap_cu_warning_message_transmission.c b/openair2/F1AP/f1ap_cu_warning_message_transmission.c
new file mode 100644
index 0000000000000000000000000000000000000000..b6bbedba2f0ed9c62704a0f9fdcf52c3e182ed60
--- /dev/null
+++ b/openair2/F1AP/f1ap_cu_warning_message_transmission.c
@@ -0,0 +1,31 @@
+/*
+ * 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
+ */
+
+/*! \file f1ap_du_interface_management.h
+ * \brief f1ap interface management for DU
+ * \author EURECOM/NTUST
+ * \date 2018
+ * \version 0.1
+ * \company Eurecom
+ * \email: navid.nikaein@eurecom.fr, bing-kai.hong@eurecom.fr
+ * \note
+ * \warning
+ */
\ No newline at end of file
diff --git a/openair2/F1AP/f1ap_cu_warning_message_transmission.h b/openair2/F1AP/f1ap_cu_warning_message_transmission.h
new file mode 100644
index 0000000000000000000000000000000000000000..b6bbedba2f0ed9c62704a0f9fdcf52c3e182ed60
--- /dev/null
+++ b/openair2/F1AP/f1ap_cu_warning_message_transmission.h
@@ -0,0 +1,31 @@
+/*
+ * 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
+ */
+
+/*! \file f1ap_du_interface_management.h
+ * \brief f1ap interface management for DU
+ * \author EURECOM/NTUST
+ * \date 2018
+ * \version 0.1
+ * \company Eurecom
+ * \email: navid.nikaein@eurecom.fr, bing-kai.hong@eurecom.fr
+ * \note
+ * \warning
+ */
\ No newline at end of file
diff --git a/openair2/F1AP/f1ap_decoder.c b/openair2/F1AP/f1ap_decoder.c
new file mode 100644
index 0000000000000000000000000000000000000000..7bd5359e29fa0665f387134c28a6a1be8c5dd837
--- /dev/null
+++ b/openair2/F1AP/f1ap_decoder.c
@@ -0,0 +1,181 @@
+/*
+ * 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
+ */
+
+/*! \file f1ap_decoder.c
+ * \brief f1ap pdu decode procedures
+ * \author EURECOM/NTUST
+ * \date 2018
+ * \version 0.1
+ * \company Eurecom
+ * \email: navid.nikaein@eurecom.fr, bing-kai.hong@eurecom.fr
+ * \note
+ * \warning
+ */
+
+#include "f1ap_common.h"
+#include "f1ap_decoder.h"
+
+int asn1_decoder_xer_print = 0;
+
+static int f1ap_decode_initiating_message(F1AP_F1AP_PDU_t *pdu)
+{
+  //MessageDef *message_p;
+  //MessagesIds message_id;
+  //asn_encode_to_new_buffer_result_t res = { NULL, {0, NULL, NULL} };
+  DevAssert(pdu != NULL);
+
+  switch(pdu->choice.initiatingMessage->procedureCode) {
+    
+    case F1AP_ProcedureCode_id_F1Setup:
+      //res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_F1AP_F1AP_PDU, pdu);
+      LOG_I(F1AP, "%s(): F1AP_ProcedureCode_id_F1Setup\n", __func__);
+      break;
+
+    case F1AP_ProcedureCode_id_InitialULRRCMessageTransfer:
+      //res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_F1AP_F1AP_PDU, pdu);
+      LOG_I(F1AP, "%s(): F1AP_ProcedureCode_id_InitialULRRCMessageTransfer\n", __func__);
+      break;
+
+    case F1AP_ProcedureCode_id_DLRRCMessageTransfer:
+      //res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_F1AP_F1AP_PDU, pdu);
+      LOG_I(F1AP, "%s(): F1AP_ProcedureCode_id_DLRRCMessageTransfer\n", __func__);
+      break;
+
+    case F1AP_ProcedureCode_id_ULRRCMessageTransfer:
+      //res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_F1AP_F1AP_PDU, pdu);
+      LOG_I(F1AP, "%s(): F1AP_ProcedureCode_id_ULRRCMessageTransfer\n", __func__);
+      break;
+    case F1AP_ProcedureCode_id_UEContextRelease:
+      LOG_I(F1AP, "%s(): F1AP_ProcedureCode_id_UEContextRelease\n", __func__);
+      break;
+    case F1AP_ProcedureCode_id_UEContextReleaseRequest:
+      LOG_I(F1AP, "%s(): F1AP_ProcedureCode_id_UEContextReleaseRequest\n", __func__);
+      break;
+    // case F1AP_ProcedureCode_id_InitialContextSetup:
+    //   res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_F1AP_F1AP_PDU, pdu);
+    //   message_id = F1AP_INITIAL_CONTEXT_SETUP_LOG;
+    //   message_p = itti_alloc_new_message_sized(TASK_F1AP, message_id,
+    //               res.result.encoded + sizeof (IttiMsgText));
+    //   message_p->ittiMsg.f1ap_initial_context_setup_log.size = res.result.encoded;
+    //   memcpy(&message_p->ittiMsg.f1ap_initial_context_setup_log.text, res.buffer, res.result.encoded);
+    //   itti_send_msg_to_task(TASK_UNKNOWN, INSTANCE_DEFAULT, message_p);
+    //   free(res.buffer);
+    //   break;
+
+    default:
+      // F1AP_ERROR("Unknown procedure ID (%d) for initiating message\n",
+      //            (int)pdu->choice.initiatingMessage->procedureCode);
+      LOG_E(F1AP, "Unknown procedure ID (%d) for initiating message\n",
+                  (int)pdu->choice.initiatingMessage->procedureCode);
+      AssertFatal( 0, "Unknown procedure ID (%d) for initiating message\n",
+                   (int)pdu->choice.initiatingMessage->procedureCode);
+      return -1;
+  }
+
+  return 0;
+}
+
+static int f1ap_decode_successful_outcome(F1AP_F1AP_PDU_t *pdu)
+{
+  DevAssert(pdu != NULL);
+
+  switch(pdu->choice.successfulOutcome->procedureCode) {
+    case F1AP_ProcedureCode_id_F1Setup:
+      LOG_I(F1AP, "%s(): F1AP_ProcedureCode_id_F1Setup\n", __func__);
+      break;
+
+    case F1AP_ProcedureCode_id_UEContextRelease:
+      LOG_I(F1AP, "%s(): F1AP_ProcedureCode_id_UEContextRelease\n", __func__);
+      break;
+
+    default:
+      LOG_E(F1AP,"Unknown procedure ID (%d) for successfull outcome message\n",
+                 (int)pdu->choice.successfulOutcome->procedureCode);
+      return -1;
+  }
+
+  return 0;
+}
+
+static int f1ap_decode_unsuccessful_outcome(F1AP_F1AP_PDU_t *pdu)
+{
+  DevAssert(pdu != NULL);
+
+  switch(pdu->choice.unsuccessfulOutcome->procedureCode) {
+    case F1AP_ProcedureCode_id_F1Setup:
+    LOG_I(F1AP, "%s(): F1AP_ProcedureCode_id_F1Setup\n", __func__);
+    break;
+
+    default:
+      // F1AP_ERROR("Unknown procedure ID (%d) for unsuccessfull outcome message\n",
+      //            (int)pdu->choice.unsuccessfulOutcome->procedureCode);
+      LOG_E(F1AP, "Unknown procedure ID (%d) for unsuccessfull outcome message\n",
+                 (int)pdu->choice.unsuccessfulOutcome->procedureCode);
+      return -1;
+  }
+
+  return 0;
+}
+
+int f1ap_decode_pdu(F1AP_F1AP_PDU_t *pdu, const uint8_t *const buffer, uint32_t length)
+{
+  asn_dec_rval_t dec_ret;
+
+  DevAssert(buffer != NULL);
+
+  dec_ret = aper_decode(NULL,
+                        &asn_DEF_F1AP_F1AP_PDU,
+                        (void **)&pdu,
+                        buffer,
+                        length,
+                        0,
+                        0);
+
+  if (asn1_decoder_xer_print) {
+    LOG_E(F1AP, "----------------- ASN1 DECODER PRINT START----------------- \n");
+    xer_fprint(stdout, &asn_DEF_F1AP_F1AP_PDU, pdu);
+    LOG_E(F1AP, "----------------- ASN1 DECODER PRINT END ----------------- \n");
+  }
+  //LOG_I(F1AP, "f1ap_decode_pdu.dec_ret.code = %d\n", dec_ret.code);
+
+  if (dec_ret.code != RC_OK) {
+    LOG_E(F1AP, "Failed to decode pdu\n");
+    return -1;
+  }
+
+  switch(pdu->present) {
+    case F1AP_F1AP_PDU_PR_initiatingMessage:
+      return f1ap_decode_initiating_message(pdu);
+
+    case F1AP_F1AP_PDU_PR_successfulOutcome:
+      return f1ap_decode_successful_outcome(pdu);
+
+    case F1AP_F1AP_PDU_PR_unsuccessfulOutcome:
+      return f1ap_decode_unsuccessful_outcome(pdu);
+
+    default:
+      LOG_E(F1AP, "Unknown presence (%d) or not implemented\n", (int)pdu->present);
+      break;
+  }
+
+
+  return -1;
+}
diff --git a/openair2/F1AP/f1ap_decoder.h b/openair2/F1AP/f1ap_decoder.h
new file mode 100644
index 0000000000000000000000000000000000000000..57814db34df79c031956c94488621a2081d484b7
--- /dev/null
+++ b/openair2/F1AP/f1ap_decoder.h
@@ -0,0 +1,39 @@
+/*
+ * 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
+ */
+
+/*! \file f1ap_decoder.h
+ * \brief f1ap pdu decode procedures
+ * \author EURECOM/NTUST
+ * \date 2018
+ * \version 0.1
+ * \company Eurecom
+ * \email: navid.nikaein@eurecom.fr, bing-kai.hong@eurecom.fr
+ * \note
+ * \warning
+ */
+
+#ifndef F1AP_ENB_ENCODER_H_
+#define F1AP_ENB_ENCODER_H_
+
+int f1ap_decode_pdu(F1AP_F1AP_PDU_t *pdu, const uint8_t *const buffer, uint32_t length)
+__attribute__ ((warn_unused_result));
+
+#endif /* F1AP_ENB_ENCODER_H_ */
diff --git a/openair2/F1AP/f1ap_default_values.h b/openair2/F1AP/f1ap_default_values.h
new file mode 100644
index 0000000000000000000000000000000000000000..91a11796240a85284a8388b717a16783d7a110b8
--- /dev/null
+++ b/openair2/F1AP/f1ap_default_values.h
@@ -0,0 +1,46 @@
+/*
+ * 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
+ */
+
+/*! \file f1ap_default_values.h
+ * \brief default values for f1ap procedures
+ * \author EURECOM/NTUST
+ * \date 2018
+ * \version 0.1
+ * \company Eurecom
+ * \email: navid.nikaein@eurecom.fr, bing-kai.hong@eurecom.fr
+ * \note
+ * \warning
+ */
+
+#ifndef F1AP_DEFAULT_VALUES_H_
+#define F1AP_DEFAULT_VALUES_H_
+
+#define ENB_TAC (1)
+#define ENB_MCC (208)
+#define ENB_MNC (92)
+
+#define ENB_NAME        "Eurecom ENB"
+#define ENB_NAME_FORMAT (ENB_NAME" %u")
+
+#define F1AP_PORT_NUMBER        (30923)
+#define F1AP_SCTP_PPID          (62)
+
+#endif /* F1AP_DEFAULT_VALUES_H_ */
diff --git a/openair2/F1AP/f1ap_du_interface_management.c b/openair2/F1AP/f1ap_du_interface_management.c
new file mode 100644
index 0000000000000000000000000000000000000000..f076b28a44930fe37d228ed09d0b017733dd07bd
--- /dev/null
+++ b/openair2/F1AP/f1ap_du_interface_management.c
@@ -0,0 +1,1050 @@
+/*
+ * 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
+ */
+
+/*! \file f1ap_du_interface_management.c
+ * \brief f1ap interface management for DU
+ * \author EURECOM/NTUST
+ * \date 2018
+ * \version 0.1
+ * \company Eurecom
+ * \email: navid.nikaein@eurecom.fr, bing-kai.hong@eurecom.fr
+ * \note
+ * \warning
+ */
+
+#include "f1ap_common.h"
+#include "f1ap_encoder.h"
+#include "f1ap_decoder.h"
+#include "f1ap_itti_messaging.h"
+#include "f1ap_du_interface_management.h"
+#include "assertions.h"
+
+extern f1ap_setup_req_t *f1ap_du_data;
+
+
+int DU_handle_RESET(instance_t instance,
+                                uint32_t assoc_id,
+                                uint32_t stream,
+                                F1AP_F1AP_PDU_t *pdu) {
+  AssertFatal(1==0,"Not implemented yet\n");
+}
+
+int DU_send_RESET_ACKKNOWLEDGE(instance_t instance, F1AP_ResetAcknowledge_t *ResetAcknowledge) {
+  AssertFatal(1==0,"Not implemented yet\n");
+}
+
+int DU_send_RESET(instance_t instance, F1AP_Reset_t *Reset) {
+  AssertFatal(1==0,"Not implemented yet\n");
+}
+
+int DU_handle_RESET_ACKNOWLEDGE(instance_t instance,
+                                uint32_t assoc_id,
+                                uint32_t stream,
+                                F1AP_F1AP_PDU_t *pdu) {
+  AssertFatal(1==0,"Not implemented yet\n");
+}
+
+
+/*
+    Error Indication
+*/
+
+int DU_send_ERROR_INDICATION(instance_t instance, F1AP_F1AP_PDU_t *pdu_p) {
+  AssertFatal(1==0,"Not implemented yet\n");
+}
+
+int DU_handle_ERROR_INDICATION(instance_t instance,
+                                uint32_t assoc_id,
+                                uint32_t stream,
+                                F1AP_F1AP_PDU_t *pdu) {
+  AssertFatal(1==0,"Not implemented yet\n");
+}
+
+
+/*
+    F1 Setup
+*/
+
+// SETUP REQUEST
+int DU_send_F1_SETUP_REQUEST(instance_t instance) {
+  module_id_t enb_mod_idP=0;
+  module_id_t du_mod_idP=0;
+
+  F1AP_F1AP_PDU_t          pdu; 
+  F1AP_F1SetupRequest_t    *out;
+  F1AP_F1SetupRequestIEs_t *ie;
+
+  uint8_t  *buffer;
+  uint32_t  len;
+  int       i = 0;
+  int       j = 0;
+
+  /* Create */
+  /* 0. pdu Type */
+  memset(&pdu, 0, sizeof(pdu));
+  pdu.present = F1AP_F1AP_PDU_PR_initiatingMessage;
+  pdu.choice.initiatingMessage = (F1AP_InitiatingMessage_t *)calloc(1, sizeof(F1AP_InitiatingMessage_t));
+  pdu.choice.initiatingMessage->procedureCode = F1AP_ProcedureCode_id_F1Setup;
+  pdu.choice.initiatingMessage->criticality   = F1AP_Criticality_reject;
+  pdu.choice.initiatingMessage->value.present = F1AP_InitiatingMessage__value_PR_F1SetupRequest;
+  out = &pdu.choice.initiatingMessage->value.choice.F1SetupRequest;
+
+  /* mandatory */
+  /* c1. Transaction ID (integer value) */
+  ie = (F1AP_F1SetupRequestIEs_t *)calloc(1, sizeof(F1AP_F1SetupRequestIEs_t));
+  ie->id                        = F1AP_ProtocolIE_ID_id_TransactionID;
+  ie->criticality               = F1AP_Criticality_reject;
+  ie->value.present             = F1AP_F1SetupRequestIEs__value_PR_TransactionID;
+  ie->value.choice.TransactionID = F1AP_get_next_transaction_identifier(enb_mod_idP, du_mod_idP);
+  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+
+  /* mandatory */
+  /* c2. GNB_DU_ID (integrer value) */
+  ie = (F1AP_F1SetupRequestIEs_t *)calloc(1, sizeof(F1AP_F1SetupRequestIEs_t));
+  ie->id                        = F1AP_ProtocolIE_ID_id_gNB_DU_ID;
+  ie->criticality               = F1AP_Criticality_reject;
+  ie->value.present             = F1AP_F1SetupRequestIEs__value_PR_GNB_DU_ID;
+  asn_int642INTEGER(&ie->value.choice.GNB_DU_ID, f1ap_du_data->gNB_DU_id);
+  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+
+  /* optional */
+  /* c3. GNB_DU_Name */
+  if (f1ap_du_data->gNB_DU_name != NULL) {
+    ie = (F1AP_F1SetupRequestIEs_t *)calloc(1, sizeof(F1AP_F1SetupRequestIEs_t));
+    ie->id                        = F1AP_ProtocolIE_ID_id_gNB_DU_Name;
+    ie->criticality               = F1AP_Criticality_ignore;
+    ie->value.present             = F1AP_F1SetupRequestIEs__value_PR_GNB_DU_Name;
+    OCTET_STRING_fromBuf(&ie->value.choice.GNB_DU_Name, f1ap_du_data->gNB_DU_name,
+                         strlen(f1ap_du_data->gNB_DU_name));
+    ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+  }
+
+  /* mandatory */
+  /* c4. serverd cells list */
+  ie = (F1AP_F1SetupRequestIEs_t *)calloc(1, sizeof(F1AP_F1SetupRequestIEs_t));
+  ie->id                        = F1AP_ProtocolIE_ID_id_gNB_DU_Served_Cells_List;
+  ie->criticality               = F1AP_Criticality_reject;
+  ie->value.present             = F1AP_F1SetupRequestIEs__value_PR_GNB_DU_Served_Cells_List;
+
+  int num_cells_available = f1ap_du_data->num_cells_available;
+  LOG_D(F1AP, "num_cells_available = %d \n", num_cells_available);
+  for (i=0;
+       i<num_cells_available;
+       i++) {
+        /* mandatory */
+        /* 4.1 serverd cells item */
+
+        F1AP_GNB_DU_Served_Cells_ItemIEs_t *gnb_du_served_cell_list_item_ies;
+        gnb_du_served_cell_list_item_ies = (F1AP_GNB_DU_Served_Cells_ItemIEs_t *)calloc(1, sizeof(F1AP_GNB_DU_Served_Cells_ItemIEs_t));
+        gnb_du_served_cell_list_item_ies->id = F1AP_ProtocolIE_ID_id_GNB_DU_Served_Cells_Item;
+        gnb_du_served_cell_list_item_ies->criticality = F1AP_Criticality_reject;
+        gnb_du_served_cell_list_item_ies->value.present = F1AP_GNB_DU_Served_Cells_ItemIEs__value_PR_GNB_DU_Served_Cells_Item;
+        
+
+        F1AP_GNB_DU_Served_Cells_Item_t gnb_du_served_cells_item;
+        memset((void *)&gnb_du_served_cells_item, 0, sizeof(F1AP_GNB_DU_Served_Cells_Item_t));
+
+        /* 4.1.1 serverd cell Information */
+        F1AP_Served_Cell_Information_t served_cell_information;
+
+        memset((void *)&served_cell_information, 0, sizeof(F1AP_Served_Cell_Information_t));
+
+        /* - nRCGI */
+        F1AP_NRCGI_t nRCGI;
+        MCC_MNC_TO_PLMNID(f1ap_du_data->mcc[i], f1ap_du_data->mnc[i], f1ap_du_data->mnc_digit_length[i], &nRCGI.pLMN_Identity);
+        LOG_D(F1AP, "plmn: (%d,%d)\n",f1ap_du_data->mcc[i],f1ap_du_data->mnc[i]);
+        //MCC_MNC_TO_PLMNID(208, 95, 2, &nRCGI.pLMN_Identity);
+
+        NR_CELL_ID_TO_BIT_STRING(f1ap_du_data->nr_cellid[i], &nRCGI.nRCellIdentity);
+        LOG_D(F1AP, "nRCellIdentity (%llx): %x.%x.%x.%x.%x\n",
+              (long long unsigned int)f1ap_du_data->nr_cellid[i],
+              nRCGI.nRCellIdentity.buf[0],
+              nRCGI.nRCellIdentity.buf[1],
+              nRCGI.nRCellIdentity.buf[2],
+              nRCGI.nRCellIdentity.buf[3],
+              nRCGI.nRCellIdentity.buf[4]);
+
+        served_cell_information.nRCGI = nRCGI;
+
+        /* - nRPCI */
+        served_cell_information.nRPCI = f1ap_du_data->nr_pci[i];  // int 0..1007
+
+        /* - fiveGS_TAC */
+        OCTET_STRING_fromBuf(&served_cell_information.fiveGS_TAC,
+                             (const char*)&f1ap_du_data->tac[i],
+                             3);
+
+        /* - Configured_EPS_TAC */
+        if(0){
+          served_cell_information.configured_EPS_TAC = (F1AP_Configured_EPS_TAC_t *)calloc(1, sizeof(F1AP_Configured_EPS_TAC_t));
+          OCTET_STRING_fromBuf(served_cell_information.configured_EPS_TAC,
+                             "2",
+                             2);
+        }
+
+        /* - broadcast PLMNs */
+        // RK: add the num_available_broadcast_PLMNs to the message 
+        int num_available_broadcast_PLMNs = 1; //f1ap_du_data->num_available_broadcast_PLMNs;
+        LOG_D(F1AP, "num_available_broadcast_PLMNs = %d \n", num_available_broadcast_PLMNs);
+        for (j=0;
+            j<num_available_broadcast_PLMNs;    // num_available_broadcast_PLMNs
+            j++) {
+            /* > PLMN BroadcastPLMNs Item */
+            F1AP_BroadcastPLMNs_Item_t *broadcastPLMNs_Item = (F1AP_BroadcastPLMNs_Item_t *)calloc(1, sizeof(F1AP_BroadcastPLMNs_Item_t));
+            //MCC_MNC_TO_PLMNID(208, 95, 2, &broadcastPLMNs_Item->pLMN_Identity);
+            MCC_MNC_TO_PLMNID(f1ap_du_data->mcc[i], f1ap_du_data->mnc[i], f1ap_du_data->mnc_digit_length[i], &broadcastPLMNs_Item->pLMN_Identity);
+            ASN_SEQUENCE_ADD(&served_cell_information.servedPLMNs.list, broadcastPLMNs_Item);
+        }
+
+        // // /* - CHOICE NR-MODE-Info */
+        F1AP_NR_Mode_Info_t nR_Mode_Info;
+        //f1ap_du_data->fdd_flag = 1;
+        if (f1ap_du_data->fdd_flag) { // FDD
+          nR_Mode_Info.present = F1AP_NR_Mode_Info_PR_fDD;
+          F1AP_FDD_Info_t *fDD_Info = (F1AP_FDD_Info_t *)calloc(1, sizeof(F1AP_FDD_Info_t));
+
+          /* FDD.1 UL NRFreqInfo */
+            /* FDD.1.1 UL NRFreqInfo ARFCN */
+            fDD_Info->uL_NRFreqInfo.nRARFCN = f1ap_du_data->nr_mode_info[i].fdd.ul_nr_arfcn; // Integer
+
+            /* FDD.1.2 F1AP_SUL_Information */
+            if(0) { // Optional
+              F1AP_SUL_Information_t *fdd_sul_info = (F1AP_SUL_Information_t *)calloc(1, sizeof(F1AP_SUL_Information_t));
+              fdd_sul_info->sUL_NRARFCN = 0;
+              fdd_sul_info->sUL_transmission_Bandwidth.nRSCS = 0;
+              fdd_sul_info->sUL_transmission_Bandwidth.nRNRB = 0;
+              fDD_Info->uL_NRFreqInfo.sul_Information = fdd_sul_info;
+            }
+
+            /* FDD.1.3 freqBandListNr */
+            int fdd_ul_num_available_freq_Bands = f1ap_du_data->nr_mode_info[i].fdd.ul_num_frequency_bands;
+            LOG_D(F1AP, "fdd_ul_num_available_freq_Bands = %d \n", fdd_ul_num_available_freq_Bands);
+            int fdd_ul_j;
+            for (fdd_ul_j=0;
+                 fdd_ul_j<fdd_ul_num_available_freq_Bands;
+                 fdd_ul_j++) {
+
+                  F1AP_FreqBandNrItem_t nr_freqBandNrItem;
+                  memset((void *)&nr_freqBandNrItem, 0, sizeof(F1AP_FreqBandNrItem_t));
+                  /* FDD.1.3.1 freqBandIndicatorNr*/
+                  nr_freqBandNrItem.freqBandIndicatorNr = f1ap_du_data->nr_mode_info[i].fdd.ul_nr_band[fdd_ul_j]; //
+
+                  /* FDD.1.3.2 supportedSULBandList*/
+                  int num_available_supported_SULBands = f1ap_du_data->nr_mode_info[i].fdd.ul_num_sul_frequency_bands;
+                  LOG_D(F1AP, "num_available_supported_SULBands = %d \n", num_available_supported_SULBands);
+                  int fdd_ul_k;
+                  for (fdd_ul_k=0;
+                       fdd_ul_k<num_available_supported_SULBands;
+                       fdd_ul_k++) {
+                        F1AP_SupportedSULFreqBandItem_t nr_supportedSULFreqBandItem;
+                        memset((void *)&nr_supportedSULFreqBandItem, 0, sizeof(F1AP_SupportedSULFreqBandItem_t));
+                          /* FDD.1.3.2.1 freqBandIndicatorNr */
+                          nr_supportedSULFreqBandItem.freqBandIndicatorNr = f1ap_du_data->nr_mode_info[i].fdd.ul_nr_sul_band[fdd_ul_k]; //
+                        ASN_SEQUENCE_ADD(&nr_freqBandNrItem.supportedSULBandList.list, &nr_supportedSULFreqBandItem);
+                  } // for FDD : UL supported_SULBands
+                  ASN_SEQUENCE_ADD(&fDD_Info->uL_NRFreqInfo.freqBandListNr.list, &nr_freqBandNrItem);
+            } // for FDD : UL freq_Bands
+           
+          /* FDD.2 DL NRFreqInfo */
+            /* FDD.2.1 DL NRFreqInfo ARFCN */
+            fDD_Info->dL_NRFreqInfo.nRARFCN = f1ap_du_data->nr_mode_info[i].fdd.dl_nr_arfcn; // Integer
+
+            /* FDD.2.2 F1AP_SUL_Information */
+            if(0) { // Optional
+              F1AP_SUL_Information_t *fdd_sul_info = (F1AP_SUL_Information_t *)calloc(1, sizeof(F1AP_SUL_Information_t));
+              fdd_sul_info->sUL_NRARFCN = 0;
+              fdd_sul_info->sUL_transmission_Bandwidth.nRSCS = 0;
+              fdd_sul_info->sUL_transmission_Bandwidth.nRNRB = 0;
+              fDD_Info->dL_NRFreqInfo.sul_Information = fdd_sul_info;
+            }
+
+            /* FDD.2.3 freqBandListNr */
+            int fdd_dl_num_available_freq_Bands = f1ap_du_data->nr_mode_info[i].fdd.dl_num_frequency_bands;
+            LOG_D(F1AP, "fdd_dl_num_available_freq_Bands = %d \n", fdd_dl_num_available_freq_Bands);
+            int fdd_dl_j;
+            for (fdd_dl_j=0;
+                 fdd_dl_j<fdd_dl_num_available_freq_Bands;
+                 fdd_dl_j++) {
+
+                  F1AP_FreqBandNrItem_t nr_freqBandNrItem;
+                  memset((void *)&nr_freqBandNrItem, 0, sizeof(F1AP_FreqBandNrItem_t));
+                  /* FDD.2.3.1 freqBandIndicatorNr*/
+                  nr_freqBandNrItem.freqBandIndicatorNr = f1ap_du_data->nr_mode_info[i].fdd.dl_nr_band[fdd_dl_j]; //
+
+                  /* FDD.2.3.2 supportedSULBandList*/
+                  int num_available_supported_SULBands = f1ap_du_data->nr_mode_info[i].fdd.dl_num_sul_frequency_bands;
+                  LOG_D(F1AP, "num_available_supported_SULBands = %d \n", num_available_supported_SULBands);
+                  int fdd_dl_k;
+                  for (fdd_dl_k=0;
+                       fdd_dl_k<num_available_supported_SULBands;
+                       fdd_dl_k++) {
+                        F1AP_SupportedSULFreqBandItem_t nr_supportedSULFreqBandItem;
+                        memset((void *)&nr_supportedSULFreqBandItem, 0, sizeof(F1AP_SupportedSULFreqBandItem_t));
+                          /* FDD.2.3.2.1 freqBandIndicatorNr */
+                          nr_supportedSULFreqBandItem.freqBandIndicatorNr = f1ap_du_data->nr_mode_info[i].fdd.dl_nr_sul_band[fdd_dl_k]; //
+                        ASN_SEQUENCE_ADD(&nr_freqBandNrItem.supportedSULBandList.list, &nr_supportedSULFreqBandItem);
+                  } // for FDD : DL supported_SULBands
+                  ASN_SEQUENCE_ADD(&fDD_Info->dL_NRFreqInfo.freqBandListNr.list, &nr_freqBandNrItem);
+            } // for FDD : DL freq_Bands
+
+          /* FDD.3 UL Transmission Bandwidth */
+          fDD_Info->uL_Transmission_Bandwidth.nRSCS = f1ap_du_data->nr_mode_info[i].fdd.ul_scs;
+          fDD_Info->uL_Transmission_Bandwidth.nRNRB = f1ap_du_data->nr_mode_info[i].fdd.ul_nrb;
+          /* FDD.4 DL Transmission Bandwidth */
+          fDD_Info->dL_Transmission_Bandwidth.nRSCS = f1ap_du_data->nr_mode_info[i].fdd.dl_scs;
+          fDD_Info->dL_Transmission_Bandwidth.nRNRB = f1ap_du_data->nr_mode_info[i].fdd.dl_nrb;
+          
+          nR_Mode_Info.choice.fDD = fDD_Info;
+        } else { // TDD
+          nR_Mode_Info.present = F1AP_NR_Mode_Info_PR_tDD;
+          F1AP_TDD_Info_t *tDD_Info = (F1AP_TDD_Info_t *)calloc(1, sizeof(F1AP_TDD_Info_t));
+
+          /* TDD.1 nRFreqInfo */
+            /* TDD.1.1 nRFreqInfo ARFCN */
+            tDD_Info->nRFreqInfo.nRARFCN = f1ap_du_data->nr_mode_info[i].tdd.nr_arfcn; // Integer
+
+            /* TDD.1.2 F1AP_SUL_Information */
+            if(0) { // Optional
+              F1AP_SUL_Information_t *tdd_sul_info = (F1AP_SUL_Information_t *)calloc(1, sizeof(F1AP_SUL_Information_t));
+              tdd_sul_info->sUL_NRARFCN = 0;
+              tdd_sul_info->sUL_transmission_Bandwidth.nRSCS = 0;
+              tdd_sul_info->sUL_transmission_Bandwidth.nRNRB = 0;
+              tDD_Info->nRFreqInfo.sul_Information = tdd_sul_info;
+            }
+
+            /* TDD.1.3 freqBandListNr */
+            int tdd_num_available_freq_Bands = f1ap_du_data->nr_mode_info[i].tdd.num_frequency_bands;
+            LOG_D(F1AP, "tdd_num_available_freq_Bands = %d \n", tdd_num_available_freq_Bands);
+            int j;
+            for (j=0;
+                 j<tdd_num_available_freq_Bands;
+                 j++) {
+
+                  F1AP_FreqBandNrItem_t nr_freqBandNrItem;
+                  memset((void *)&nr_freqBandNrItem, 0, sizeof(F1AP_FreqBandNrItem_t));
+                  /* TDD.1.3.1 freqBandIndicatorNr*/
+                  nr_freqBandNrItem.freqBandIndicatorNr = *f1ap_du_data->nr_mode_info[i].tdd.nr_band; //
+
+                  /* TDD.1.3.2 supportedSULBandList*/
+                  int num_available_supported_SULBands = f1ap_du_data->nr_mode_info[i].tdd.num_sul_frequency_bands;
+                  LOG_D(F1AP, "num_available_supported_SULBands = %d \n", num_available_supported_SULBands);
+                  int k;
+                  for (k=0;
+                       k<num_available_supported_SULBands;
+                       k++) {
+                        F1AP_SupportedSULFreqBandItem_t nr_supportedSULFreqBandItem;
+                        memset((void *)&nr_supportedSULFreqBandItem, 0, sizeof(F1AP_SupportedSULFreqBandItem_t));
+                          /* TDD.1.3.2.1 freqBandIndicatorNr */
+                          nr_supportedSULFreqBandItem.freqBandIndicatorNr = *f1ap_du_data->nr_mode_info[i].tdd.nr_sul_band; //
+                        ASN_SEQUENCE_ADD(&nr_freqBandNrItem.supportedSULBandList.list, &nr_supportedSULFreqBandItem);
+                  } // for TDD : supported_SULBands
+                  ASN_SEQUENCE_ADD(&tDD_Info->nRFreqInfo.freqBandListNr.list, &nr_freqBandNrItem);
+            } // for TDD : freq_Bands
+
+          /* TDD.2 transmission_Bandwidth */
+          tDD_Info->transmission_Bandwidth.nRSCS = f1ap_du_data->nr_mode_info[i].tdd.scs;
+          tDD_Info->transmission_Bandwidth.nRNRB = f1ap_du_data->nr_mode_info[i].tdd.nrb;
+     
+          nR_Mode_Info.choice.tDD = tDD_Info;
+        } // if nR_Mode_Info
+        
+        served_cell_information.nR_Mode_Info = nR_Mode_Info;
+
+        /* - measurementTimingConfiguration */
+        char *measurementTimingConfiguration = f1ap_du_data->measurement_timing_information[i]; // sept. 2018
+
+        OCTET_STRING_fromBuf(&served_cell_information.measurementTimingConfiguration,
+                             measurementTimingConfiguration,
+                             strlen(measurementTimingConfiguration));
+        gnb_du_served_cells_item.served_Cell_Information = served_cell_information; //
+
+        /* 4.1.2 gNB-DU System Information */
+        F1AP_GNB_DU_System_Information_t *gNB_DU_System_Information = (F1AP_GNB_DU_System_Information_t *)calloc(1, sizeof(F1AP_GNB_DU_System_Information_t));
+
+        OCTET_STRING_fromBuf(&gNB_DU_System_Information->mIB_message,  // sept. 2018
+                             (const char*)f1ap_du_data->mib[i],//f1ap_du_data->mib,
+                             f1ap_du_data->mib_length[i]);
+
+        OCTET_STRING_fromBuf(&gNB_DU_System_Information->sIB1_message,  // sept. 2018
+                             (const char*)f1ap_du_data->sib1[i],
+                             f1ap_du_data->sib1_length[i]);
+
+        gnb_du_served_cells_item.gNB_DU_System_Information = gNB_DU_System_Information; //
+
+        /* ADD */
+        gnb_du_served_cell_list_item_ies->value.choice.GNB_DU_Served_Cells_Item = gnb_du_served_cells_item;
+
+        ASN_SEQUENCE_ADD(&ie->value.choice.GNB_DU_Served_Cells_List.list, 
+                        gnb_du_served_cell_list_item_ies);
+
+  }
+  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+
+  /* encode */
+  if (f1ap_encode_pdu(&pdu, &buffer, &len) < 0) {
+    LOG_E(F1AP, "Failed to encode F1 setup request\n");
+    return -1;
+  }
+
+  MSC_LOG_TX_MESSAGE(
+  MSC_F1AP_DU,
+  MSC_F1AP_CU,
+  (const char *)buffer,
+  len,
+  MSC_AS_TIME_FMT" F1_SETUP_REQUEST initiatingMessage gNB_DU_name %s",
+  0,0,//MSC_AS_TIME_ARGS(ctxt_pP),
+  f1ap_du_data->gNB_DU_name);
+
+  du_f1ap_itti_send_sctp_data_req(instance, f1ap_du_data->assoc_id, buffer, len, 0);
+
+  return 0;
+}
+
+int DU_handle_F1_SETUP_RESPONSE(instance_t instance,
+				uint32_t               assoc_id,
+				uint32_t               stream,
+				F1AP_F1AP_PDU_t       *pdu)
+{
+
+   LOG_D(F1AP, "DU_handle_F1_SETUP_RESPONSE\n");
+
+   AssertFatal(pdu->present == F1AP_F1AP_PDU_PR_successfulOutcome,
+	       "pdu->present != F1AP_F1AP_PDU_PR_successfulOutcome\n");
+   AssertFatal(pdu->choice.successfulOutcome->procedureCode  == F1AP_ProcedureCode_id_F1Setup,
+	       "pdu->choice.successfulOutcome->procedureCode != F1AP_ProcedureCode_id_F1Setup\n");
+   AssertFatal(pdu->choice.successfulOutcome->criticality  == F1AP_Criticality_reject,
+	       "pdu->choice.successfulOutcome->criticality != F1AP_Criticality_reject\n");
+   AssertFatal(pdu->choice.successfulOutcome->value.present  == F1AP_SuccessfulOutcome__value_PR_F1SetupResponse,
+	       "pdu->choice.successfulOutcome->value.present != F1AP_SuccessfulOutcome__value_PR_F1SetupResponse\n");
+
+   F1AP_F1SetupResponse_t    *in = &pdu->choice.successfulOutcome->value.choice.F1SetupResponse;
+
+
+   F1AP_F1SetupResponseIEs_t *ie;
+   int TransactionId = -1;
+   int num_cells_to_activate = 0;
+   F1AP_Cells_to_be_Activated_List_Item_t *cell;
+
+   MessageDef *msg_p = itti_alloc_new_message (TASK_DU_F1, F1AP_SETUP_RESP);
+
+   LOG_D(F1AP, "F1AP: F1Setup-Resp: protocolIEs.list.count %d\n",
+         in->protocolIEs.list.count);
+   for (int i=0;i < in->protocolIEs.list.count; i++) {
+     ie = in->protocolIEs.list.array[i];
+     switch (ie->id) {
+     case F1AP_ProtocolIE_ID_id_TransactionID:
+       AssertFatal(ie->criticality == F1AP_Criticality_reject,
+		   "ie->criticality != F1AP_Criticality_reject\n");
+       AssertFatal(ie->value.present == F1AP_F1SetupResponseIEs__value_PR_TransactionID,
+		   "ie->value.present != F1AP_F1SetupResponseIEs__value_PR_TransactionID\n");
+       TransactionId=ie->value.choice.TransactionID;
+       LOG_D(F1AP, "F1AP: F1Setup-Resp: TransactionId %d\n",
+             TransactionId);
+       break;
+     case F1AP_ProtocolIE_ID_id_gNB_CU_Name:
+       AssertFatal(ie->criticality == F1AP_Criticality_ignore,
+		   "ie->criticality != F1AP_Criticality_ignore\n");
+       AssertFatal(ie->value.present == F1AP_F1SetupResponseIEs__value_PR_GNB_CU_Name,
+		   "ie->value.present != F1AP_F1SetupResponseIEs__value_PR_TransactionID\n");
+       F1AP_SETUP_RESP (msg_p).gNB_CU_name = malloc(ie->value.choice.GNB_CU_Name.size+1);
+       memcpy(F1AP_SETUP_RESP (msg_p).gNB_CU_name,ie->value.choice.GNB_CU_Name.buf,ie->value.choice.GNB_CU_Name.size);
+       F1AP_SETUP_RESP (msg_p).gNB_CU_name[ie->value.choice.GNB_CU_Name.size]='\0';
+       LOG_D(F1AP, "F1AP: F1Setup-Resp: gNB_CU_name %s\n",
+             F1AP_SETUP_RESP (msg_p).gNB_CU_name);
+       break;
+     case F1AP_ProtocolIE_ID_id_Cells_to_be_Activated_List:
+       AssertFatal(ie->criticality == F1AP_Criticality_reject,
+		   "ie->criticality != F1AP_Criticality_reject\n");
+       AssertFatal(ie->value.present == F1AP_F1SetupResponseIEs__value_PR_Cells_to_be_Activated_List,
+		   "ie->value.present != F1AP_F1SetupResponseIEs__value_PR_Cells_to_be_Activated_List\n");
+       num_cells_to_activate = ie->value.choice.Cells_to_be_Activated_List.list.count;
+       LOG_D(F1AP, "F1AP: Activating %d cells\n",num_cells_to_activate);
+       for (int i=0;i<num_cells_to_activate;i++) {
+	 
+	 F1AP_Cells_to_be_Activated_List_ItemIEs_t *cells_to_be_activated_list_item_ies = (F1AP_Cells_to_be_Activated_List_ItemIEs_t *) ie->value.choice.Cells_to_be_Activated_List.list.array[i];
+
+	 AssertFatal(cells_to_be_activated_list_item_ies->id == F1AP_ProtocolIE_ID_id_Cells_to_be_Activated_List_Item,
+		   "cells_to_be_activated_list_item_ies->id != F1AP_ProtocolIE_ID_id_Cells_to_be_Activated_List_Item");
+	 AssertFatal(cells_to_be_activated_list_item_ies->criticality == F1AP_Criticality_reject,
+		     "cells_to_be_activated_list_item_ies->criticality == F1AP_Criticality_reject");
+	 AssertFatal(cells_to_be_activated_list_item_ies->value.present == F1AP_Cells_to_be_Activated_List_ItemIEs__value_PR_Cells_to_be_Activated_List_Item,
+		     "cells_to_be_activated_list_item_ies->value.present == F1AP_Cells_to_be_Activated_List_ItemIEs__value_PR_Cells_to_be_Activated_List_Item");
+
+	 cell = &cells_to_be_activated_list_item_ies->value.choice.Cells_to_be_Activated_List_Item;
+
+	 TBCD_TO_MCC_MNC(&cell->nRCGI.pLMN_Identity, F1AP_SETUP_RESP (msg_p).mcc[i], F1AP_SETUP_RESP (msg_p).mnc[i], F1AP_SETUP_RESP (msg_p).mnc_digit_length[i]);
+	 AssertFatal(cell->nRPCI != NULL, "nRPCI is null\n");
+	 LOG_D(F1AP, "nr_cellId : %x %x %x %x %x\n",
+         cell->nRCGI.nRCellIdentity.buf[0],
+         cell->nRCGI.nRCellIdentity.buf[1],
+         cell->nRCGI.nRCellIdentity.buf[2],
+         cell->nRCGI.nRCellIdentity.buf[3],
+         cell->nRCGI.nRCellIdentity.buf[4]);
+	 BIT_STRING_TO_NR_CELL_IDENTITY(&cell->nRCGI.nRCellIdentity,
+					F1AP_SETUP_RESP (msg_p).nr_cellid[i]);
+	 F1AP_SETUP_RESP (msg_p).nrpci[i] = *cell->nRPCI;
+
+	 F1AP_ProtocolExtensionContainer_160P9_t *ext = (F1AP_ProtocolExtensionContainer_160P9_t *)cell->iE_Extensions;
+	 AssertFatal(ext!=NULL,"Extension for SI is null\n");
+	 F1AP_SETUP_RESP (msg_p).num_SI[i] = ext->list.count;
+	 AssertFatal(ext->list.count==1,"At least one SI message should be there, and only 1 for now!\n");
+   LOG_D(F1AP, "F1AP: F1Setup-Resp Cell %d MCC %d MNC %d NRCellid %lx num_si %d\n",
+         i, F1AP_SETUP_RESP (msg_p).mcc[i], F1AP_SETUP_RESP (msg_p).mnc[i],
+         F1AP_SETUP_RESP (msg_p).nr_cellid[i], F1AP_SETUP_RESP (msg_p).num_SI[i]);
+	 for (int si =0;si < ext->list.count;si++) {
+	   size_t size = ext->list.array[si]->extensionValue.choice.GNB_CUSystemInformation.sImessage.size;
+	   F1AP_SETUP_RESP (msg_p).SI_container_length[i][si] = size;
+     LOG_D(F1AP, "F1AP: F1Setup-Resp SI_container_length[%d][%d] %ld bytes\n", i, si, size);
+	   F1AP_SETUP_RESP (msg_p).SI_container[i][si] = malloc(F1AP_SETUP_RESP (msg_p).SI_container_length[i][si]);
+
+	   memcpy((void*)F1AP_SETUP_RESP (msg_p).SI_container[i][si],
+		  (void*)ext->list.array[si]->extensionValue.choice.GNB_CUSystemInformation.sImessage.buf,
+		  F1AP_SETUP_RESP (msg_p).SI_container_length[i][si]);
+	 }
+       }
+       break;
+     }
+   }
+   AssertFatal(TransactionId!=-1,"TransactionId was not sent\n");
+   AssertFatal(num_cells_to_activate>0,"No cells activated\n");
+   F1AP_SETUP_RESP (msg_p).num_cells_to_activate = num_cells_to_activate;
+
+   for (int i=0;i<num_cells_to_activate;i++)  
+     AssertFatal(F1AP_SETUP_RESP (msg_p).num_SI[i] > 0, "System Information %d is missing",i);
+
+   MSC_LOG_RX_MESSAGE(
+    MSC_F1AP_DU,
+    MSC_F1AP_CU,
+    0,
+    0,
+    MSC_AS_TIME_FMT" DU_handle_F1_SETUP_RESPONSE successfulOutcome assoc_id %d",
+    0,0,//MSC_AS_TIME_ARGS(ctxt_pP),
+    assoc_id);
+ 
+   LOG_D(F1AP, "Sending F1AP_SETUP_RESP ITTI message to ENB_APP with assoc_id (%d->%d)\n",
+         assoc_id,ENB_MODULE_ID_TO_INSTANCE(assoc_id));
+   itti_send_msg_to_task(TASK_ENB_APP, ENB_MODULE_ID_TO_INSTANCE(assoc_id), msg_p);
+
+   return 0;
+}
+
+// SETUP FAILURE
+int DU_handle_F1_SETUP_FAILURE(instance_t instance,
+                               uint32_t assoc_id,
+                               uint32_t stream,
+                               F1AP_F1AP_PDU_t *pdu) {
+  LOG_E(F1AP, "DU_handle_F1_SETUP_FAILURE\n");
+  return 0;
+}
+
+
+/*
+    gNB-DU Configuration Update
+*/
+
+//void DU_send_gNB_DU_CONFIGURATION_UPDATE(F1AP_GNBDUConfigurationUpdate_t *GNBDUConfigurationUpdate) {
+int DU_send_gNB_DU_CONFIGURATION_UPDATE(instance_t instance,
+                                         instance_t du_mod_idP,
+                                         f1ap_setup_req_t *f1ap_setup_req) {
+  F1AP_F1AP_PDU_t                     pdu;
+  F1AP_GNBDUConfigurationUpdate_t     *out;
+  F1AP_GNBDUConfigurationUpdateIEs_t  *ie;
+
+  uint8_t  *buffer;
+  uint32_t  len;
+  int       i = 0;
+  int       j = 0;
+
+  /* Create */
+  /* 0. Message Type */
+  memset(&pdu, 0, sizeof(pdu));
+  pdu.present = F1AP_F1AP_PDU_PR_initiatingMessage;
+  pdu.choice.initiatingMessage = (F1AP_InitiatingMessage_t *)calloc(1, sizeof(F1AP_InitiatingMessage_t));
+  pdu.choice.initiatingMessage->procedureCode = F1AP_ProcedureCode_id_gNBDUConfigurationUpdate;
+  pdu.choice.initiatingMessage->criticality   = F1AP_Criticality_reject;
+  pdu.choice.initiatingMessage->value.present = F1AP_InitiatingMessage__value_PR_GNBDUConfigurationUpdate;
+  out = &pdu.choice.initiatingMessage->value.choice.GNBDUConfigurationUpdate;
+
+  /* mandatory */
+  /* c1. Transaction ID (integer value) */
+  ie = (F1AP_GNBDUConfigurationUpdateIEs_t *)calloc(1, sizeof(F1AP_GNBDUConfigurationUpdateIEs_t));
+  ie->id                        = F1AP_ProtocolIE_ID_id_TransactionID;
+  ie->criticality               = F1AP_Criticality_reject;
+  ie->value.present             = F1AP_GNBDUConfigurationUpdateIEs__value_PR_TransactionID;
+  ie->value.choice.TransactionID = F1AP_get_next_transaction_identifier(instance, du_mod_idP);
+  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+
+
+  /* mandatory */
+  /* c2. Served_Cells_To_Add */
+  ie = (F1AP_GNBDUConfigurationUpdateIEs_t *)calloc(1, sizeof(F1AP_GNBDUConfigurationUpdateIEs_t));
+  ie->id                        = F1AP_ProtocolIE_ID_id_Served_Cells_To_Add_List;
+  ie->criticality               = F1AP_Criticality_reject;
+  ie->value.present             = F1AP_GNBDUConfigurationUpdateIEs__value_PR_Served_Cells_To_Add_List;
+
+  for (j=0;
+       j<1;
+       j++) {
+        //
+        F1AP_Served_Cells_To_Add_ItemIEs_t *served_cells_to_add_item_ies;
+        served_cells_to_add_item_ies = (F1AP_Served_Cells_To_Add_ItemIEs_t *)calloc(1, sizeof(F1AP_Served_Cells_To_Add_ItemIEs_t));
+        served_cells_to_add_item_ies->id            = F1AP_ProtocolIE_ID_id_Served_Cells_To_Add_Item;
+        served_cells_to_add_item_ies->criticality   = F1AP_Criticality_reject;
+        served_cells_to_add_item_ies->value.present = F1AP_Served_Cells_To_Add_ItemIEs__value_PR_Served_Cells_To_Add_Item;
+        
+        F1AP_Served_Cells_To_Add_Item_t served_cells_to_add_item;
+        memset((void *)&served_cells_to_add_item, 0, sizeof(F1AP_Served_Cells_To_Add_Item_t));
+
+        /* 2.1.1 serverd cell Information */
+        F1AP_Served_Cell_Information_t served_cell_information;
+
+        memset((void *)&served_cell_information, 0, sizeof(F1AP_Served_Cell_Information_t));
+        /* - nRCGI */
+        F1AP_NRCGI_t nRCGI;
+        MCC_MNC_TO_PLMNID(f1ap_setup_req->mcc[i], f1ap_setup_req->mnc[i], f1ap_setup_req->mnc_digit_length[i], &nRCGI.pLMN_Identity);
+        LOG_D(F1AP, "nr_cellId : %x %x %x %x %x\n",
+              nRCGI.nRCellIdentity.buf[0],
+              nRCGI.nRCellIdentity.buf[1],
+              nRCGI.nRCellIdentity.buf[2],
+              nRCGI.nRCellIdentity.buf[3],
+              nRCGI.nRCellIdentity.buf[4]);
+        NR_CELL_ID_TO_BIT_STRING(f1ap_setup_req->nr_cellid[i], &nRCGI.nRCellIdentity);
+        served_cell_information.nRCGI = nRCGI;
+
+        /* - nRPCI */
+        served_cell_information.nRPCI = f1ap_setup_req->nr_pci[i];  // int 0..1007
+
+        /* - fiveGS_TAC */
+        OCTET_STRING_fromBuf(&served_cell_information.fiveGS_TAC,
+                             (const char *) &f1ap_setup_req->tac[i],
+                             3);
+
+        /* - Configured_EPS_TAC */
+        if(1){
+          served_cell_information.configured_EPS_TAC = (F1AP_Configured_EPS_TAC_t *)calloc(1, sizeof(F1AP_Configured_EPS_TAC_t));
+          OCTET_STRING_fromBuf(served_cell_information.configured_EPS_TAC,
+                             "2",
+                             2);
+        }
+
+        /* - broadcast PLMNs */
+        int maxnoofBPLMNS = 1;
+        for (i=0;
+            i<maxnoofBPLMNS;
+            i++) {
+            /* > PLMN BroadcastPLMNs Item */
+            F1AP_BroadcastPLMNs_Item_t *broadcastPLMNs_Item = (F1AP_BroadcastPLMNs_Item_t *)calloc(1, sizeof(F1AP_BroadcastPLMNs_Item_t));
+            //memset((void *)&broadcastPLMNs_Item, 0, sizeof(F1AP_BroadcastPLMNs_Item_t));
+            MCC_MNC_TO_PLMNID(f1ap_setup_req->mcc[i], f1ap_setup_req->mnc[i], f1ap_setup_req->mnc_digit_length[i], &broadcastPLMNs_Item->pLMN_Identity);
+            ASN_SEQUENCE_ADD(&served_cell_information.servedPLMNs.list, broadcastPLMNs_Item);
+        }
+
+        // // /* - CHOICE NR-MODE-Info */
+        F1AP_NR_Mode_Info_t nR_Mode_Info;
+
+        if (f1ap_setup_req->fdd_flag) {
+          nR_Mode_Info.present = F1AP_NR_Mode_Info_PR_fDD;
+          /* > FDD >> FDD Info */
+          F1AP_FDD_Info_t *fDD_Info = (F1AP_FDD_Info_t *)calloc(1, sizeof(F1AP_FDD_Info_t));
+          /* >>> UL NRFreqInfo */
+          fDD_Info->uL_NRFreqInfo.nRARFCN = 999L;
+
+          F1AP_FreqBandNrItem_t ul_freqBandNrItem;
+          memset((void *)&ul_freqBandNrItem, 0, sizeof(F1AP_FreqBandNrItem_t));
+          ul_freqBandNrItem.freqBandIndicatorNr = 888L;
+
+            F1AP_SupportedSULFreqBandItem_t ul_supportedSULFreqBandItem;
+            memset((void *)&ul_supportedSULFreqBandItem, 0, sizeof(F1AP_SupportedSULFreqBandItem_t));
+            ul_supportedSULFreqBandItem.freqBandIndicatorNr = 777L;
+            ASN_SEQUENCE_ADD(&ul_freqBandNrItem.supportedSULBandList.list, &ul_supportedSULFreqBandItem);
+
+          ASN_SEQUENCE_ADD(&fDD_Info->uL_NRFreqInfo.freqBandListNr.list, &ul_freqBandNrItem);
+
+          /* >>> DL NRFreqInfo */
+          fDD_Info->dL_NRFreqInfo.nRARFCN = 666L;
+
+          F1AP_FreqBandNrItem_t dl_freqBandNrItem;
+          memset((void *)&dl_freqBandNrItem, 0, sizeof(F1AP_FreqBandNrItem_t));
+          dl_freqBandNrItem.freqBandIndicatorNr = 555L;
+
+            F1AP_SupportedSULFreqBandItem_t dl_supportedSULFreqBandItem;
+            memset((void *)&dl_supportedSULFreqBandItem, 0, sizeof(F1AP_SupportedSULFreqBandItem_t));
+            dl_supportedSULFreqBandItem.freqBandIndicatorNr = 444L;
+            ASN_SEQUENCE_ADD(&dl_freqBandNrItem.supportedSULBandList.list, &dl_supportedSULFreqBandItem);
+
+          ASN_SEQUENCE_ADD(&fDD_Info->dL_NRFreqInfo.freqBandListNr.list, &dl_freqBandNrItem);
+
+          /* >>> UL Transmission Bandwidth */
+          fDD_Info->uL_Transmission_Bandwidth.nRSCS = F1AP_NRSCS_scs15;
+          fDD_Info->uL_Transmission_Bandwidth.nRNRB = F1AP_NRNRB_nrb11;
+          /* >>> DL Transmission Bandwidth */
+          fDD_Info->dL_Transmission_Bandwidth.nRSCS = F1AP_NRSCS_scs15;
+          fDD_Info->dL_Transmission_Bandwidth.nRNRB = F1AP_NRNRB_nrb11;
+          
+          nR_Mode_Info.choice.fDD = fDD_Info;
+        } else { // TDD
+          nR_Mode_Info.present = F1AP_NR_Mode_Info_PR_tDD;
+
+          /* > TDD >> TDD Info */
+          F1AP_TDD_Info_t *tDD_Info = (F1AP_TDD_Info_t *)calloc(1, sizeof(F1AP_TDD_Info_t));
+          /* >>> ARFCN */
+          tDD_Info->nRFreqInfo.nRARFCN = 999L; // Integer
+          F1AP_FreqBandNrItem_t nr_freqBandNrItem;
+          memset((void *)&nr_freqBandNrItem, 0, sizeof(F1AP_FreqBandNrItem_t));
+          nr_freqBandNrItem.freqBandIndicatorNr = 555L;
+
+            F1AP_SupportedSULFreqBandItem_t nr_supportedSULFreqBandItem;
+            memset((void *)&nr_supportedSULFreqBandItem, 0, sizeof(F1AP_SupportedSULFreqBandItem_t));
+            nr_supportedSULFreqBandItem.freqBandIndicatorNr = 444L;
+            ASN_SEQUENCE_ADD(&nr_freqBandNrItem.supportedSULBandList.list, &nr_supportedSULFreqBandItem);
+
+          ASN_SEQUENCE_ADD(&tDD_Info->nRFreqInfo.freqBandListNr.list, &nr_freqBandNrItem);
+
+          tDD_Info->transmission_Bandwidth.nRSCS= F1AP_NRSCS_scs15;
+          tDD_Info->transmission_Bandwidth.nRNRB= F1AP_NRNRB_nrb11;
+     
+          nR_Mode_Info.choice.tDD = tDD_Info;
+        } 
+        
+        served_cell_information.nR_Mode_Info = nR_Mode_Info;
+
+        /* - measurementTimingConfiguration */
+        char *measurementTimingConfiguration = "0"; // sept. 2018
+
+        OCTET_STRING_fromBuf(&served_cell_information.measurementTimingConfiguration,
+                             measurementTimingConfiguration,
+                             strlen(measurementTimingConfiguration));
+        served_cells_to_add_item.served_Cell_Information = served_cell_information; //
+
+        /* 2.1.2 gNB-DU System Information */
+        F1AP_GNB_DU_System_Information_t *gNB_DU_System_Information = (F1AP_GNB_DU_System_Information_t *)calloc(1, sizeof(F1AP_GNB_DU_System_Information_t));
+
+        OCTET_STRING_fromBuf(&gNB_DU_System_Information->mIB_message,  // sept. 2018
+                             "1",
+                             sizeof("1"));
+
+        OCTET_STRING_fromBuf(&gNB_DU_System_Information->sIB1_message,  // sept. 2018
+                             "1",
+                             sizeof("1"));
+        served_cells_to_add_item.gNB_DU_System_Information = gNB_DU_System_Information; //
+
+        /* ADD */
+        served_cells_to_add_item_ies->value.choice.Served_Cells_To_Add_Item = served_cells_to_add_item;
+
+        ASN_SEQUENCE_ADD(&ie->value.choice.Served_Cells_To_Add_List.list, 
+                        served_cells_to_add_item_ies);
+
+  }
+  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+
+
+  /* mandatory */
+  /* c3. Served_Cells_To_Modify */
+  ie = (F1AP_GNBDUConfigurationUpdateIEs_t *)calloc(1, sizeof(F1AP_GNBDUConfigurationUpdateIEs_t));
+  ie->id                        = F1AP_ProtocolIE_ID_id_Served_Cells_To_Modify_List;
+  ie->criticality               = F1AP_Criticality_reject;
+  ie->value.present             = F1AP_GNBDUConfigurationUpdateIEs__value_PR_Served_Cells_To_Modify_List;
+
+  for (i=0;
+       i<1;
+       i++) {
+        //
+        F1AP_Served_Cells_To_Modify_ItemIEs_t *served_cells_to_modify_item_ies;
+        served_cells_to_modify_item_ies = (F1AP_Served_Cells_To_Modify_ItemIEs_t *)calloc(1, sizeof(F1AP_Served_Cells_To_Modify_ItemIEs_t));
+        served_cells_to_modify_item_ies->id            = F1AP_ProtocolIE_ID_id_Served_Cells_To_Modify_Item;
+        served_cells_to_modify_item_ies->criticality   = F1AP_Criticality_reject;
+        served_cells_to_modify_item_ies->value.present = F1AP_Served_Cells_To_Modify_ItemIEs__value_PR_Served_Cells_To_Modify_Item;
+        
+        F1AP_Served_Cells_To_Modify_Item_t served_cells_to_modify_item;
+        memset((void *)&served_cells_to_modify_item, 0, sizeof(F1AP_Served_Cells_To_Modify_Item_t));
+
+        /* 3.1 oldNRCGI */
+        F1AP_NRCGI_t oldNRCGI;
+        MCC_MNC_TO_PLMNID(f1ap_setup_req->mcc[i], f1ap_setup_req->mnc[i], f1ap_setup_req->mnc_digit_length[i],
+                                         &oldNRCGI.pLMN_Identity);
+        NR_CELL_ID_TO_BIT_STRING(f1ap_setup_req->nr_cellid[i], &oldNRCGI.nRCellIdentity);
+        served_cells_to_modify_item.oldNRCGI = oldNRCGI;
+
+
+        /* 3.2.1 serverd cell Information */
+        F1AP_Served_Cell_Information_t served_cell_information;
+        memset((void *)&served_cell_information, 0, sizeof(F1AP_Served_Cell_Information_t));
+
+        /* - nRCGI */
+        F1AP_NRCGI_t nRCGI;
+        MCC_MNC_TO_PLMNID(f1ap_setup_req->mcc[i], f1ap_setup_req->mnc[i], f1ap_setup_req->mnc_digit_length[i],
+                                         &nRCGI.pLMN_Identity);
+        NR_CELL_ID_TO_BIT_STRING(f1ap_setup_req->nr_cellid[i], &nRCGI.nRCellIdentity);
+        served_cell_information.nRCGI = nRCGI;
+
+        /* - nRPCI */
+        served_cell_information.nRPCI = f1ap_setup_req->nr_pci[i];  // int 0..1007
+
+        /* - fiveGS_TAC */
+        OCTET_STRING_fromBuf(&served_cell_information.fiveGS_TAC,
+                             (const char *) &f1ap_setup_req->tac[i],
+                             3);
+
+        /* - Configured_EPS_TAC */
+        if(1){
+          served_cell_information.configured_EPS_TAC = (F1AP_Configured_EPS_TAC_t *)calloc(1, sizeof(F1AP_Configured_EPS_TAC_t));
+          OCTET_STRING_fromBuf(served_cell_information.configured_EPS_TAC,
+                             "2",
+                             2);
+        }
+
+        /* - broadcast PLMNs */
+        int maxnoofBPLMNS = 1;
+        for (i=0;
+            i<maxnoofBPLMNS;
+            i++) {
+            /* > PLMN BroadcastPLMNs Item */
+            F1AP_BroadcastPLMNs_Item_t *broadcastPLMNs_Item = (F1AP_BroadcastPLMNs_Item_t *)calloc(1, sizeof(F1AP_BroadcastPLMNs_Item_t));
+            //memset((void *)&broadcastPLMNs_Item, 0, sizeof(F1AP_BroadcastPLMNs_Item_t));
+            MCC_MNC_TO_PLMNID(f1ap_setup_req->mcc[i], f1ap_setup_req->mnc[i], f1ap_setup_req->mnc_digit_length[i], &broadcastPLMNs_Item->pLMN_Identity);
+            ASN_SEQUENCE_ADD(&served_cell_information.servedPLMNs.list, broadcastPLMNs_Item);
+        }
+
+        // // /* - CHOICE NR-MODE-Info */
+        F1AP_NR_Mode_Info_t nR_Mode_Info;
+
+        if (f1ap_setup_req->fdd_flag) {
+          nR_Mode_Info.present = F1AP_NR_Mode_Info_PR_fDD;
+          /* > FDD >> FDD Info */
+          F1AP_FDD_Info_t *fDD_Info = (F1AP_FDD_Info_t *)calloc(1, sizeof(F1AP_FDD_Info_t));
+          /* >>> UL NRFreqInfo */
+          fDD_Info->uL_NRFreqInfo.nRARFCN = 999L;
+
+          F1AP_FreqBandNrItem_t ul_freqBandNrItem;
+          memset((void *)&ul_freqBandNrItem, 0, sizeof(F1AP_FreqBandNrItem_t));
+          ul_freqBandNrItem.freqBandIndicatorNr = 888L;
+
+            F1AP_SupportedSULFreqBandItem_t ul_supportedSULFreqBandItem;
+            memset((void *)&ul_supportedSULFreqBandItem, 0, sizeof(F1AP_SupportedSULFreqBandItem_t));
+            ul_supportedSULFreqBandItem.freqBandIndicatorNr = 777L;
+            ASN_SEQUENCE_ADD(&ul_freqBandNrItem.supportedSULBandList.list, &ul_supportedSULFreqBandItem);
+
+          ASN_SEQUENCE_ADD(&fDD_Info->uL_NRFreqInfo.freqBandListNr.list, &ul_freqBandNrItem);
+
+          /* >>> DL NRFreqInfo */
+          fDD_Info->dL_NRFreqInfo.nRARFCN = 666L;
+
+          F1AP_FreqBandNrItem_t dl_freqBandNrItem;
+          memset((void *)&dl_freqBandNrItem, 0, sizeof(F1AP_FreqBandNrItem_t));
+          dl_freqBandNrItem.freqBandIndicatorNr = 555L;
+
+            F1AP_SupportedSULFreqBandItem_t dl_supportedSULFreqBandItem;
+            memset((void *)&dl_supportedSULFreqBandItem, 0, sizeof(F1AP_SupportedSULFreqBandItem_t));
+            dl_supportedSULFreqBandItem.freqBandIndicatorNr = 444L;
+            ASN_SEQUENCE_ADD(&dl_freqBandNrItem.supportedSULBandList.list, &dl_supportedSULFreqBandItem);
+
+          ASN_SEQUENCE_ADD(&fDD_Info->dL_NRFreqInfo.freqBandListNr.list, &dl_freqBandNrItem);
+
+          /* >>> UL Transmission Bandwidth */
+          fDD_Info->uL_Transmission_Bandwidth.nRSCS = F1AP_NRSCS_scs15;
+          fDD_Info->uL_Transmission_Bandwidth.nRNRB = F1AP_NRNRB_nrb11;
+          /* >>> DL Transmission Bandwidth */
+          fDD_Info->dL_Transmission_Bandwidth.nRSCS = F1AP_NRSCS_scs15;
+          fDD_Info->dL_Transmission_Bandwidth.nRNRB = F1AP_NRNRB_nrb11;
+          
+          nR_Mode_Info.choice.fDD = fDD_Info;
+        } else { // TDD
+          nR_Mode_Info.present = F1AP_NR_Mode_Info_PR_tDD;
+
+          /* > TDD >> TDD Info */
+          F1AP_TDD_Info_t *tDD_Info = (F1AP_TDD_Info_t *)calloc(1, sizeof(F1AP_TDD_Info_t));
+          /* >>> ARFCN */
+          tDD_Info->nRFreqInfo.nRARFCN = 999L; // Integer
+          F1AP_FreqBandNrItem_t nr_freqBandNrItem;
+          memset((void *)&nr_freqBandNrItem, 0, sizeof(F1AP_FreqBandNrItem_t));
+          nr_freqBandNrItem.freqBandIndicatorNr = 555L;
+
+            F1AP_SupportedSULFreqBandItem_t nr_supportedSULFreqBandItem;
+            memset((void *)&nr_supportedSULFreqBandItem, 0, sizeof(F1AP_SupportedSULFreqBandItem_t));
+            nr_supportedSULFreqBandItem.freqBandIndicatorNr = 444L;
+            ASN_SEQUENCE_ADD(&nr_freqBandNrItem.supportedSULBandList.list, &nr_supportedSULFreqBandItem);
+
+          ASN_SEQUENCE_ADD(&tDD_Info->nRFreqInfo.freqBandListNr.list, &nr_freqBandNrItem);
+
+          tDD_Info->transmission_Bandwidth.nRSCS= F1AP_NRSCS_scs15;
+          tDD_Info->transmission_Bandwidth.nRNRB= F1AP_NRNRB_nrb11;
+     
+          nR_Mode_Info.choice.tDD = tDD_Info;
+        } 
+        
+        served_cell_information.nR_Mode_Info = nR_Mode_Info;
+
+        /* - measurementTimingConfiguration */
+        char *measurementTimingConfiguration = "0"; // sept. 2018
+
+        OCTET_STRING_fromBuf(&served_cell_information.measurementTimingConfiguration,
+                             measurementTimingConfiguration,
+                             strlen(measurementTimingConfiguration));
+        served_cells_to_modify_item.served_Cell_Information = served_cell_information; //
+
+        /* 3.2.2 gNB-DU System Information */
+        F1AP_GNB_DU_System_Information_t *gNB_DU_System_Information = (F1AP_GNB_DU_System_Information_t *)calloc(1, sizeof(F1AP_GNB_DU_System_Information_t));
+
+        OCTET_STRING_fromBuf(&gNB_DU_System_Information->mIB_message,  // sept. 2018
+                             "1",
+                             sizeof("1"));
+
+        OCTET_STRING_fromBuf(&gNB_DU_System_Information->sIB1_message,  // sept. 2018
+                             "1",
+                             sizeof("1"));
+        served_cells_to_modify_item.gNB_DU_System_Information = gNB_DU_System_Information; //
+
+        /* ADD */
+        served_cells_to_modify_item_ies->value.choice.Served_Cells_To_Modify_Item = served_cells_to_modify_item;
+
+        ASN_SEQUENCE_ADD(&ie->value.choice.Served_Cells_To_Modify_List.list, 
+                        served_cells_to_modify_item_ies);
+
+  }
+  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+
+
+  /* mandatory */
+  /* c4. Served_Cells_To_Delete */
+  ie = (F1AP_GNBDUConfigurationUpdateIEs_t *)calloc(1, sizeof(F1AP_GNBDUConfigurationUpdateIEs_t));
+  ie->id                        = F1AP_ProtocolIE_ID_id_Served_Cells_To_Delete_List;
+  ie->criticality               = F1AP_Criticality_reject;
+  ie->value.present             = F1AP_GNBDUConfigurationUpdateIEs__value_PR_Served_Cells_To_Delete_List;
+
+  for (i=0;
+       i<1;
+       i++) {
+        //
+        F1AP_Served_Cells_To_Delete_ItemIEs_t *served_cells_to_delete_item_ies;
+        served_cells_to_delete_item_ies = (F1AP_Served_Cells_To_Delete_ItemIEs_t *)calloc(1, sizeof(F1AP_Served_Cells_To_Delete_ItemIEs_t));
+        served_cells_to_delete_item_ies->id            = F1AP_ProtocolIE_ID_id_Served_Cells_To_Delete_Item;
+        served_cells_to_delete_item_ies->criticality   = F1AP_Criticality_reject;
+        served_cells_to_delete_item_ies->value.present = F1AP_Served_Cells_To_Delete_ItemIEs__value_PR_Served_Cells_To_Delete_Item;
+        
+        F1AP_Served_Cells_To_Delete_Item_t served_cells_to_delete_item;
+        memset((void *)&served_cells_to_delete_item, 0, sizeof(F1AP_Served_Cells_To_Delete_Item_t));
+
+        /* 3.1 oldNRCGI */
+        F1AP_NRCGI_t oldNRCGI;
+        MCC_MNC_TO_PLMNID(f1ap_setup_req->mcc[i], f1ap_setup_req->mnc[i], f1ap_setup_req->mnc_digit_length[i],
+                                         &oldNRCGI.pLMN_Identity);
+        NR_CELL_ID_TO_BIT_STRING(f1ap_setup_req->nr_cellid[i], &oldNRCGI.nRCellIdentity);
+        served_cells_to_delete_item.oldNRCGI = oldNRCGI;
+
+        /* ADD */
+        served_cells_to_delete_item_ies->value.choice.Served_Cells_To_Delete_Item = served_cells_to_delete_item;
+
+        ASN_SEQUENCE_ADD(&ie->value.choice.Served_Cells_To_Delete_List.list, 
+                         served_cells_to_delete_item_ies);
+  }
+  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+
+
+  /* mandatory */
+  /* c5. Active_Cells_List */
+  ie = (F1AP_GNBDUConfigurationUpdateIEs_t *)calloc(1, sizeof(F1AP_GNBDUConfigurationUpdateIEs_t));
+  ie->id                        = F1AP_ProtocolIE_ID_id_Active_Cells_List;
+  ie->criticality               = F1AP_Criticality_reject;
+  ie->value.present             = F1AP_GNBDUConfigurationUpdateIEs__value_PR_Active_Cells_List;
+
+  for (i=0;
+       i<1;
+       i++) {
+        //
+        F1AP_Active_Cells_ItemIEs_t *active_cells_item_ies;
+        active_cells_item_ies = (F1AP_Active_Cells_ItemIEs_t *)calloc(1, sizeof(F1AP_Active_Cells_ItemIEs_t));
+        active_cells_item_ies->id            = F1AP_ProtocolIE_ID_id_Active_Cells_Item;
+        active_cells_item_ies->criticality   = F1AP_Criticality_reject;
+        active_cells_item_ies->value.present = F1AP_Active_Cells_ItemIEs__value_PR_Active_Cells_Item;
+        
+        F1AP_Active_Cells_Item_t active_cells_item;
+        memset((void *)&active_cells_item, 0, sizeof(F1AP_Active_Cells_Item_t));
+
+        /* 3.1 oldNRCGI */
+        F1AP_NRCGI_t nRCGI;
+        MCC_MNC_TO_PLMNID(f1ap_setup_req->mcc[i], f1ap_setup_req->mnc[i], f1ap_setup_req->mnc_digit_length[i],
+                                         &nRCGI.pLMN_Identity);
+        NR_CELL_ID_TO_BIT_STRING(f1ap_setup_req->nr_cellid[i], &nRCGI.nRCellIdentity);
+        active_cells_item.nRCGI = nRCGI;
+        
+        /* ADD */
+        active_cells_item_ies->value.choice.Active_Cells_Item = active_cells_item;
+
+        ASN_SEQUENCE_ADD(&ie->value.choice.Active_Cells_List.list, 
+                         active_cells_item_ies);
+  }
+  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+
+
+  if (f1ap_encode_pdu(&pdu, &buffer, &len) < 0) {
+    LOG_E(F1AP, "Failed to encode F1 setup request\n");
+    return -1;
+  }
+
+  return 0;
+}
+
+
+
+int DU_handle_gNB_DU_CONFIGURATION_FAILURE(instance_t instance,
+                                uint32_t assoc_id,
+                                uint32_t stream,
+                                F1AP_F1AP_PDU_t *pdu) {
+  AssertFatal(1==0,"Not implemented yet\n");
+}
+
+int DU_handle_gNB_DU_CONFIGURATION_UPDATE_ACKNOWLEDGE(instance_t instance,
+                                uint32_t assoc_id,
+                                uint32_t stream,
+                                F1AP_F1AP_PDU_t *pdu) {
+  AssertFatal(1==0,"Not implemented yet\n");
+}
+
+
+int DU_handle_gNB_CU_CONFIGURATION_UPDATE(instance_t instance,
+                                uint32_t assoc_id,
+                                uint32_t stream,
+                                F1AP_F1AP_PDU_t *pdu) {
+  AssertFatal(1==0,"Not implemented yet\n");
+}
+
+int DU_send_gNB_CU_CONFIGURATION_UPDATE_FAILURE(instance_t instance,
+                    F1AP_GNBCUConfigurationUpdateFailure_t *GNBCUConfigurationUpdateFailure) {
+  AssertFatal(1==0,"Not implemented yet\n");
+}
+
+int DU_send_gNB_CU_CONFIGURATION_UPDATE_ACKNOWLEDGE(instance_t instance,
+                    F1AP_GNBCUConfigurationUpdateAcknowledge_t *GNBCUConfigurationUpdateAcknowledge) {
+  AssertFatal(1==0,"Not implemented yet\n");
+}
+
+
+int DU_send_gNB_DU_RESOURCE_COORDINATION_REQUEST(instance_t instance,
+                    F1AP_GNBDUResourceCoordinationRequest_t *GNBDUResourceCoordinationRequest) {
+  AssertFatal(0, "Not implemented yet\n");
+}
+
+int DU_handle_gNB_DU_RESOURCE_COORDINATION_RESPONSE(instance_t instance,
+                                uint32_t assoc_id,
+                                uint32_t stream,
+                                F1AP_F1AP_PDU_t *pdu) {
+  AssertFatal(0, "Not implemented yet\n");
+}
diff --git a/openair2/F1AP/f1ap_du_interface_management.h b/openair2/F1AP/f1ap_du_interface_management.h
new file mode 100644
index 0000000000000000000000000000000000000000..941b86a6d4228d7e61539c5de198178de363471e
--- /dev/null
+++ b/openair2/F1AP/f1ap_du_interface_management.h
@@ -0,0 +1,118 @@
+/*
+ * 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
+ */
+
+/*! \file f1ap_du_interface_management.h
+ * \brief f1ap interface management for DU
+ * \author EURECOM/NTUST
+ * \date 2018
+ * \version 0.1
+ * \company Eurecom
+ * \email: navid.nikaein@eurecom.fr, bing-kai.hong@eurecom.fr
+ * \note
+ * \warning
+ */
+
+#ifndef F1AP_DU_INTERFACE_MANAGEMENT_H_
+#define F1AP_DU_INTERFACE_MANAGEMENT_H_
+
+/*
+ * Reset
+ */
+int DU_handle_RESET(instance_t instance,
+                    uint32_t assoc_id,
+                    uint32_t stream,
+                    F1AP_F1AP_PDU_t *pdu);
+int DU_send_RESET_ACKKNOWLEDGE(instance_t instance, F1AP_ResetAcknowledge_t *ResetAcknowledge);
+int DU_send_RESET(instance_t instance, F1AP_Reset_t *Reset);
+int DU_handle_RESET_ACKNOWLEDGE(instance_t instance,
+                                uint32_t assoc_id,
+                                uint32_t stream,
+                                F1AP_F1AP_PDU_t *pdu);
+
+/*
+ * Error Indication
+ */
+int DU_send_ERROR_INDICATION(instance_t instance, F1AP_F1AP_PDU_t *pdu_p);
+int DU_handle_ERROR_INDICATION(instance_t instance,
+                               uint32_t assoc_id,
+                               uint32_t stream,
+                               F1AP_F1AP_PDU_t *pdu);
+
+
+/*
+ * F1 Setup
+ */
+int DU_send_F1_SETUP_REQUEST(instance_t instance);
+
+int DU_handle_F1_SETUP_RESPONSE(instance_t instance,
+                                uint32_t assoc_id,
+                                uint32_t stream,
+                                F1AP_F1AP_PDU_t *pdu);
+
+int DU_handle_F1_SETUP_FAILURE(instance_t instance,
+                               uint32_t assoc_id,
+                               uint32_t stream,
+                               F1AP_F1AP_PDU_t *pdu);
+
+/*
+ * gNB-DU Configuration Update
+ */
+int DU_send_gNB_DU_CONFIGURATION_UPDATE(instance_t instance,
+                                         instance_t du_mod_idP,
+                                         f1ap_setup_req_t *f1ap_du_data);
+
+int DU_handle_gNB_DU_CONFIGURATION_FAILURE(instance_t instance,
+                                           uint32_t assoc_id,
+                                           uint32_t stream,
+                                           F1AP_F1AP_PDU_t *pdu);
+
+int DU_handle_gNB_DU_CONFIGURATION_UPDATE_ACKNOWLEDGE(instance_t instance,
+                                                      uint32_t assoc_id,
+                                                      uint32_t stream,
+                                                      F1AP_F1AP_PDU_t *pdu);
+
+/*
+ * gNB-CU Configuration Update
+ */
+int DU_handle_gNB_CU_CONFIGURATION_UPDATE(instance_t instance,
+                                          uint32_t assoc_id,
+                                          uint32_t stream,
+                                          F1AP_F1AP_PDU_t *pdu);
+
+int DU_send_gNB_CU_CONFIGURATION_UPDATE_FAILURE(instance_t instance,
+                    F1AP_GNBCUConfigurationUpdateFailure_t *GNBCUConfigurationUpdateFailure);
+
+int DU_send_gNB_CU_CONFIGURATION_UPDATE_ACKNOWLEDGE(instance_t instance,
+                    F1AP_GNBCUConfigurationUpdateAcknowledge_t *GNBCUConfigurationUpdateAcknowledge);
+
+
+/*
+ * gNB-DU Resource Coordination
+ */
+int DU_send_gNB_DU_RESOURCE_COORDINATION_REQUEST(instance_t instance,
+                    F1AP_GNBDUResourceCoordinationRequest_t *GNBDUResourceCoordinationRequest);
+
+int DU_handle_gNB_DU_RESOURCE_COORDINATION_RESPONSE(instance_t instance,
+                                                    uint32_t assoc_id,
+                                                    uint32_t stream,
+                                                    F1AP_F1AP_PDU_t *pdu);
+
+#endif /* F1AP_DU_INTERFACE_MANAGEMENT_H_ */
diff --git a/openair2/F1AP/f1ap_du_paging.c b/openair2/F1AP/f1ap_du_paging.c
new file mode 100644
index 0000000000000000000000000000000000000000..b6bbedba2f0ed9c62704a0f9fdcf52c3e182ed60
--- /dev/null
+++ b/openair2/F1AP/f1ap_du_paging.c
@@ -0,0 +1,31 @@
+/*
+ * 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
+ */
+
+/*! \file f1ap_du_interface_management.h
+ * \brief f1ap interface management for DU
+ * \author EURECOM/NTUST
+ * \date 2018
+ * \version 0.1
+ * \company Eurecom
+ * \email: navid.nikaein@eurecom.fr, bing-kai.hong@eurecom.fr
+ * \note
+ * \warning
+ */
\ No newline at end of file
diff --git a/openair2/F1AP/f1ap_du_paging.h b/openair2/F1AP/f1ap_du_paging.h
new file mode 100644
index 0000000000000000000000000000000000000000..b6bbedba2f0ed9c62704a0f9fdcf52c3e182ed60
--- /dev/null
+++ b/openair2/F1AP/f1ap_du_paging.h
@@ -0,0 +1,31 @@
+/*
+ * 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
+ */
+
+/*! \file f1ap_du_interface_management.h
+ * \brief f1ap interface management for DU
+ * \author EURECOM/NTUST
+ * \date 2018
+ * \version 0.1
+ * \company Eurecom
+ * \email: navid.nikaein@eurecom.fr, bing-kai.hong@eurecom.fr
+ * \note
+ * \warning
+ */
\ No newline at end of file
diff --git a/openair2/F1AP/f1ap_du_rrc_message_transfer.c b/openair2/F1AP/f1ap_du_rrc_message_transfer.c
new file mode 100644
index 0000000000000000000000000000000000000000..bb477f56961fb48856fe4869215ce8048250b7cc
--- /dev/null
+++ b/openair2/F1AP/f1ap_du_rrc_message_transfer.c
@@ -0,0 +1,863 @@
+/*
+ * 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
+ */
+
+/*! \file f1ap_du_rrc_message_transfer.c
+ * \brief f1ap rrc message transfer for DU
+ * \author EURECOM/NTUST
+ * \date 2018
+ * \version 0.1
+ * \company Eurecom
+ * \email: navid.nikaein@eurecom.fr, bing-kai.hong@eurecom.fr
+ * \note
+ * \warning
+ */
+
+#include "f1ap_common.h"
+#include "f1ap_encoder.h"
+#include "f1ap_decoder.h"
+#include "f1ap_itti_messaging.h"
+
+#include "f1ap_du_rrc_message_transfer.h"
+
+
+#include "LTE_DL-CCCH-Message.h"
+#include "LTE_DL-DCCH-Message.h"
+#include "LTE_UL-DCCH-Message.h"
+
+// for SRB1_logicalChannelConfig_defaultValue
+#include "rrc_extern.h"
+#include "common/ran_context.h"
+
+#include "rrc_eNB_UE_context.h"
+
+// undefine C_RNTI from
+// openair1/PHY/LTE_TRANSPORT/transport_common.h which
+// replaces in ie->value.choice.C_RNTI, causing
+// a compile error
+
+#undef C_RNTI 
+
+extern f1ap_setup_req_t *f1ap_du_data;
+extern RAN_CONTEXT_t RC;
+extern f1ap_cudu_inst_t f1ap_du_inst[MAX_eNB];
+
+
+
+/*  DL RRC Message Transfer */
+int DU_handle_DL_RRC_MESSAGE_TRANSFER(instance_t       instance,
+                                      uint32_t         assoc_id,
+                                      uint32_t         stream,
+                                      F1AP_F1AP_PDU_t *pdu) {
+  LOG_D(F1AP, "DU_handle_DL_RRC_MESSAGE_TRANSFER \n");
+  
+  F1AP_DLRRCMessageTransfer_t    *container;
+  F1AP_DLRRCMessageTransferIEs_t *ie;
+
+  uint64_t        cu_ue_f1ap_id;
+  uint64_t        du_ue_f1ap_id;
+  uint64_t        srb_id;
+  int             executeDuplication;
+  sdu_size_t      rrc_dl_sdu_len;
+  //uint64_t        subscriberProfileIDforRFP;
+  //uint64_t        rAT_FrequencySelectionPriority;
+
+  DevAssert(pdu != NULL);
+
+  if (stream != 0) {
+    LOG_E(F1AP, "[SCTP %d] Received F1 on stream != 0 (%d)\n",
+               assoc_id, stream);
+    return -1;
+  }
+
+  container = &pdu->choice.initiatingMessage->value.choice.DLRRCMessageTransfer;
+
+
+  /* GNB_CU_UE_F1AP_ID */
+  F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_DLRRCMessageTransferIEs_t, ie, container,
+                             F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID, true);
+  cu_ue_f1ap_id = ie->value.choice.GNB_CU_UE_F1AP_ID;
+  LOG_D(F1AP, "cu_ue_f1ap_id %lu \n", cu_ue_f1ap_id);
+
+
+  /* GNB_DU_UE_F1AP_ID */
+  F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_DLRRCMessageTransferIEs_t, ie, container,
+                             F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID, true);
+  du_ue_f1ap_id = ie->value.choice.GNB_DU_UE_F1AP_ID;
+  LOG_D(F1AP, "du_ue_f1ap_id %lu associated with UE RNTI %x \n",
+        du_ue_f1ap_id,
+        f1ap_get_rnti_by_du_id(&f1ap_du_inst[instance], du_ue_f1ap_id)); // this should be the one transmitted via initial ul rrc message transfer
+
+  if (f1ap_du_add_cu_ue_id(&f1ap_du_inst[instance],du_ue_f1ap_id, cu_ue_f1ap_id) < 0 ) {
+    LOG_E(F1AP, "Failed to find the F1AP UID \n");
+    //return -1;
+  }
+
+  /* optional */
+  /* oldgNB_DU_UE_F1AP_ID */
+  if (0) {
+    F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_DLRRCMessageTransferIEs_t, ie, container,
+                             F1AP_ProtocolIE_ID_id_oldgNB_DU_UE_F1AP_ID, true);
+  }
+
+  /* mandatory */
+  /* SRBID */
+  F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_DLRRCMessageTransferIEs_t, ie, container,
+                             F1AP_ProtocolIE_ID_id_SRBID, true);
+  srb_id = ie->value.choice.SRBID;
+  LOG_D(F1AP, "srb_id %lu \n", srb_id);
+
+  /* optional */
+  /* ExecuteDuplication */
+  if (0) {
+    F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_DLRRCMessageTransferIEs_t, ie, container,
+                             F1AP_ProtocolIE_ID_id_ExecuteDuplication, true);
+    executeDuplication = ie->value.choice.ExecuteDuplication;
+    LOG_D(F1AP, "ExecuteDuplication %d \n", executeDuplication);
+  }
+
+  // issue in here
+  /* mandatory */
+  /* RRC Container */
+  F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_DLRRCMessageTransferIEs_t, ie, container,
+                             F1AP_ProtocolIE_ID_id_RRCContainer, true);
+  // BK: need check
+  // create an ITTI message and copy SDU
+
+  //  message_p = itti_alloc_new_message (TASK_CU_F1, RRC_MAC_CCCH_DATA_IND);
+  //  memset (RRC_MAC_CCCH_DATA_IND (message_p).sdu, 0, CCCH_SDU_SIZE);
+  rrc_dl_sdu_len = ie->value.choice.RRCContainer.size;
+  //  memcpy(RRC_MAC_CCCH_DATA_IND (message_p).sdu, ie->value.choice.RRCContainer.buf,
+  //         ccch_sdu_len);
+
+  //LOG_I(F1AP, "%s() RRCContainer size %lu: ", __func__, ie->value.choice.RRCContainer.size);
+  //for (int i = 0;i < ie->value.choice.RRCContainer.size; i++)
+  //  printf("%02x ", ie->value.choice.RRCContainer.buf[i]);
+  //printf("\n");
+
+  /* optional */
+  /* RAT_FrequencyPriorityInformation */
+  if (0) {
+    F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_DLRRCMessageTransferIEs_t, ie, container,
+                             F1AP_ProtocolIE_ID_id_RAT_FrequencyPriorityInformation, true);
+
+    switch(ie->value.choice.RAT_FrequencyPriorityInformation.present) {
+      case F1AP_RAT_FrequencyPriorityInformation_PR_subscriberProfileIDforRFP:
+        //subscriberProfileIDforRFP = ie->value.choice.RAT_FrequencyPriorityInformation.choice.subscriberProfileIDforRFP;
+        break;
+      case F1AP_RAT_FrequencyPriorityInformation_PR_rAT_FrequencySelectionPriority:
+        //rAT_FrequencySelectionPriority = ie->value.choice.RAT_FrequencyPriorityInformation.choice.rAT_FrequencySelectionPriority;
+        break;
+      default:
+        LOG_W(F1AP, "unhandled IE RAT_FrequencyPriorityInformation.present\n");
+        break;
+    }
+  }
+
+  // decode RRC Container and act on the message type
+  AssertFatal(srb_id<3,"illegal srb_id\n");
+
+  protocol_ctxt_t ctxt;
+  ctxt.rnti      = f1ap_get_rnti_by_du_id(&f1ap_du_inst[instance], du_ue_f1ap_id);
+  ctxt.module_id = instance;
+  ctxt.instance  = instance;
+  ctxt.enb_flag  = 1;
+
+ struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(
+                                                RC.rrc[ctxt.module_id],
+                                                ctxt.rnti);
+
+  if (srb_id == 0) {
+    LTE_DL_CCCH_Message_t* dl_ccch_msg=NULL;
+    asn_dec_rval_t dec_rval;
+    dec_rval = uper_decode(NULL,
+         &asn_DEF_LTE_DL_CCCH_Message,
+         (void**)&dl_ccch_msg,
+         ie->value.choice.RRCContainer.buf,
+         rrc_dl_sdu_len,0,0);
+    AssertFatal(dec_rval.code == RC_OK, "could not decode F1AP message\n");
+    switch (dl_ccch_msg->message.choice.c1.present) {
+
+      case LTE_DL_CCCH_MessageType__c1_PR_NOTHING:
+        LOG_I(F1AP, "Received PR_NOTHING on DL-CCCH-Message\n");
+        break;
+
+      case LTE_DL_CCCH_MessageType__c1_PR_rrcConnectionReestablishment:
+        LOG_I(F1AP,
+              "Logical Channel DL-CCCH (SRB0), Received RRCConnectionReestablishment\n");
+        break;
+
+      case LTE_DL_CCCH_MessageType__c1_PR_rrcConnectionReestablishmentReject:
+        LOG_I(F1AP,
+              "Logical Channel DL-CCCH (SRB0), Received RRCConnectionReestablishmentReject\n");
+        break;
+
+      case LTE_DL_CCCH_MessageType__c1_PR_rrcConnectionReject:
+        LOG_I(F1AP,
+              "Logical Channel DL-CCCH (SRB0), Received RRCConnectionReject \n");
+        break;
+
+      case LTE_DL_CCCH_MessageType__c1_PR_rrcConnectionSetup:
+      {
+        LOG_I(F1AP,
+              "Logical Channel DL-CCCH (SRB0), Received RRCConnectionSetup DU_ID %lx/RNTI %x\n",
+              du_ue_f1ap_id,
+              f1ap_get_rnti_by_du_id(&f1ap_du_inst[instance], du_ue_f1ap_id));
+          // Get configuration
+
+        LTE_RRCConnectionSetup_t* rrcConnectionSetup = &dl_ccch_msg->message.choice.c1.choice.rrcConnectionSetup;
+        AssertFatal(rrcConnectionSetup!=NULL,"rrcConnectionSetup is null\n");
+        LTE_RadioResourceConfigDedicated_t* radioResourceConfigDedicated = &rrcConnectionSetup->criticalExtensions.choice.c1.choice.rrcConnectionSetup_r8.radioResourceConfigDedicated;
+
+        // get SRB logical channel information
+        LTE_SRB_ToAddModList_t *SRB_configList;
+        LTE_SRB_ToAddMod_t *SRB1_config;
+        LTE_LogicalChannelConfig_t *SRB1_logicalChannelConfig = NULL;
+        SRB_configList                 = radioResourceConfigDedicated->srb_ToAddModList;
+
+        AssertFatal(SRB_configList!=NULL,"SRB_configList is null\n");
+        for (int cnt = 0; cnt < (SRB_configList)->list.count; cnt++) {
+          if ((SRB_configList)->list.array[cnt]->srb_Identity == 1) {
+            SRB1_config = (SRB_configList)->list.array[cnt];
+
+            if (SRB1_config->logicalChannelConfig) {
+              if (SRB1_config->logicalChannelConfig->present ==
+                LTE_SRB_ToAddMod__logicalChannelConfig_PR_explicitValue) {
+                SRB1_logicalChannelConfig = &SRB1_config->logicalChannelConfig->choice.explicitValue;
+              } else {
+                SRB1_logicalChannelConfig = &SRB1_logicalChannelConfig_defaultValue;
+              }
+            } else {
+              SRB1_logicalChannelConfig = &SRB1_logicalChannelConfig_defaultValue;
+            }
+          }
+        } // for
+        rrc_rlc_config_asn1_req(&ctxt,
+          SRB_configList,
+          (LTE_DRB_ToAddModList_t*) NULL,
+          (LTE_DRB_ToReleaseList_t*) NULL
+#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0))
+          , (LTE_PMCH_InfoList_r9_t *) NULL,
+          0,0
+#   endif
+          );
+
+      // This should be somewhere in the f1ap_cudu_ue_inst_t
+      /*int macrlc_instance = 0; 
+
+      rnti_t rnti = f1ap_get_rnti_by_du_id(&f1ap_du_inst[0], du_ue_f1ap_id);
+      struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[macrlc_instance],rnti);
+      */  
+      eNB_RRC_UE_t *ue_p = &ue_context_p->ue_context; 
+      AssertFatal(ue_p->Srb0.Active == 1,"SRB0 is not active\n");
+
+      memcpy((void*)ue_p->Srb0.Tx_buffer.Payload,
+             (void*)ie->value.choice.RRCContainer.buf,
+             rrc_dl_sdu_len); // ie->value.choice.RRCContainer.size
+
+      ue_p->Srb0.Tx_buffer.payload_size = rrc_dl_sdu_len;
+
+      LTE_MAC_MainConfig_t    *mac_MainConfig  = NULL;
+      if (radioResourceConfigDedicated->mac_MainConfig)
+        mac_MainConfig = &radioResourceConfigDedicated->mac_MainConfig->choice.explicitValue;
+
+      rrc_mac_config_req_eNB(
+          ctxt.module_id,
+          0, //primaryCC_id,
+          0,0,0,0,0,
+#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
+          0,
+#endif
+          ctxt.rnti,
+          (LTE_BCCH_BCH_Message_t *) NULL,
+          (LTE_RadioResourceConfigCommonSIB_t *) NULL,
+#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
+          (LTE_RadioResourceConfigCommonSIB_t *) NULL,
+#endif
+          radioResourceConfigDedicated->physicalConfigDedicated,
+#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0))
+          (LTE_SCellToAddMod_r10_t *)NULL,
+          //(struct PhysicalConfigDedicatedSCell_r10 *)NULL,
+#endif
+          (LTE_MeasObjectToAddMod_t **) NULL,
+          mac_MainConfig,
+          1,
+          SRB1_logicalChannelConfig,
+          NULL, // measGapConfig,
+          (LTE_TDD_Config_t *) NULL,
+          NULL,
+          (LTE_SchedulingInfoList_t *) NULL,
+          0, NULL, NULL, (LTE_MBSFN_SubframeConfigList_t *) NULL
+#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0))
+          , 0, (LTE_MBSFN_AreaInfoList_r9_t *) NULL, (LTE_PMCH_InfoList_r9_t *) NULL
+#endif
+#if (LTE_RRC_VERSION >= MAKE_VERSION(13, 0, 0))
+          ,
+          (LTE_SystemInformationBlockType1_v1310_IEs_t *)NULL
+#endif
+          );
+          break;
+      } // case
+
+      default:
+        AssertFatal(1==0,
+        "Unknown message\n");
+        break;
+    }// switch case
+    return(0);
+  } else if (srb_id == 1) { 
+
+    LTE_DL_DCCH_Message_t* dl_dcch_msg=NULL;
+    asn_dec_rval_t dec_rval;
+    dec_rval = uper_decode(NULL,
+         &asn_DEF_LTE_DL_DCCH_Message,
+         (void**)&dl_dcch_msg,
+         &ie->value.choice.RRCContainer.buf[1], // buf[0] includes the pdcp header
+         rrc_dl_sdu_len,0,0);
+    
+    if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) 
+      LOG_E(F1AP," Failed to decode DL-DCCH (%zu bytes)\n",dec_rval.consumed);
+    else
+      LOG_D(F1AP, "Received message: present %d and c1 present %d\n",
+            dl_dcch_msg->message.present, dl_dcch_msg->message.choice.c1.present);
+
+    if (dl_dcch_msg->message.present == LTE_DL_DCCH_MessageType_PR_c1) {
+     
+      switch (dl_dcch_msg->message.choice.c1.present) {
+	
+      case LTE_DL_DCCH_MessageType__c1_PR_NOTHING:
+        LOG_I(F1AP, "Received PR_NOTHING on DL-DCCH-Message\n");
+        return 0;
+      case LTE_DL_DCCH_MessageType__c1_PR_dlInformationTransfer:
+        LOG_I(F1AP,"Received NAS DL Information Transfer\n");
+        break;	
+      case LTE_DL_DCCH_MessageType__c1_PR_csfbParametersResponseCDMA2000:
+        LOG_I(F1AP,"Received NAS sfbParametersResponseCDMA2000\n");
+        break;  
+      case LTE_DL_DCCH_MessageType__c1_PR_handoverFromEUTRAPreparationRequest:
+        LOG_I(F1AP,"Received NAS andoverFromEUTRAPreparationRequest\n");
+        break;  
+      case LTE_DL_DCCH_MessageType__c1_PR_mobilityFromEUTRACommand:
+        LOG_I(F1AP,"Received NAS mobilityFromEUTRACommand\n");
+        break;
+      case LTE_DL_DCCH_MessageType__c1_PR_rrcConnectionReconfiguration:
+	     // handle RRCConnectionReconfiguration
+        LOG_I(F1AP,
+              "Logical Channel DL-DCCH (SRB1), Received RRCConnectionReconfiguration DU_ID %lx/RNTI %x\n",
+              du_ue_f1ap_id,
+              f1ap_get_rnti_by_du_id(&f1ap_du_inst[instance], du_ue_f1ap_id));
+	
+        LTE_RRCConnectionReconfiguration_t* rrcConnectionReconfiguration = &dl_dcch_msg->message.choice.c1.choice.rrcConnectionReconfiguration;
+
+        if (rrcConnectionReconfiguration->criticalExtensions.present == LTE_RRCConnectionReconfiguration__criticalExtensions_PR_c1) {
+	        if (rrcConnectionReconfiguration->criticalExtensions.choice.c1.present ==
+	         LTE_RRCConnectionReconfiguration__criticalExtensions__c1_PR_rrcConnectionReconfiguration_r8) {
+	          LTE_RRCConnectionReconfiguration_r8_IEs_t* rrcConnectionReconfiguration_r8 =
+	          &rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8;
+	    
+            if (rrcConnectionReconfiguration_r8->mobilityControlInfo) {
+	            LOG_I(F1AP, "Mobility Control Information is present\n");
+	            AssertFatal(1==0,"Can't handle this yet in DU\n");
+	          }
+	          if (rrcConnectionReconfiguration_r8->measConfig != NULL) {
+	            LOG_I(F1AP, "Measurement Configuration is present\n");
+	          } 
+	    
+      	    if (rrcConnectionReconfiguration_r8->radioResourceConfigDedicated) {
+              LOG_I(F1AP, "Radio Resource Configuration is present\n");
+      	      uint8_t DRB2LCHAN[8];
+              long drb_id;
+              int i;
+              LTE_DRB_ToAddModList_t  *DRB_configList  = rrcConnectionReconfiguration_r8->radioResourceConfigDedicated->drb_ToAddModList;
+              LTE_SRB_ToAddModList_t  *SRB_configList  = rrcConnectionReconfiguration_r8->radioResourceConfigDedicated->srb_ToAddModList;
+              LTE_DRB_ToReleaseList_t *DRB_ReleaseList = rrcConnectionReconfiguration_r8->radioResourceConfigDedicated->drb_ToReleaseList;
+              LTE_MAC_MainConfig_t    *mac_MainConfig  = NULL;
+              if (rrcConnectionReconfiguration_r8->radioResourceConfigDedicated->mac_MainConfig)
+                mac_MainConfig = &rrcConnectionReconfiguration_r8->radioResourceConfigDedicated->mac_MainConfig->choice.explicitValue;
+              LTE_MeasGapConfig_t     *measGapConfig   = NULL;
+              struct LTE_PhysicalConfigDedicated* physicalConfigDedicated = rrcConnectionReconfiguration_r8->radioResourceConfigDedicated->physicalConfigDedicated;
+              rrc_rlc_config_asn1_req(
+                &ctxt,
+                SRB_configList, // NULL,  //LG-RK 14/05/2014 SRB_configList,
+                DRB_configList,
+                DRB_ReleaseList
+      #if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0))
+                , (LTE_PMCH_InfoList_r9_t *) NULL
+                , 0, 0
+      #endif
+                );
+
+              if (SRB_configList != NULL) {
+                for (i = 0; (i < SRB_configList->list.count) && (i < 3); i++) {
+                  if (SRB_configList->list.array[i]->srb_Identity == 1 ){
+                    ue_context_p->ue_context.Srb1.Active=1;
+                  }
+                  else if (SRB_configList->list.array[i]->srb_Identity == 2 )  {
+                    ue_context_p->ue_context.Srb2.Active=1;
+                    ue_context_p->ue_context.Srb2.Srb_info.Srb_id=2;
+                    LOG_I(F1AP, "[DU %d] SRB2 is now active\n",ctxt.module_id);
+                  } else {
+                    LOG_W(F1AP, "[DU %d] invalide SRB identity %ld\n",ctxt.module_id,
+                   SRB_configList->list.array[i]->srb_Identity);
+                  }
+                }
+              }
+
+              if (DRB_configList != NULL) {
+                for (i = 0; i < DRB_configList->list.count; i++) {  // num max DRB (11-3-8)
+                  if (DRB_configList->list.array[i]) {
+                    drb_id = (int)DRB_configList->list.array[i]->drb_Identity;
+                    LOG_I(F1AP,
+                          "[DU %d] Logical Channel UL-DCCH, Received RRCConnectionReconfiguration for UE rnti %x, reconfiguring DRB %d/LCID %d\n",
+                          ctxt.module_id,
+                          ctxt.rnti,
+                          (int)DRB_configList->list.array[i]->drb_Identity,
+                          (int)*DRB_configList->list.array[i]->logicalChannelIdentity);
+
+                  if (ue_context_p->ue_context.DRB_active[drb_id] == 0) {
+                    ue_context_p->ue_context.DRB_active[drb_id] = 1;
+
+                    if (DRB_configList->list.array[i]->logicalChannelIdentity) {
+                      DRB2LCHAN[i] = (uint8_t) * DRB_configList->list.array[i]->logicalChannelIdentity;
+                    }
+
+                    rrc_mac_config_req_eNB(
+                      ctxt.module_id,
+                      0,0,0,0,0,0,
+        #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
+                   0,
+        #endif
+                   ue_context_p->ue_context.rnti,
+                   (LTE_BCCH_BCH_Message_t *) NULL,
+                   (LTE_RadioResourceConfigCommonSIB_t *) NULL,
+        #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
+                   (LTE_RadioResourceConfigCommonSIB_t *) NULL,
+        #endif
+                   physicalConfigDedicated,
+        #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0))
+                   (LTE_SCellToAddMod_r10_t *)NULL,
+                   //(struct PhysicalConfigDedicatedSCell_r10 *)NULL,
+        #endif
+                   (LTE_MeasObjectToAddMod_t **) NULL,
+                   mac_MainConfig,
+                   DRB2LCHAN[i],
+                   DRB_configList->list.array[i]->logicalChannelConfig,
+                   measGapConfig,
+                   (LTE_TDD_Config_t *) NULL,
+                   NULL,
+                   (LTE_SchedulingInfoList_t *) NULL,
+                   0, NULL, NULL, (LTE_MBSFN_SubframeConfigList_t *) NULL
+        #if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0))
+                   , 0, (LTE_MBSFN_AreaInfoList_r9_t *) NULL, (LTE_PMCH_InfoList_r9_t *) NULL
+        #endif
+        #if (LTE_RRC_VERSION >= MAKE_VERSION(13, 0, 0))
+                   ,
+                   (LTE_SystemInformationBlockType1_v1310_IEs_t *)NULL
+        #endif
+                   );
+                  }
+
+                } else {        // remove LCHAN from MAC/PHY
+                  AssertFatal(1==0,"Can't handle this yet in DU\n");  
+                } 
+        	     }
+        	   }
+           }
+         }
+       }
+	    break;
+      case LTE_DL_DCCH_MessageType__c1_PR_rrcConnectionRelease:
+  	    // handle RRCConnectionRelease
+        LOG_I(F1AP, "Received RRCConnectionRelease\n");
+  	    break;
+      case LTE_DL_DCCH_MessageType__c1_PR_securityModeCommand:
+        LOG_I(F1AP, "Received securityModeCommand\n");
+          break; 
+      case LTE_DL_DCCH_MessageType__c1_PR_ueCapabilityEnquiry:
+        LOG_I(F1AP, "Received ueCapabilityEnquiry\n");
+          break;
+      case LTE_DL_DCCH_MessageType__c1_PR_counterCheck:
+  #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0))
+      case LTE_DL_DCCH_MessageType__c1_PR_loggedMeasurementConfiguration_r10:
+      case LTE_DL_DCCH_MessageType__c1_PR_rnReconfiguration_r10:
+  #endif
+      case LTE_DL_DCCH_MessageType__c1_PR_spare1:
+      case LTE_DL_DCCH_MessageType__c1_PR_spare2:
+      case LTE_DL_DCCH_MessageType__c1_PR_spare3:
+  #if (LTE_RRC_VERSION < MAKE_VERSION(14, 0, 0))
+      case LTE_DL_DCCH_MessageType__c1_PR_spare4:
+  #endif
+  	    break;
+      case LTE_DL_DCCH_MessageType__c1_PR_ueInformationRequest_r9:
+        LOG_I(F1AP, "Received ueInformationRequest_r9\n");
+        break;
+      case LTE_DL_DCCH_MessageType__c1_PR_rrcConnectionResume_r13:
+        LOG_I(F1AP, "Received rrcConnectionResume_r13\n");
+	   } 
+	 }	
+  }
+  else if (srb_id == 2) {
+    
+  }
+
+  LOG_I(F1AP, "Received DL RRC Transfer on srb_id %ld\n", srb_id);
+  rlc_op_status_t    rlc_status;
+  boolean_t          ret             = TRUE;
+  mem_block_t       *pdcp_pdu_p      = NULL; 
+  pdcp_pdu_p = get_free_mem_block(rrc_dl_sdu_len, __func__);
+
+  //LOG_I(F1AP, "PRRCContainer size %lu:", ie->value.choice.RRCContainer.size);
+  //for (int i = 0; i < ie->value.choice.RRCContainer.size; i++)
+  //  printf("%02x ", ie->value.choice.RRCContainer.buf[i]);
+
+  //printf (", PDCP PDU size %d:", rrc_dl_sdu_len);
+  //for (int i=0;i<rrc_dl_sdu_len;i++) printf("%2x ",pdcp_pdu_p->data[i]);
+  //printf("\n");
+
+
+  if (pdcp_pdu_p != NULL) {
+    memset(pdcp_pdu_p->data, 0, rrc_dl_sdu_len);
+    memcpy(&pdcp_pdu_p->data[0], ie->value.choice.RRCContainer.buf, rrc_dl_sdu_len);
+      rlc_status = rlc_data_req(&ctxt
+                                , 1
+                                , MBMS_FLAG_NO
+                                , srb_id
+                                , 0
+                                , 0
+                                , rrc_dl_sdu_len
+                                , pdcp_pdu_p
+#ifdef Rel14
+                                ,NULL
+                                ,NULL
+#endif
+                                );
+      switch (rlc_status) {
+        case RLC_OP_STATUS_OK:
+          //LOG_I(F1AP, "Data sending request over RLC succeeded!\n");
+          ret=TRUE;
+          break;
+
+        case RLC_OP_STATUS_BAD_PARAMETER:
+          LOG_W(F1AP, "Data sending request over RLC failed with 'Bad Parameter' reason!\n");
+          ret= FALSE;
+          break;
+
+        case RLC_OP_STATUS_INTERNAL_ERROR:
+          LOG_W(F1AP, "Data sending request over RLC failed with 'Internal Error' reason!\n");
+          ret= FALSE;
+          break;
+
+        case RLC_OP_STATUS_OUT_OF_RESSOURCES:
+          LOG_W(F1AP, "Data sending request over RLC failed with 'Out of Resources' reason!\n");
+          ret= FALSE;
+          break;
+
+        default:
+          LOG_W(F1AP, "RLC returned an unknown status code after PDCP placed the order to send some data (Status Code:%d)\n", rlc_status);
+          ret= FALSE;
+          break;
+      } // switch case
+      return ret; 
+    } // if pdcp_pdu_p
+  
+  return 0;
+  
+}
+
+int DU_send_UL_RRC_MESSAGE_TRANSFER(instance_t instance, const f1ap_ul_rrc_message_t *msg) {
+  const rnti_t rnti = msg->rnti;
+
+  F1AP_F1AP_PDU_t                pdu;
+  F1AP_ULRRCMessageTransfer_t    *out;
+  F1AP_ULRRCMessageTransferIEs_t *ie;
+
+  uint8_t *buffer = NULL;
+  uint32_t len;
+
+
+  LOG_I(F1AP, "[DU %d] %s: size %d UE RNTI %x in SRB %d\n",
+        instance, __func__, msg->rrc_container_length, rnti, msg->srb_id);
+
+  //LOG_I(F1AP, "%s() RRCContainer size %d: ", __func__, msg->rrc_container_length);
+  //for (int i = 0;i < msg->rrc_container_length; i++)
+  //  printf("%02x ", msg->rrc_container[i]);
+  //printf("\n");
+
+  /* Create */
+  /* 0. Message Type */
+  memset(&pdu, 0, sizeof(pdu));
+  pdu.present = F1AP_F1AP_PDU_PR_initiatingMessage;
+  pdu.choice.initiatingMessage = (F1AP_InitiatingMessage_t *)calloc(1, sizeof(F1AP_InitiatingMessage_t));
+  pdu.choice.initiatingMessage->procedureCode = F1AP_ProcedureCode_id_ULRRCMessageTransfer;
+  pdu.choice.initiatingMessage->criticality   = F1AP_Criticality_ignore;
+  pdu.choice.initiatingMessage->value.present = F1AP_InitiatingMessage__value_PR_ULRRCMessageTransfer;
+  out = &pdu.choice.initiatingMessage->value.choice.ULRRCMessageTransfer;
+  
+  /* mandatory */
+  /* c1. GNB_CU_UE_F1AP_ID */
+  ie = (F1AP_ULRRCMessageTransferIEs_t *)calloc(1, sizeof(F1AP_ULRRCMessageTransferIEs_t));
+  ie->id                             = F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID;
+  ie->criticality                    = F1AP_Criticality_reject;
+  ie->value.present                  = F1AP_ULRRCMessageTransferIEs__value_PR_GNB_CU_UE_F1AP_ID;
+
+  ie->value.choice.GNB_CU_UE_F1AP_ID = f1ap_get_cu_ue_f1ap_id(&f1ap_du_inst[instance], rnti);
+
+  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+
+  /* mandatory */
+  /* c2. GNB_DU_UE_F1AP_ID */
+  ie = (F1AP_ULRRCMessageTransferIEs_t *)calloc(1, sizeof(F1AP_ULRRCMessageTransferIEs_t));
+  ie->id                             = F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID;
+  ie->criticality                    = F1AP_Criticality_reject;
+  ie->value.present                  = F1AP_ULRRCMessageTransferIEs__value_PR_GNB_DU_UE_F1AP_ID;
+  ie->value.choice.GNB_DU_UE_F1AP_ID = f1ap_get_du_ue_f1ap_id(&f1ap_du_inst[instance], rnti);
+  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+
+  /* mandatory */
+  /* c3. SRBID */
+  ie = (F1AP_ULRRCMessageTransferIEs_t *)calloc(1, sizeof(F1AP_ULRRCMessageTransferIEs_t));
+  ie->id                            = F1AP_ProtocolIE_ID_id_SRBID;
+  ie->criticality                   = F1AP_Criticality_reject;
+  ie->value.present                 = F1AP_ULRRCMessageTransferIEs__value_PR_SRBID;
+  ie->value.choice.SRBID            = msg->srb_id;
+  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+
+  // issue in here
+  /* mandatory */
+  /* c4. RRCContainer */
+  ie = (F1AP_ULRRCMessageTransferIEs_t *)calloc(1, sizeof(F1AP_ULRRCMessageTransferIEs_t));
+  ie->id                            = F1AP_ProtocolIE_ID_id_RRCContainer;
+  ie->criticality                   = F1AP_Criticality_reject;
+  ie->value.present                 = F1AP_ULRRCMessageTransferIEs__value_PR_RRCContainer;
+  OCTET_STRING_fromBuf(&ie->value.choice.RRCContainer,
+                       (const char *) msg->rrc_container,
+                       msg->rrc_container_length);
+  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+
+  if (msg->srb_id == 1 || msg->srb_id == 2) {
+    struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[instance], rnti);
+
+   
+    LTE_UL_DCCH_Message_t* ul_dcch_msg=NULL;
+    asn_dec_rval_t dec_rval;
+    dec_rval = uper_decode(NULL,
+         &asn_DEF_LTE_UL_DCCH_Message,
+         (void**)&ul_dcch_msg,
+         &ie->value.choice.RRCContainer.buf[1], // buf[0] includes the pdcp header
+         msg->rrc_container_length, 0, 0);
+    
+    if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) 
+      LOG_E(F1AP, " Failed to decode UL-DCCH (%zu bytes)\n",dec_rval.consumed);
+    else
+      LOG_I(F1AP, "Received message: present %d and c1 present %d\n",
+            ul_dcch_msg->message.present, ul_dcch_msg->message.choice.c1.present);
+
+    if (ul_dcch_msg->message.present == LTE_UL_DCCH_MessageType_PR_c1) {
+
+      switch (ul_dcch_msg->message.choice.c1.present) {
+      case LTE_UL_DCCH_MessageType__c1_PR_NOTHING:   /* No components present */
+        break;
+
+      case LTE_UL_DCCH_MessageType__c1_PR_csfbParametersRequestCDMA2000:
+        break;
+
+      case LTE_UL_DCCH_MessageType__c1_PR_measurementReport:
+        break;
+
+      case LTE_UL_DCCH_MessageType__c1_PR_rrcConnectionReconfigurationComplete:
+        break;
+
+      case LTE_UL_DCCH_MessageType__c1_PR_rrcConnectionReestablishmentComplete:
+        break;
+
+      case LTE_UL_DCCH_MessageType__c1_PR_rrcConnectionSetupComplete:
+        LOG_I(F1AP, "[MSG] RRC UL rrcConnectionSetupComplete \n");
+       if(!ue_context_p){
+          LOG_E(F1AP, "Did not find the UE context associated with UE RNTOI %x, ue_context_p is NULL\n", rnti);
+        }else {
+          LOG_I(F1AP, "Processing RRCConnectionSetupComplete UE %x\n", rnti);
+          ue_context_p->ue_context.Status = RRC_CONNECTED;
+        }
+
+        break;
+      case LTE_UL_DCCH_MessageType__c1_PR_securityModeComplete:
+        LOG_I(F1AP, "[MSG] RRC securityModeComplete \n");
+        break;
+
+      case LTE_UL_DCCH_MessageType__c1_PR_securityModeFailure:
+        break;
+
+      case LTE_UL_DCCH_MessageType__c1_PR_ueCapabilityInformation:
+        LOG_I(F1AP, "[MSG] RRC ueCapabilityInformation \n");
+        break;
+
+      case LTE_UL_DCCH_MessageType__c1_PR_ulHandoverPreparationTransfer:
+        break;
+
+      case LTE_UL_DCCH_MessageType__c1_PR_ulInformationTransfer:
+        LOG_I(F1AP,"[MSG] RRC UL Information Transfer \n");
+        break;
+
+      case LTE_UL_DCCH_MessageType__c1_PR_counterCheckResponse:
+        break;
+
+#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0))
+
+      case LTE_UL_DCCH_MessageType__c1_PR_ueInformationResponse_r9:
+        break;
+      case LTE_UL_DCCH_MessageType__c1_PR_proximityIndication_r9:
+       break;
+#endif
+
+#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0))
+      case LTE_UL_DCCH_MessageType__c1_PR_rnReconfigurationComplete_r10:
+        break;
+
+      case LTE_UL_DCCH_MessageType__c1_PR_mbmsCountingResponse_r10:
+       break;
+
+      case LTE_UL_DCCH_MessageType__c1_PR_interFreqRSTDMeasurementIndication_r10:
+       break;
+#endif
+
+      }
+    }
+  }
+    /* encode */
+  if (f1ap_encode_pdu(&pdu, &buffer, &len) < 0) {
+    LOG_E(F1AP, "Failed to encode F1 setup request\n");
+    return -1;
+  }
+
+  du_f1ap_itti_send_sctp_data_req(instance, f1ap_du_data->assoc_id, buffer, len, f1ap_du_data->default_sctp_stream_id);
+  return 0;
+}
+
+
+/*  UL RRC Message Transfer */
+int DU_send_INITIAL_UL_RRC_MESSAGE_TRANSFER(module_id_t     module_idP,
+                                            int             CC_idP,
+                                            int             UE_id,
+                                            rnti_t          rntiP,
+                                            const uint8_t   *sduP,
+                                            sdu_size_t      sdu_lenP) {
+  F1AP_F1AP_PDU_t                       pdu;
+  F1AP_InitialULRRCMessageTransfer_t    *out;
+  F1AP_InitialULRRCMessageTransferIEs_t *ie;
+
+  uint8_t  *buffer;
+  uint32_t  len;
+  int f1ap_uid = f1ap_add_ue (&f1ap_du_inst[module_idP], module_idP, CC_idP,UE_id, rntiP);
+
+  if (f1ap_uid  < 0 ) {
+    LOG_E(F1AP, "Failed to add UE \n");
+    return -1;
+  }
+
+  /* Create */
+  /* 0. Message Type */
+  memset(&pdu, 0, sizeof(pdu));
+  pdu.present = F1AP_F1AP_PDU_PR_initiatingMessage;
+  pdu.choice.initiatingMessage = (F1AP_InitiatingMessage_t *)calloc(1, sizeof(F1AP_InitiatingMessage_t));
+  pdu.choice.initiatingMessage->procedureCode = F1AP_ProcedureCode_id_InitialULRRCMessageTransfer;
+  pdu.choice.initiatingMessage->criticality   = F1AP_Criticality_ignore;
+  pdu.choice.initiatingMessage->value.present = F1AP_InitiatingMessage__value_PR_InitialULRRCMessageTransfer;
+  out = &pdu.choice.initiatingMessage->value.choice.InitialULRRCMessageTransfer;
+  
+
+  /* mandatory */
+  /* c1. GNB_DU_UE_F1AP_ID */
+  ie = (F1AP_InitialULRRCMessageTransferIEs_t *)calloc(1, sizeof(F1AP_InitialULRRCMessageTransferIEs_t));
+  ie->id                             = F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID;
+  ie->criticality                    = F1AP_Criticality_reject;
+  ie->value.present                  = F1AP_InitialULRRCMessageTransferIEs__value_PR_GNB_DU_UE_F1AP_ID;
+  ie->value.choice.GNB_DU_UE_F1AP_ID = f1ap_du_inst[module_idP].f1ap_ue[f1ap_uid].du_ue_f1ap_id;
+  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+
+  /* mandatory */
+  /* c2. NRCGI */
+  ie = (F1AP_InitialULRRCMessageTransferIEs_t *)calloc(1, sizeof(F1AP_InitialULRRCMessageTransferIEs_t));
+  ie->id                             = F1AP_ProtocolIE_ID_id_NRCGI;
+  ie->criticality                    = F1AP_Criticality_reject;
+  ie->value.present                  = F1AP_InitialULRRCMessageTransferIEs__value_PR_NRCGI;
+
+  F1AP_NRCGI_t nRCGI;
+  MCC_MNC_TO_PLMNID(f1ap_du_data->mcc[0], f1ap_du_data->mnc[0], f1ap_du_data->mnc_digit_length[0],
+                                         &nRCGI.pLMN_Identity);
+  NR_CELL_ID_TO_BIT_STRING(f1ap_du_data->nr_cellid[0], &nRCGI.nRCellIdentity);
+  ie->value.choice.NRCGI = nRCGI;
+
+  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+
+  /* mandatory */
+  /* c3. C_RNTI */  // 16
+  ie = (F1AP_InitialULRRCMessageTransferIEs_t *)calloc(1, sizeof(F1AP_InitialULRRCMessageTransferIEs_t));
+  ie->id                             = F1AP_ProtocolIE_ID_id_C_RNTI;
+  ie->criticality                    = F1AP_Criticality_reject;
+  ie->value.present                  = F1AP_InitialULRRCMessageTransferIEs__value_PR_C_RNTI;
+  C_RNTI_TO_BIT_STRING(rntiP, &ie->value.choice.C_RNTI);
+  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+
+  /* mandatory */
+  /* c4. RRCContainer */
+  ie = (F1AP_InitialULRRCMessageTransferIEs_t *)calloc(1, sizeof(F1AP_InitialULRRCMessageTransferIEs_t));
+  ie->id                            = F1AP_ProtocolIE_ID_id_RRCContainer;
+  ie->criticality                   = F1AP_Criticality_reject;
+  ie->value.present                 = F1AP_InitialULRRCMessageTransferIEs__value_PR_RRCContainer;
+  OCTET_STRING_fromBuf(&ie->value.choice.RRCContainer, (const char *)sduP, sdu_lenP);
+  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+
+  /* optional */
+  /* c5. DUtoCURRCContainer */
+  if (0) {
+    ie = (F1AP_InitialULRRCMessageTransferIEs_t *)calloc(1, sizeof(F1AP_InitialULRRCMessageTransferIEs_t));
+    ie->id                             = F1AP_ProtocolIE_ID_id_DUtoCURRCContainer;
+    ie->criticality                    = F1AP_Criticality_reject;
+    ie->value.present                  = F1AP_InitialULRRCMessageTransferIEs__value_PR_DUtoCURRCContainer;
+    OCTET_STRING_fromBuf(&ie->value.choice.DUtoCURRCContainer, "dummy_val",
+                       strlen("dummy_val"));
+    ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+  }
+
+    /* encode */
+  if (f1ap_encode_pdu(&pdu, &buffer, &len) < 0) {
+    LOG_E(F1AP, "Failed to encode F1 setup request\n");
+    return -1;
+  }
+
+
+  struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_allocate_new_UE_context(RC.rrc[module_idP]);
+  ue_context_p->ue_id_rnti                    = rntiP; 
+  ue_context_p->ue_context.rnti               = rntiP;
+  ue_context_p->ue_context.random_ue_identity = rntiP;
+  ue_context_p->ue_context.Srb0.Active        = 1;
+  RB_INSERT(rrc_ue_tree_s, &RC.rrc[module_idP]->rrc_ue_head, ue_context_p);
+  du_f1ap_itti_send_sctp_data_req(module_idP, f1ap_du_data->assoc_id, buffer, len,  f1ap_du_data->default_sctp_stream_id);
+
+  return 0;
+}
+    
+
+void init_f1ap_du_ue_inst (void) {
+
+   memset(f1ap_du_inst, 0, sizeof(f1ap_du_inst));
+}
+
+
diff --git a/openair2/F1AP/f1ap_du_rrc_message_transfer.h b/openair2/F1AP/f1ap_du_rrc_message_transfer.h
new file mode 100644
index 0000000000000000000000000000000000000000..1406e48f3d3a76320a2d4ca99b7fc1b5cbdd6bd6
--- /dev/null
+++ b/openair2/F1AP/f1ap_du_rrc_message_transfer.h
@@ -0,0 +1,53 @@
+/*
+ * 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
+ */
+
+/*! \file f1ap_du_rrc_message_transfer.h
+ * \brief f1ap rrc message transfer for DU
+ * \author EURECOM/NTUST
+ * \date 2018
+ * \version 0.1
+ * \company Eurecom
+ * \email: navid.nikaein@eurecom.fr, bing-kai.hong@eurecom.fr
+ * \note
+ * \warning
+ */
+
+
+#ifndef F1AP_DU_RRC_MESSAGE_TRANSFER_H_
+#define F1AP_DU_RRC_MESSAGE_TRANSFER_H_
+
+#include "f1ap_common.h"
+
+int DU_handle_DL_RRC_MESSAGE_TRANSFER(instance_t       instance,
+                                      uint32_t         assoc_id,
+                                      uint32_t         stream,
+                                      F1AP_F1AP_PDU_t *pdu);
+
+int DU_send_UL_RRC_MESSAGE_TRANSFER(instance_t instance, const f1ap_ul_rrc_message_t *msg);
+
+int DU_send_INITIAL_UL_RRC_MESSAGE_TRANSFER(module_id_t     module_idP,
+                                            int             CC_idP,
+                                            int             UE_id,
+                                            rnti_t          rntiP,
+                                            const uint8_t   *sduP,
+                                            sdu_size_t      sdu_lenP);
+
+#endif /* F1AP_DU_RRC_MESSAGE_TRANSFER_H_ */
diff --git a/openair2/F1AP/f1ap_du_system_information.c b/openair2/F1AP/f1ap_du_system_information.c
new file mode 100644
index 0000000000000000000000000000000000000000..b6bbedba2f0ed9c62704a0f9fdcf52c3e182ed60
--- /dev/null
+++ b/openair2/F1AP/f1ap_du_system_information.c
@@ -0,0 +1,31 @@
+/*
+ * 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
+ */
+
+/*! \file f1ap_du_interface_management.h
+ * \brief f1ap interface management for DU
+ * \author EURECOM/NTUST
+ * \date 2018
+ * \version 0.1
+ * \company Eurecom
+ * \email: navid.nikaein@eurecom.fr, bing-kai.hong@eurecom.fr
+ * \note
+ * \warning
+ */
\ No newline at end of file
diff --git a/openair2/F1AP/f1ap_du_system_information.h b/openair2/F1AP/f1ap_du_system_information.h
new file mode 100644
index 0000000000000000000000000000000000000000..b6bbedba2f0ed9c62704a0f9fdcf52c3e182ed60
--- /dev/null
+++ b/openair2/F1AP/f1ap_du_system_information.h
@@ -0,0 +1,31 @@
+/*
+ * 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
+ */
+
+/*! \file f1ap_du_interface_management.h
+ * \brief f1ap interface management for DU
+ * \author EURECOM/NTUST
+ * \date 2018
+ * \version 0.1
+ * \company Eurecom
+ * \email: navid.nikaein@eurecom.fr, bing-kai.hong@eurecom.fr
+ * \note
+ * \warning
+ */
\ No newline at end of file
diff --git a/openair2/F1AP/f1ap_du_task.c b/openair2/F1AP/f1ap_du_task.c
new file mode 100644
index 0000000000000000000000000000000000000000..d287e1e5bf7d5f4cadab48b590225f106ca75aea
--- /dev/null
+++ b/openair2/F1AP/f1ap_du_task.c
@@ -0,0 +1,207 @@
+/*
+ * 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
+ */
+
+/*! \file openair2/F1AP/f1ap_du_task.c
+* \brief data structures for F1 interface modules
+* \author EURECOM/NTUST
+* \date 2018
+* \version 0.1
+* \company Eurecom
+* \email: navid.nikaein@eurecom.fr, raymond.knopp@eurecom.fr, bing-kai.hong@eurecom.fr
+* \note
+* \warning
+*/
+
+#include "f1ap_common.h"
+#include "f1ap_handlers.h"
+#include "f1ap_du_interface_management.h"
+#include "f1ap_du_ue_context_management.h"
+#include "f1ap_du_rrc_message_transfer.h"
+#include "f1ap_du_task.h"
+#include "proto_agent.h"
+
+extern RAN_CONTEXT_t RC;
+
+f1ap_setup_req_t *f1ap_du_data;
+f1ap_cudu_inst_t f1ap_du_inst[MAX_eNB];
+
+void du_task_send_sctp_association_req(instance_t instance, f1ap_setup_req_t *f1ap_setup_req) {
+  
+  DevAssert(f1ap_setup_req != NULL);
+
+  MessageDef                 *message_p                   = NULL;
+  sctp_new_association_req_t *sctp_new_association_req_p  = NULL;
+
+  message_p = itti_alloc_new_message(TASK_DU_F1, SCTP_NEW_ASSOCIATION_REQ);
+
+  sctp_new_association_req_p = &message_p->ittiMsg.sctp_new_association_req;
+  sctp_new_association_req_p->ulp_cnx_id = instance;
+  sctp_new_association_req_p->port = F1AP_PORT_NUMBER;
+  sctp_new_association_req_p->ppid = F1AP_SCTP_PPID;
+
+  sctp_new_association_req_p->in_streams  = f1ap_setup_req->sctp_in_streams;
+  sctp_new_association_req_p->out_streams = f1ap_setup_req->sctp_out_streams;
+
+  // remote
+  memcpy(&sctp_new_association_req_p->remote_address,
+         &f1ap_setup_req->CU_f1_ip_address,
+         sizeof(f1ap_setup_req->CU_f1_ip_address));
+
+  // local
+  memcpy(&sctp_new_association_req_p->local_address,
+         &f1ap_setup_req->DU_f1_ip_address,
+         sizeof(f1ap_setup_req->DU_f1_ip_address));
+
+  // store data
+  f1ap_du_data = (f1ap_setup_req_t *)calloc(1, sizeof(f1ap_setup_req_t));
+  *f1ap_du_data = *f1ap_setup_req;
+  //printf("sib itti message %s\n", f1ap_setup_req_t->sib1[0]);
+
+  //printf("nr_cellid : %llx (%lld)",f1ap_setup_req->nr_cellid[0],f1ap_setup_req->nr_cellid[0]);
+  
+  //du_f1ap_register_to_sctp
+  itti_send_msg_to_task(TASK_SCTP, instance, message_p);
+}
+
+void du_task_handle_sctp_association_resp(instance_t instance, sctp_new_association_resp_t *sctp_new_association_resp) {
+
+  DevAssert(sctp_new_association_resp != NULL);
+
+  if (sctp_new_association_resp->sctp_state != SCTP_STATE_ESTABLISHED) {
+    LOG_W(F1AP, "Received unsuccessful result for SCTP association (%u), instance %d, cnx_id %u\n",
+              sctp_new_association_resp->sctp_state,
+              instance,
+              sctp_new_association_resp->ulp_cnx_id);
+
+      //f1ap_handle_setup_message(instance, sctp_new_association_resp->sctp_state == SCTP_STATE_SHUTDOWN);
+    return; // exit -1 for debugging 
+    }
+
+    // save the assoc id 
+  f1ap_du_data->assoc_id         = sctp_new_association_resp->assoc_id;
+  f1ap_du_data->sctp_in_streams  = sctp_new_association_resp->in_streams;
+  f1ap_du_data->sctp_out_streams = sctp_new_association_resp->out_streams;
+  f1ap_du_data->default_sctp_stream_id = 0;
+
+  /* setup parameters for F1U and start the server */
+  const cudu_params_t params = {
+    .local_ipv4_address  = RC.mac[instance]->eth_params_n.my_addr,
+    .local_port          = RC.mac[instance]->eth_params_n.my_portd,
+    .remote_ipv4_address = RC.mac[instance]->eth_params_n.remote_addr,
+    .remote_port         = RC.mac[instance]->eth_params_n.remote_portd
+  };
+  AssertFatal(proto_agent_start(instance, &params) == 0,
+              "could not start PROTO_AGENT for F1U on instance %d!\n", instance);
+
+  DU_send_F1_SETUP_REQUEST(instance);
+}
+
+void du_task_handle_sctp_data_ind(instance_t instance, sctp_data_ind_t *sctp_data_ind)
+{
+  int result;
+
+  DevAssert(sctp_data_ind != NULL);
+
+  f1ap_handle_message(instance, sctp_data_ind->assoc_id, sctp_data_ind->stream,
+                          sctp_data_ind->buffer, sctp_data_ind->buffer_length);
+
+  result = itti_free(TASK_UNKNOWN, sctp_data_ind->buffer);
+  AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
+}
+
+
+void *F1AP_DU_task(void *arg) {
+
+  //sctp_cu_init();
+  MessageDef *received_msg = NULL;
+  int         result;
+
+  LOG_I(F1AP, "Starting F1AP at DU\n");
+
+  //f1ap_eNB_prepare_internal_data();
+
+  itti_mark_task_ready(TASK_DU_F1);
+
+  // SCTP
+  while (1) {
+    itti_receive_msg(TASK_DU_F1, &received_msg);
+
+    switch (ITTI_MSG_ID(received_msg)) {
+
+      // case TERMINATE_MESSAGE:
+      //   //F1AP_WARN(" *** Exiting F1AP DU thread\n");
+      //   itti_exit_task();
+      //   break;
+
+      case F1AP_SETUP_REQ: // this is not a true F1 message, but rather an ITTI message sent by enb_app
+        // 1. save the itti msg so that you can use it to sen f1ap_setup_req, fill the f1ap_setup_req message, 
+        // 2. store the message in f1ap context, that is also stored in RC
+        // 2. send a sctp_association req
+        LOG_I(F1AP, "DU Task Received F1AP_SETUP_REQ\n");
+        du_task_send_sctp_association_req(ITTI_MESSAGE_GET_INSTANCE(received_msg),
+                                              &F1AP_SETUP_REQ(received_msg));
+        break;
+
+      case SCTP_NEW_ASSOCIATION_RESP:
+        // 1. store the respon
+        // 2. send the f1setup_req
+        LOG_I(F1AP, "DU Task Received SCTP_NEW_ASSOCIATION_RESP\n");
+        du_task_handle_sctp_association_resp(ITTI_MESSAGE_GET_INSTANCE(received_msg),
+                                      &received_msg->ittiMsg.sctp_new_association_resp);
+        break;
+
+      case SCTP_DATA_IND: 
+        // ex: any F1 incoming message for DU ends here
+        LOG_I(F1AP, "DU Task Received SCTP_DATA_IND\n");
+        du_task_handle_sctp_data_ind(ITTI_MESSAGE_GET_INSTANCE(received_msg),
+                                    &received_msg->ittiMsg.sctp_data_ind);
+        break;
+
+     case F1AP_UL_RRC_MESSAGE: // from rrc
+        LOG_I(F1AP, "DU Task Received F1AP_UL_RRC_MESSAGE\n");
+        DU_send_UL_RRC_MESSAGE_TRANSFER(ITTI_MESSAGE_GET_INSTANCE(received_msg),
+                                        &F1AP_UL_RRC_MESSAGE(received_msg));
+        break;
+
+      case F1AP_UE_CONTEXT_RELEASE_REQ: // from MAC
+        LOG_I(F1AP, "DU Task Received F1AP_UE_CONTEXT_RELEASE_REQ\n");
+        DU_send_UE_CONTEXT_RELEASE_REQUEST(ITTI_MESSAGE_GET_INSTANCE(received_msg),
+                                           &F1AP_UE_CONTEXT_RELEASE_REQ(received_msg));
+        break;
+
+      case TERMINATE_MESSAGE:
+        LOG_W(F1AP, " *** Exiting F1AP thread\n");
+        itti_exit_task();
+        break;
+
+      default:
+        LOG_E(F1AP, "DU Received unhandled message: %d:%s\n",
+              ITTI_MSG_ID(received_msg), ITTI_MSG_NAME(received_msg));
+        break;
+    } // switch
+    result = itti_free (ITTI_MSG_ORIGIN_ID(received_msg), received_msg);
+    AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
+
+    received_msg = NULL;
+  } // while
+
+  return NULL;
+}
diff --git a/openair2/F1AP/f1ap_du_task.h b/openair2/F1AP/f1ap_du_task.h
new file mode 100644
index 0000000000000000000000000000000000000000..2d5195baedea362bef3a1a68150860f5d2a27560
--- /dev/null
+++ b/openair2/F1AP/f1ap_du_task.h
@@ -0,0 +1,30 @@
+/*
+ * 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
+ */
+
+#ifndef F1AP_DU_TASK_H_
+#define F1AP_DU_TASK_H_
+
+void du_task_send_sctp_association_req(instance_t instance, f1ap_setup_req_t *f1ap_setup_req);
+void du_task_handle_sctp_association_resp(instance_t instance, sctp_new_association_resp_t *sctp_new_association_resp);
+void du_task_handle_sctp_data_ind(instance_t instance, sctp_data_ind_t *sctp_data_ind);
+void *F1AP_DU_task(void *arg);
+
+#endif /* F1AP_DU_TASK_H_ */
diff --git a/openair2/F1AP/f1ap_du_ue_context_management.c b/openair2/F1AP/f1ap_du_ue_context_management.c
new file mode 100644
index 0000000000000000000000000000000000000000..1a80132ea83d35fa47770c4e111cd1863b94d00f
--- /dev/null
+++ b/openair2/F1AP/f1ap_du_ue_context_management.c
@@ -0,0 +1,1292 @@
+/*
+ * 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
+ */
+
+/*! \file f1ap_du_ue_context_management.c
+ * \brief F1AP UE Context Management, DU side
+ * \author EURECOM/NTUST
+ * \date 2018
+ * \version 0.1
+ * \company Eurecom
+ * \email: navid.nikaein@eurecom.fr, bing-kai.hong@eurecom.fr
+ * \note
+ * \warning
+ */
+
+#include "f1ap_common.h"
+#include "f1ap_encoder.h"
+#include "f1ap_decoder.h"
+#include "f1ap_itti_messaging.h"
+#include "f1ap_du_ue_context_management.h"
+
+#include "rrc_extern.h"
+#include "rrc_eNB_UE_context.h"
+
+// undefine C_RNTI from
+// openair1/PHY/LTE_TRANSPORT/transport_common.h which
+// replaces in ie->value.choice.C_RNTI, causing
+// a compile error
+
+#undef C_RNTI 
+
+extern f1ap_setup_req_t *f1ap_du_data;
+extern f1ap_cudu_inst_t f1ap_du_inst[MAX_eNB];
+extern RAN_CONTEXT_t RC;
+
+int DU_handle_UE_CONTEXT_SETUP_REQUEST(instance_t       instance,
+                                       uint32_t         assoc_id,
+                                       uint32_t         stream,
+                                       F1AP_F1AP_PDU_t *pdu)
+{
+  MessageDef                      *msg_p; // message to RRC
+  F1AP_UEContextSetupRequest_t    *container;
+  F1AP_UEContextSetupRequestIEs_t *ie;
+  int i;
+
+  DevAssert(pdu);
+
+  msg_p = itti_alloc_new_message(TASK_DU_F1, F1AP_UE_CONTEXT_SETUP_REQ);
+	f1ap_ue_context_setup_req_t *f1ap_ue_context_setup_req;
+	f1ap_ue_context_setup_req = &F1AP_UE_CONTEXT_SETUP_REQ(msg_p);
+
+  container = &pdu->choice.initiatingMessage->value.choice.UEContextSetupRequest;
+
+  /* GNB_CU_UE_F1AP_ID */
+  F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextSetupRequestIEs_t, ie, container,
+                             F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID, true);
+  f1ap_ue_context_setup_req->gNB_CU_ue_id = ie->value.choice.GNB_CU_UE_F1AP_ID;
+
+  /* optional */
+  /* GNB_DU_UE_F1AP_ID */
+  F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextSetupRequestIEs_t, ie, container,
+                             F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID, false);
+  if (ie) {
+    f1ap_ue_context_setup_req->gNB_DU_ue_id = malloc(sizeof(uint32_t));
+    if (f1ap_ue_context_setup_req->gNB_DU_ue_id)
+      *f1ap_ue_context_setup_req->gNB_DU_ue_id = ie->value.choice.GNB_DU_UE_F1AP_ID;
+  } else {
+    f1ap_ue_context_setup_req->gNB_DU_ue_id = NULL;
+  }
+
+  /* SpCell_ID */
+  F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextSetupRequestIEs_t, ie, container,
+                             F1AP_ProtocolIE_ID_id_SpCell_ID, true);
+  PLMNID_TO_MCC_MNC(&ie->value.choice.NRCGI.pLMN_Identity,
+										f1ap_ue_context_setup_req->mcc,
+										f1ap_ue_context_setup_req->mnc,
+                    f1ap_ue_context_setup_req->mnc_digit_length);
+  BIT_STRING_TO_NR_CELL_IDENTITY(&ie->value.choice.NRCGI.nRCellIdentity, f1ap_ue_context_setup_req->nr_cellid);
+
+
+  /* ServCellIndex */
+  F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextSetupRequestIEs_t, ie, container,
+                             F1AP_ProtocolIE_ID_id_ServCellndex, true);
+  f1ap_ue_context_setup_req->servCellIndex = ie->value.choice.ServCellIndex;
+
+  /* optional */
+  /* CellULConfigured */
+  F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextSetupRequestIEs_t, ie, container,
+                             F1AP_ProtocolIE_ID_id_SpCellULConfigured, false);  // SpCellULConfigured
+  if (ie) {
+    /* correct here */
+    f1ap_ue_context_setup_req->cellULConfigured = malloc(sizeof(uint32_t));
+    if (f1ap_ue_context_setup_req->cellULConfigured)
+      *f1ap_ue_context_setup_req->cellULConfigured = ie->value.choice.CellULConfigured;
+  } else {
+    f1ap_ue_context_setup_req->cellULConfigured = NULL;
+  }
+
+  /* CUtoDURRCInformation */
+
+
+  /* Candidate_SpCell_List */
+
+
+  /* optional */
+  /* DRXCycle */
+
+  /* optional */
+  /* ResourceCoordinationTransferContainer */
+
+
+  /* SCell_ToBeSetup_List */
+
+  /* SRBs_ToBeSetup_List */
+
+  /* DRBs_ToBeSetup_List */
+
+  /* Decode DRBs_ToBeSetup_List */
+  F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextSetupRequestIEs_t, ie, container,
+                             F1AP_ProtocolIE_ID_id_DRBs_ToBeSetup_List, true);
+  f1ap_ue_context_setup_req->drbs_to_be_setup_length = ie->value.choice.DRBs_ToBeSetup_List.list.count;
+  f1ap_ue_context_setup_req->drbs_to_be_setup = calloc(f1ap_ue_context_setup_req->drbs_to_be_setup_length,
+                                                       sizeof(f1ap_drb_to_be_setup_t));
+  AssertFatal(f1ap_ue_context_setup_req->drbs_to_be_setup,
+              "could not allocate memory for f1ap_ue_context_setup_req->drbs_to_be_setup\n");
+  for (i = 0; i < f1ap_ue_context_setup_req->drbs_to_be_setup_length; ++i) {
+    f1ap_drb_to_be_setup_t *drb_p = &f1ap_ue_context_setup_req->drbs_to_be_setup[i];
+    F1AP_DRBs_ToBeSetup_Item_t *drbs_tobesetup_item_p;
+    drbs_tobesetup_item_p = &((F1AP_DRBs_ToBeSetup_ItemIEs_t *)ie->value.choice.DRBs_ToBeSetup_List.list.array[i])->value.choice.DRBs_ToBeSetup_Item;
+
+    drb_p->drb_id = drbs_tobesetup_item_p->dRBID;
+
+    /* TODO in the following, assume only one UP UL TNL is present.
+     * this matches/assumes OAI CU implementation, can be up to 2! */
+    drb_p->up_ul_tnl_length = 1;
+    AssertFatal(drbs_tobesetup_item_p->uLUPTNLInformation_ToBeSetup_List.list.count > 0,
+                "no UL UP TNL Information in DRBs to be Setup list\n");
+    F1AP_ULUPTNLInformation_ToBeSetup_Item_t *ul_up_tnl_info_p = (F1AP_ULUPTNLInformation_ToBeSetup_Item_t *)drbs_tobesetup_item_p->uLUPTNLInformation_ToBeSetup_List.list.array[0];
+    F1AP_GTPTunnel_t *ul_up_tnl0 = ul_up_tnl_info_p->uLUPTNLInformation.choice.gTPTunnel;
+    BIT_STRING_TO_TRANSPORT_LAYER_ADDRESS_IPv4(&ul_up_tnl0->transportLayerAddress, drb_p->up_ul_tnl[0].tl_address);
+    OCTET_STRING_TO_INT32(&ul_up_tnl0->gTP_TEID, drb_p->up_ul_tnl[0].gtp_teid);
+
+    switch (drbs_tobesetup_item_p->rLCMode) {
+    case F1AP_RLCMode_rlc_am:
+      drb_p->rlc_mode = RLC_MODE_AM;
+      break;
+    default:
+      drb_p->rlc_mode = RLC_MODE_TM;
+      break;
+    }
+  }
+
+  AssertFatal(0, "check configuration, send to appropriate handler\n");
+
+  return 0;
+}
+
+//void DU_send_UE_CONTEXT_SETUP_RESPONSE(F1AP_UEContextSetupResponse_t *UEContextSetupResponse) {
+int DU_send_UE_CONTEXT_SETUP_RESPONSE(instance_t instance) {
+  F1AP_F1AP_PDU_t                  pdu;
+  F1AP_UEContextSetupResponse_t    *out;
+  F1AP_UEContextSetupResponseIEs_t *ie;
+
+  uint8_t  *buffer;
+  uint32_t  len;
+  int       i = 0, j = 0;
+
+  rnti_t    rntiP;  // note: need get value
+
+  /* Create */
+  /* 0. Message Type */
+  memset(&pdu, 0, sizeof(pdu));
+  pdu.present = F1AP_F1AP_PDU_PR_successfulOutcome;
+  pdu.choice.successfulOutcome = (F1AP_SuccessfulOutcome_t *)calloc(1, sizeof(F1AP_SuccessfulOutcome_t));
+  pdu.choice.successfulOutcome->procedureCode = F1AP_ProcedureCode_id_UEContextSetup;
+  pdu.choice.successfulOutcome->criticality   = F1AP_Criticality_reject;
+  pdu.choice.successfulOutcome->value.present = F1AP_SuccessfulOutcome__value_PR_UEContextSetupResponse;
+  out = &pdu.choice.successfulOutcome->value.choice.UEContextSetupResponse;
+
+  /* mandatory */
+  /* c1. GNB_CU_UE_F1AP_ID */
+  ie = (F1AP_UEContextSetupResponseIEs_t *)calloc(1, sizeof(F1AP_UEContextSetupResponseIEs_t));
+  ie->id                             = F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID;
+  ie->criticality                    = F1AP_Criticality_reject;
+  ie->value.present                  = F1AP_UEContextSetupResponseIEs__value_PR_GNB_CU_UE_F1AP_ID;
+  ie->value.choice.GNB_CU_UE_F1AP_ID = 126L;
+  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+
+  /* mandatory */
+  /* c2. GNB_DU_UE_F1AP_ID */
+  ie = (F1AP_UEContextSetupResponseIEs_t *)calloc(1, sizeof(F1AP_UEContextSetupResponseIEs_t));
+  ie->id                             = F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID;
+  ie->criticality                    = F1AP_Criticality_reject;
+  ie->value.present                  = F1AP_UEContextSetupResponseIEs__value_PR_GNB_DU_UE_F1AP_ID;
+  ie->value.choice.GNB_DU_UE_F1AP_ID = 651L;
+  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+
+  /* mandatory */
+  /* c3. DUtoCURRCInformation */
+  ie = (F1AP_UEContextSetupResponseIEs_t *)calloc(1, sizeof(F1AP_UEContextSetupResponseIEs_t));
+  ie->id                             = F1AP_ProtocolIE_ID_id_DUtoCURRCInformation;
+  ie->criticality                    = F1AP_Criticality_reject;
+  ie->value.present                  = F1AP_UEContextSetupResponseIEs__value_PR_DUtoCURRCInformation;
+  {
+    /* cellGroupConfig */
+    OCTET_STRING_fromBuf(&ie->value.choice.DUtoCURRCInformation.cellGroupConfig, "asdsa",
+                         strlen("asdsa"));
+    /* OPTIONAL */
+    /* measGapConfig */
+    if (0) {
+      ie->value.choice.DUtoCURRCInformation.measGapConfig = (F1AP_MeasGapConfig_t *)calloc(1, sizeof(F1AP_MeasGapConfig_t));
+      OCTET_STRING_fromBuf( ie->value.choice.DUtoCURRCInformation.measGapConfig, "asdsa",
+                           strlen("asdsa"));
+    }
+
+    /* OPTIONAL */
+    /* requestedP_MaxFR1 */
+    if (0) {
+      ie->value.choice.DUtoCURRCInformation.requestedP_MaxFR1 = (OCTET_STRING_t *)calloc(1, sizeof(OCTET_STRING_t));
+      OCTET_STRING_fromBuf( ie->value.choice.DUtoCURRCInformation.requestedP_MaxFR1, "asdsa",
+                           strlen("asdsa"));
+    }
+
+    ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+  }
+
+  /* optional */
+  /* c4. C_RNTI */
+  if (0) {
+    ie = (F1AP_UEContextSetupResponseIEs_t *)calloc(1, sizeof(F1AP_UEContextSetupResponseIEs_t));
+    ie->id                             = F1AP_ProtocolIE_ID_id_C_RNTI;
+    ie->criticality                    = F1AP_Criticality_ignore;
+    ie->value.present                  = F1AP_UEContextSetupResponseIEs__value_PR_C_RNTI;
+    C_RNTI_TO_BIT_STRING(rntiP, &ie->value.choice.C_RNTI);
+    ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+  }
+
+  /* optional */
+  /* c5. ResourceCoordinationTransferContainer */
+  if (0) {
+    ie = (F1AP_UEContextSetupResponseIEs_t *)calloc(1, sizeof(F1AP_UEContextSetupResponseIEs_t));
+    ie->id                             = F1AP_ProtocolIE_ID_id_ResourceCoordinationTransferContainer;
+    ie->criticality                    = F1AP_Criticality_ignore;
+    ie->value.present                  = F1AP_UEContextSetupResponseIEs__value_PR_ResourceCoordinationTransferContainer;
+    OCTET_STRING_fromBuf(&ie->value.choice.ResourceCoordinationTransferContainer, "asdsa",
+                         strlen("asdsa"));
+    ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+  }
+
+  /* optional */
+  /* c6. FullConfiguration */
+  if (0) {
+    ie = (F1AP_UEContextSetupResponseIEs_t *)calloc(1, sizeof(F1AP_UEContextSetupResponseIEs_t));
+    ie->id                             = F1AP_ProtocolIE_ID_id_FullConfiguration;
+    ie->criticality                    = F1AP_Criticality_ignore;
+    ie->value.present                  = F1AP_UEContextSetupResponseIEs__value_PR_FullConfiguration;
+    ie->value.choice.FullConfiguration = F1AP_FullConfiguration_full;   //enum
+    ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+  }
+
+  /* mandatory */
+  /* c7. DRBs_Setup_List */
+  ie = (F1AP_UEContextSetupResponseIEs_t *)calloc(1, sizeof(F1AP_UEContextSetupResponseIEs_t));
+  ie->id                             = F1AP_ProtocolIE_ID_id_DRBs_Setup_List;
+  ie->criticality                    = F1AP_Criticality_ignore;
+  ie->value.present                  = F1AP_UEContextSetupResponseIEs__value_PR_DRBs_Setup_List;
+
+  for (i=0;
+       i<1;
+       i++) {
+     //
+     F1AP_DRBs_Setup_ItemIEs_t *drbs_setup_item_ies;
+     drbs_setup_item_ies = (F1AP_DRBs_Setup_ItemIEs_t *)calloc(1, sizeof(F1AP_DRBs_Setup_ItemIEs_t));
+     drbs_setup_item_ies->id            = F1AP_ProtocolIE_ID_id_DRBs_Setup_Item;
+     drbs_setup_item_ies->criticality   = F1AP_Criticality_ignore;
+     drbs_setup_item_ies->value.present = F1AP_SRBs_FailedToBeSetup_ItemIEs__value_PR_SRBs_FailedToBeSetup_Item;
+
+     /* 7.1 DRBs_Setup_Item */
+     F1AP_DRBs_Setup_Item_t drbs_setup_item;
+     memset((void *)&drbs_setup_item, 0, sizeof(F1AP_DRBs_Setup_Item_t));
+
+     /* dRBID */
+     drbs_setup_item.dRBID = 12;
+     
+     /* OPTIONAL */
+     /* lCID */
+     //drbs_setup_item.lCID = (F1AP_LCID_t *)calloc(1, sizeof(F1AP_LCID_t));
+     //drbs_setup_item.lCID = 1L;
+
+     for (j=0;
+       j<1;
+       j++) {
+
+       F1AP_DLUPTNLInformation_ToBeSetup_Item_t *dLUPTNLInformation_ToBeSetup_Item;
+       dLUPTNLInformation_ToBeSetup_Item = (F1AP_DLUPTNLInformation_ToBeSetup_Item_t *)calloc(1, sizeof(F1AP_DLUPTNLInformation_ToBeSetup_Item_t));
+       dLUPTNLInformation_ToBeSetup_Item->dLUPTNLInformation.present = F1AP_UPTransportLayerInformation_PR_gTPTunnel;
+       
+       /* gTPTunnel */
+       F1AP_GTPTunnel_t *gTPTunnel = (F1AP_GTPTunnel_t *)calloc(1, sizeof(F1AP_GTPTunnel_t));
+       {
+         /* transportLayerAddress */
+         TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(1234, &gTPTunnel->transportLayerAddress);
+
+         /* gTP_TEID */
+         OCTET_STRING_fromBuf(&gTPTunnel->gTP_TEID, "1204",
+                               strlen("1204"));
+         dLUPTNLInformation_ToBeSetup_Item->dLUPTNLInformation.choice.gTPTunnel = gTPTunnel;
+       }
+       /* ADD */
+       ASN_SEQUENCE_ADD(&drbs_setup_item.dLUPTNLInformation_ToBeSetup_List.list,
+                        dLUPTNLInformation_ToBeSetup_Item);
+     } // for j
+
+     /* ADD */
+     drbs_setup_item_ies->value.choice.DRBs_Setup_Item = drbs_setup_item;
+     ASN_SEQUENCE_ADD(&ie->value.choice.DRBs_Setup_List.list,
+                     drbs_setup_item_ies);
+  } // for i
+  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+
+  /* mandatory */
+  /* c8. SRBs_FailedToBeSetup_List */
+  ie = (F1AP_UEContextSetupResponseIEs_t *)calloc(1, sizeof(F1AP_UEContextSetupResponseIEs_t));
+  ie->id                             = F1AP_ProtocolIE_ID_id_SRBs_FailedToBeSetup_List;
+  ie->criticality                    = F1AP_Criticality_ignore;
+  ie->value.present                  = F1AP_UEContextSetupResponseIEs__value_PR_SRBs_FailedToBeSetup_List;
+
+  for (i=0;
+       i<1;
+       i++) {
+      //
+      F1AP_SRBs_FailedToBeSetup_ItemIEs_t *srbs_failedToBeSetup_item_ies;
+      srbs_failedToBeSetup_item_ies = (F1AP_SRBs_FailedToBeSetup_ItemIEs_t *)calloc(1, sizeof(F1AP_SRBs_FailedToBeSetup_ItemIEs_t));
+      srbs_failedToBeSetup_item_ies->id            = F1AP_ProtocolIE_ID_id_SRBs_FailedToBeSetup_Item;
+      srbs_failedToBeSetup_item_ies->criticality   = F1AP_Criticality_ignore;
+      srbs_failedToBeSetup_item_ies->value.present = F1AP_SRBs_FailedToBeSetup_ItemIEs__value_PR_SRBs_FailedToBeSetup_Item;
+
+      /* 8.1 SRBs_Setup_Item */
+      F1AP_SRBs_FailedToBeSetup_Item_t srbs_failedToBeSetup_item;
+      memset((void *)&srbs_failedToBeSetup_item, 0, sizeof(F1AP_SRBs_FailedToBeSetup_Item_t));
+
+      /* sRBID */
+      srbs_failedToBeSetup_item.sRBID = 13L;
+
+      /* cause */
+      srbs_failedToBeSetup_item.cause = (F1AP_Cause_t *)calloc(1, sizeof(F1AP_Cause_t));
+
+      // dummy value
+      srbs_failedToBeSetup_item.cause->present = F1AP_Cause_PR_radioNetwork;
+
+      switch(srbs_failedToBeSetup_item.cause->present)
+      {
+        case F1AP_Cause_PR_radioNetwork:
+          srbs_failedToBeSetup_item.cause->choice.radioNetwork = F1AP_CauseRadioNetwork_unspecified;
+          break;
+        case F1AP_Cause_PR_transport:
+          srbs_failedToBeSetup_item.cause->choice.transport = F1AP_CauseTransport_unspecified;
+          break;
+        case F1AP_Cause_PR_protocol:
+          srbs_failedToBeSetup_item.cause->choice.protocol = F1AP_CauseProtocol_unspecified;
+          break;
+        case F1AP_Cause_PR_misc:
+          srbs_failedToBeSetup_item.cause->choice.misc = F1AP_CauseMisc_unspecified;
+          break;
+        case F1AP_Cause_PR_NOTHING:
+        default:
+          break;
+      } // switch
+
+      /* ADD */
+      srbs_failedToBeSetup_item_ies->value.choice.SRBs_FailedToBeSetup_Item = srbs_failedToBeSetup_item;
+      ASN_SEQUENCE_ADD(&ie->value.choice.SRBs_FailedToBeSetup_List.list,
+                       srbs_failedToBeSetup_item_ies);
+  } // for i
+  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+
+  /*  */
+  /* c9. DRBs_FailedToBeSetup_List */
+  ie = (F1AP_UEContextSetupResponseIEs_t *)calloc(1, sizeof(F1AP_UEContextSetupResponseIEs_t));
+  ie->id                             = F1AP_ProtocolIE_ID_id_DRBs_FailedToBeSetup_List;
+  ie->criticality                    = F1AP_Criticality_ignore;
+  ie->value.present                  = F1AP_UEContextSetupResponseIEs__value_PR_DRBs_FailedToBeSetup_List;
+
+  for (i=0;
+       i<1;
+       i++) {
+      //
+      F1AP_DRBs_FailedToBeSetup_ItemIEs_t *drbs_failedToBeSetup_item_ies;
+      drbs_failedToBeSetup_item_ies = (F1AP_DRBs_FailedToBeSetup_ItemIEs_t *)calloc(1, sizeof(F1AP_DRBs_FailedToBeSetup_ItemIEs_t));
+      drbs_failedToBeSetup_item_ies->id            = F1AP_ProtocolIE_ID_id_DRBs_FailedToBeSetup_Item;
+      drbs_failedToBeSetup_item_ies->criticality   = F1AP_Criticality_ignore;
+      drbs_failedToBeSetup_item_ies->value.present = F1AP_DRBs_FailedToBeSetup_ItemIEs__value_PR_DRBs_FailedToBeSetup_Item;
+
+      /* 9.1 DRBs_Setup_Item */
+      F1AP_DRBs_FailedToBeSetup_Item_t drbs_failedToBeSetup_item;
+      memset((void *)&drbs_failedToBeSetup_item, 0, sizeof(F1AP_DRBs_FailedToBeSetup_Item_t));
+
+      /* dRBID */
+      drbs_failedToBeSetup_item.dRBID = 14;
+
+      /* cause */
+      drbs_failedToBeSetup_item.cause = (F1AP_Cause_t *)calloc(1, sizeof(F1AP_Cause_t));
+
+      // dummy value
+      drbs_failedToBeSetup_item.cause->present = F1AP_Cause_PR_radioNetwork;
+
+      switch(drbs_failedToBeSetup_item.cause->present)
+      {
+        case F1AP_Cause_PR_radioNetwork:
+          drbs_failedToBeSetup_item.cause->choice.radioNetwork = F1AP_CauseRadioNetwork_unspecified;
+          break;
+        case F1AP_Cause_PR_transport:
+          drbs_failedToBeSetup_item.cause->choice.transport = F1AP_CauseTransport_unspecified;
+          break;
+        case F1AP_Cause_PR_protocol:
+          drbs_failedToBeSetup_item.cause->choice.protocol = F1AP_CauseProtocol_unspecified;
+          break;
+        case F1AP_Cause_PR_misc:
+          drbs_failedToBeSetup_item.cause->choice.misc = F1AP_CauseMisc_unspecified;
+          break;
+        case F1AP_Cause_PR_NOTHING:
+        default:
+          break;
+      } // switch
+
+      /* ADD */
+      drbs_failedToBeSetup_item_ies->value.choice.DRBs_FailedToBeSetup_Item = drbs_failedToBeSetup_item;
+      ASN_SEQUENCE_ADD(&ie->value.choice.DRBs_FailedToBeSetup_List.list,
+                     drbs_failedToBeSetup_item_ies);
+  } // for i
+  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+
+  // /*  */
+  /* c10. SCell_FailedtoSetup_List */
+  ie = (F1AP_UEContextSetupResponseIEs_t *)calloc(1, sizeof(F1AP_UEContextSetupResponseIEs_t));
+  ie->id                             = F1AP_ProtocolIE_ID_id_SCell_FailedtoSetup_List;
+  ie->criticality                    = F1AP_Criticality_ignore;
+  ie->value.present                  = F1AP_UEContextSetupResponseIEs__value_PR_SCell_FailedtoSetup_List;
+
+  for (i=0;
+       i<1;
+       i++) {
+      //
+      F1AP_SCell_FailedtoSetup_ItemIEs_t *sCell_FailedtoSetup_item_ies;
+      sCell_FailedtoSetup_item_ies = (F1AP_SCell_FailedtoSetup_ItemIEs_t *)calloc(1, sizeof(F1AP_SCell_FailedtoSetup_ItemIEs_t));
+      sCell_FailedtoSetup_item_ies->id            = F1AP_ProtocolIE_ID_id_SCell_FailedtoSetup_Item;
+      sCell_FailedtoSetup_item_ies->criticality   = F1AP_Criticality_ignore;
+      sCell_FailedtoSetup_item_ies->value.present = F1AP_SCell_FailedtoSetup_ItemIEs__value_PR_SCell_FailedtoSetup_Item;
+
+      /* 10.1 DRBs_Setup_Item */
+      F1AP_SCell_FailedtoSetup_Item_t sCell_FailedtoSetup_item;
+      memset((void *)&sCell_FailedtoSetup_item, 0, sizeof(F1AP_SCell_FailedtoSetup_Item_t));
+
+      /* sCell_ID */
+      F1AP_NRCGI_t nRCGI;  // issue here
+      MCC_MNC_TO_PLMNID(f1ap_du_data->mcc[i], f1ap_du_data->mnc[i], f1ap_du_data->mnc_digit_length[i], &nRCGI.pLMN_Identity);
+
+      NR_CELL_ID_TO_BIT_STRING(f1ap_du_data->nr_cellid[0], &nRCGI.nRCellIdentity);
+
+      sCell_FailedtoSetup_item.sCell_ID = nRCGI;
+
+      /* cause */
+      sCell_FailedtoSetup_item.cause = (F1AP_Cause_t *)calloc(1, sizeof(F1AP_Cause_t));
+
+      // dummy value
+      sCell_FailedtoSetup_item.cause->present = F1AP_Cause_PR_radioNetwork;
+
+      switch(sCell_FailedtoSetup_item.cause->present)
+      {
+        case F1AP_Cause_PR_radioNetwork:
+          sCell_FailedtoSetup_item.cause->choice.radioNetwork = F1AP_CauseRadioNetwork_unspecified;
+          break;
+        case F1AP_Cause_PR_transport:
+          sCell_FailedtoSetup_item.cause->choice.transport = F1AP_CauseTransport_unspecified;
+          break;
+        case F1AP_Cause_PR_protocol:
+          sCell_FailedtoSetup_item.cause->choice.protocol = F1AP_CauseProtocol_unspecified;
+          break;
+        case F1AP_Cause_PR_misc:
+          sCell_FailedtoSetup_item.cause->choice.misc = F1AP_CauseMisc_unspecified;
+          break;
+        case F1AP_Cause_PR_NOTHING:
+        default:
+          break;
+      } // switch
+
+      /* ADD */
+      sCell_FailedtoSetup_item_ies->value.choice.SCell_FailedtoSetup_Item = sCell_FailedtoSetup_item;
+      ASN_SEQUENCE_ADD(&ie->value.choice.SCell_FailedtoSetup_List.list,
+                      sCell_FailedtoSetup_item_ies);
+  } // for i
+  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+ 
+
+  /* Optional */
+  /* c11. InactivityMonitoringResponse */
+  if (0) {
+    ie = (F1AP_UEContextSetupResponseIEs_t *)calloc(1, sizeof(F1AP_UEContextSetupResponseIEs_t));
+    ie->id                                        = F1AP_ProtocolIE_ID_id_InactivityMonitoringResponse;
+    ie->criticality                               = F1AP_Criticality_ignore;
+    ie->value.present                             = F1AP_UEContextSetupResponseIEs__value_PR_InactivityMonitoringResponse;
+    ie->value.choice.InactivityMonitoringResponse = F1AP_InactivityMonitoringResponse_not_supported;
+    ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+  }
+
+
+  /* Optional */
+  /* c12. CriticalityDiagnostics */
+  if (0) {
+    ie = (F1AP_UEContextSetupResponseIEs_t *)calloc(1, sizeof(F1AP_UEContextSetupResponseIEs_t));
+    ie->id                             = F1AP_ProtocolIE_ID_id_CriticalityDiagnostics;
+    ie->criticality                    = F1AP_Criticality_ignore;
+    ie->value.present                  = F1AP_UEContextSetupResponseIEs__value_PR_CriticalityDiagnostics;
+    
+    ie->value.choice.CriticalityDiagnostics.procedureCode = (F1AP_ProcedureCode_t *)calloc(1, sizeof(F1AP_ProcedureCode_t));
+    *ie->value.choice.CriticalityDiagnostics.procedureCode = F1AP_ProcedureCode_id_UEContextSetup;
+    
+    ie->value.choice.CriticalityDiagnostics.triggeringMessage = (F1AP_TriggeringMessage_t *)calloc(1, sizeof(F1AP_TriggeringMessage_t));
+    *ie->value.choice.CriticalityDiagnostics.triggeringMessage = F1AP_TriggeringMessage_initiating_message;
+    
+    ie->value.choice.CriticalityDiagnostics.procedureCriticality = (F1AP_Criticality_t *)calloc(1, sizeof(F1AP_Criticality_t));
+    *ie->value.choice.CriticalityDiagnostics.procedureCriticality = F1AP_Criticality_reject;
+    
+    ie->value.choice.CriticalityDiagnostics.transactionID = (F1AP_TransactionID_t *)calloc(1, sizeof(F1AP_TransactionID_t));
+    *ie->value.choice.CriticalityDiagnostics.transactionID = 0;
+    
+    ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+  }
+
+
+  /* encode */
+  if (f1ap_encode_pdu(&pdu, &buffer, &len) < 0) {
+    LOG_E(F1AP, "Failed to encode F1 setup request\n");
+    return -1;
+  }
+
+  return 0;
+}
+
+int DU_send_UE_CONTEXT_SETUP_FAILURE(instance_t instance) {
+  AssertFatal(1==0,"Not implemented yet\n");
+}
+
+
+int DU_send_UE_CONTEXT_RELEASE_REQUEST(instance_t instance,
+                                       f1ap_ue_context_release_req_t *req) {
+  F1AP_F1AP_PDU_t                   pdu;
+  F1AP_UEContextReleaseRequest_t    *out;
+  F1AP_UEContextReleaseRequestIEs_t *ie;
+
+  uint8_t  *buffer;
+  uint32_t  len;
+  //int       i = 0, j = 0;
+
+  /* Create */
+  /* 0. Message Type */
+  memset(&pdu, 0, sizeof(pdu));
+  pdu.present = F1AP_F1AP_PDU_PR_initiatingMessage;
+  pdu.choice.initiatingMessage = (F1AP_InitiatingMessage_t *)calloc(1, sizeof(F1AP_InitiatingMessage_t));
+  pdu.choice.initiatingMessage->procedureCode = F1AP_ProcedureCode_id_UEContextReleaseRequest;
+  pdu.choice.initiatingMessage->criticality   = F1AP_Criticality_reject;
+  pdu.choice.initiatingMessage->value.present = F1AP_InitiatingMessage__value_PR_UEContextReleaseRequest;
+  out = &pdu.choice.initiatingMessage->value.choice.UEContextReleaseRequest;
+  
+  /* mandatory */
+  /* c1. GNB_CU_UE_F1AP_ID */
+  ie = (F1AP_UEContextReleaseRequestIEs_t *)calloc(1, sizeof(F1AP_UEContextReleaseRequestIEs_t));
+  ie->id                             = F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID;
+  ie->criticality                    = F1AP_Criticality_reject;
+  ie->value.present                  = F1AP_UEContextReleaseRequestIEs__value_PR_GNB_CU_UE_F1AP_ID;
+  ie->value.choice.GNB_CU_UE_F1AP_ID = f1ap_get_cu_ue_f1ap_id(&f1ap_du_inst[instance], req->rnti);
+  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+
+  /* mandatory */
+  /* c2. GNB_DU_UE_F1AP_ID */
+  ie = (F1AP_UEContextReleaseRequestIEs_t *)calloc(1, sizeof(F1AP_UEContextReleaseRequestIEs_t));
+  ie->id                             = F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID;
+  ie->criticality                    = F1AP_Criticality_reject;
+  ie->value.present                  = F1AP_UEContextReleaseRequestIEs__value_PR_GNB_DU_UE_F1AP_ID;
+  ie->value.choice.GNB_DU_UE_F1AP_ID = f1ap_get_du_ue_f1ap_id(&f1ap_du_inst[instance], req->rnti);
+  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+
+  /* mandatory */
+  /* c3. Cause */
+  ie = (F1AP_UEContextReleaseRequestIEs_t *)calloc(1, sizeof(F1AP_UEContextReleaseRequestIEs_t));
+  ie->id                             = F1AP_ProtocolIE_ID_id_Cause;
+  ie->criticality                    = F1AP_Criticality_ignore;
+  ie->value.present                  = F1AP_UEContextReleaseRequestIEs__value_PR_Cause;
+
+  switch (req->cause)
+  {
+    case F1AP_CAUSE_RADIO_NETWORK:
+      ie->value.choice.Cause.present = F1AP_Cause_PR_radioNetwork;
+      ie->value.choice.Cause.choice.radioNetwork = req->cause_value;
+      break;
+    case F1AP_CAUSE_TRANSPORT:
+      ie->value.choice.Cause.present = F1AP_Cause_PR_transport;
+      ie->value.choice.Cause.choice.transport = req->cause_value;
+      break;
+    case F1AP_CAUSE_PROTOCOL:
+      ie->value.choice.Cause.present = F1AP_Cause_PR_protocol;
+      ie->value.choice.Cause.choice.protocol = req->cause_value;
+      break;
+    case F1AP_CAUSE_MISC:
+      ie->value.choice.Cause.present = F1AP_Cause_PR_misc;
+      ie->value.choice.Cause.choice.misc = req->cause_value;
+      break;
+    case F1AP_CAUSE_NOTHING:
+    default:
+      ie->value.choice.Cause.present = F1AP_Cause_PR_NOTHING;
+      break;
+  }
+  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+
+  /* encode */
+  if (f1ap_encode_pdu(&pdu, &buffer, &len) < 0) {
+    LOG_E(F1AP, "Failed to encode F1 context release request\n");
+    return -1;
+  }
+
+  du_f1ap_itti_send_sctp_data_req(instance,
+      f1ap_du_data->assoc_id,
+      buffer,
+      len,
+      f1ap_du_data->default_sctp_stream_id);
+
+  return 0;
+}
+
+
+int DU_handle_UE_CONTEXT_RELEASE_COMMAND(instance_t       instance,
+                                         uint32_t         assoc_id,
+                                         uint32_t         stream,
+                                         F1AP_F1AP_PDU_t *pdu) {
+
+  F1AP_UEContextReleaseCommand_t *container;
+  F1AP_UEContextReleaseCommandIEs_t *ie;
+  protocol_ctxt_t ctxt;
+
+  DevAssert(pdu);
+
+  container = &pdu->choice.initiatingMessage->value.choice.UEContextReleaseCommand;
+
+  /* GNB_CU_UE_F1AP_ID */
+  F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextReleaseCommandIEs_t, ie, container,
+                             F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID, true);
+  ctxt.rnti = f1ap_get_rnti_by_cu_id(&f1ap_du_inst[instance], ie->value.choice.GNB_CU_UE_F1AP_ID);
+  ctxt.module_id = instance;
+  ctxt.instance  = instance;
+  ctxt.enb_flag  = 1;
+
+  /* GNB_DU_UE_F1AP_ID */
+  F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextReleaseCommandIEs_t, ie, container,
+                             F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID, true);
+  const rnti_t rnti = f1ap_get_rnti_by_du_id(&f1ap_du_inst[instance],
+                                             ie->value.choice.GNB_DU_UE_F1AP_ID);
+  AssertFatal(ctxt.rnti == rnti,
+              "RNTI obtained through DU ID (%x) is different from CU ID (%x)\n",
+              rnti, ctxt.rnti);
+
+  int UE_out_of_sync = 0;
+  for (int n = 0; n < MAX_MOBILES_PER_ENB; ++n) {
+    if (RC.mac[instance]->UE_list.active[n] == TRUE
+        && rnti == UE_RNTI(instance, n)) {
+      UE_out_of_sync = RC.mac[instance]->UE_list.UE_sched_ctrl[n].ul_out_of_sync;
+      break;
+    }
+  }
+
+  /* We don't need the Cause */
+
+  /* Optional RRC Container: if present, send to UE */
+  F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextReleaseCommandIEs_t, ie, container,
+                             F1AP_ProtocolIE_ID_id_RRCContainer, false);
+  if (ie && !UE_out_of_sync) {
+    /* RRC message and UE is reachable, send message */
+    const sdu_size_t sdu_len = ie->value.choice.RRCContainer.size;
+    mem_block_t *pdu_p = NULL;
+    pdu_p = get_free_mem_block(sdu_len, __func__);
+    memcpy(&pdu_p->data[0], ie->value.choice.RRCContainer.buf, sdu_len);
+    rlc_op_status_t rlc_status = rlc_data_req(&ctxt
+                                              , 1
+                                              , MBMS_FLAG_NO
+                                              , 1 // SRB 1 correct?
+                                              , 0
+                                              , 0
+                                              , sdu_len
+                                              , pdu_p
+#ifdef Rel14
+                                              ,NULL
+                                              ,NULL
+#endif
+                                              );
+    switch (rlc_status) {
+      case RLC_OP_STATUS_OK:
+        break;
+      case RLC_OP_STATUS_BAD_PARAMETER:
+        LOG_W(F1AP, "Data sending request over RLC failed with 'Bad Parameter' reason!\n");
+        break;
+      case RLC_OP_STATUS_INTERNAL_ERROR:
+        LOG_W(F1AP, "Data sending request over RLC failed with 'Internal Error' reason!\n");
+        break;
+      case RLC_OP_STATUS_OUT_OF_RESSOURCES:
+        LOG_W(F1AP, "Data sending request over RLC failed with 'Out of Resources' reason!\n");
+        break;
+      default:
+        LOG_W(F1AP, "RLC returned an unknown status code after F1AP placed "
+              "the order to send some data (Status Code:%d)\n", rlc_status);
+        break;
+    }
+  }
+
+  struct rrc_eNB_ue_context_s* ue_context_p;
+  ue_context_p = rrc_eNB_get_ue_context(RC.rrc[ctxt.module_id], ctxt.rnti);
+  if (ue_context_p && !UE_out_of_sync) {
+    /* UE exists and is in sync so we start a timer before releasing the
+     * connection */
+    pthread_mutex_lock(&rrc_release_freelist);
+    for (uint16_t release_num = 0; release_num < NUMBER_OF_UE_MAX; release_num++) {
+      if (rrc_release_info.RRC_release_ctrl[release_num].flag == 0) {
+        if (ue_context_p->ue_context.ue_release_timer_s1 > 0)
+          rrc_release_info.RRC_release_ctrl[release_num].flag = 1;
+        else
+          rrc_release_info.RRC_release_ctrl[release_num].flag = 2;
+        rrc_release_info.RRC_release_ctrl[release_num].rnti = ctxt.rnti;
+        LOG_D(F1AP, "add rrc_release_info RNTI %x\n", ctxt.rnti);
+        // TODO: how to provide the correct MUI?
+        rrc_release_info.RRC_release_ctrl[release_num].rrc_eNB_mui = 0;
+        rrc_release_info.num_UEs++;
+        LOG_D(RRC,"Generate DLSCH Release send: index %d rnti %x mui %d flag %d \n",release_num,
+              ctxt.rnti, 0, rrc_release_info.RRC_release_ctrl[release_num].flag);
+        break;
+      }
+    }
+    pthread_mutex_unlock(&rrc_release_freelist);
+    ue_context_p->ue_context.ue_release_timer_s1 = 0;
+  } else if (ue_context_p && UE_out_of_sync) {
+    /* UE exists and is out of sync, drop the connection */
+    mac_eNB_rrc_ul_failure(instance, 0, 0, 0, rnti);
+  } else {
+    LOG_E(F1AP, "no ue_context for RNTI %x, acknowledging release\n", rnti);
+  }
+  
+  /* TODO send this once the connection has really been released */
+  f1ap_ue_context_release_cplt_t cplt;
+  cplt.rnti = ctxt.rnti;
+  DU_send_UE_CONTEXT_RELEASE_COMPLETE(instance, &cplt);
+
+  return 0;
+}
+
+
+int DU_send_UE_CONTEXT_RELEASE_COMPLETE(instance_t instance,
+                                        f1ap_ue_context_release_cplt_t *cplt) {
+  F1AP_F1AP_PDU_t                     pdu;
+  F1AP_UEContextReleaseComplete_t    *out;
+  F1AP_UEContextReleaseCompleteIEs_t *ie;
+
+  /* Create */
+  /* 0. Message Type */
+  memset(&pdu, 0, sizeof(pdu));
+  pdu.present = F1AP_F1AP_PDU_PR_successfulOutcome;
+  pdu.choice.successfulOutcome = (F1AP_SuccessfulOutcome_t *)calloc(1, sizeof(F1AP_SuccessfulOutcome_t));
+  pdu.choice.successfulOutcome->procedureCode = F1AP_ProcedureCode_id_UEContextRelease;
+  pdu.choice.successfulOutcome->criticality   = F1AP_Criticality_reject;
+  pdu.choice.successfulOutcome->value.present = F1AP_SuccessfulOutcome__value_PR_UEContextReleaseComplete;
+  out = &pdu.choice.successfulOutcome->value.choice.UEContextReleaseComplete;
+  
+  /* mandatory */
+  /* c1. GNB_CU_UE_F1AP_ID */
+  ie = (F1AP_UEContextReleaseCompleteIEs_t *)calloc(1, sizeof(F1AP_UEContextReleaseCompleteIEs_t));
+  ie->id                             = F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID;
+  ie->criticality                    = F1AP_Criticality_reject;
+  ie->value.present                  = F1AP_UEContextReleaseCompleteIEs__value_PR_GNB_CU_UE_F1AP_ID;
+  ie->value.choice.GNB_CU_UE_F1AP_ID = f1ap_get_cu_ue_f1ap_id(&f1ap_du_inst[instance], cplt->rnti);
+  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+
+  /* mandatory */
+  /* c2. GNB_DU_UE_F1AP_ID */
+  ie = (F1AP_UEContextReleaseCompleteIEs_t *)calloc(1, sizeof(F1AP_UEContextReleaseCompleteIEs_t));
+  ie->id                             = F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID;
+  ie->criticality                    = F1AP_Criticality_reject;
+  ie->value.present                  = F1AP_UEContextReleaseCompleteIEs__value_PR_GNB_DU_UE_F1AP_ID;
+  ie->value.choice.GNB_DU_UE_F1AP_ID = f1ap_get_du_ue_f1ap_id(&f1ap_du_inst[instance], cplt->rnti);
+  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+
+  /* optional -> currently not used */
+  /* c3. CriticalityDiagnostics */
+  //if (0) {
+  //  ie = (F1AP_UEContextReleaseCompleteIEs_t *)calloc(1, sizeof(F1AP_UEContextReleaseCompleteIEs_t));
+  //  ie->id                             = F1AP_ProtocolIE_ID_id_CriticalityDiagnostics;
+  //  ie->criticality                    = F1AP_Criticality_ignore;
+  //  ie->value.present                  = F1AP_UEContextReleaseCompleteIEs__value_PR_CriticalityDiagnostics;
+
+  //  // dummy value
+  //  /* optional */
+  //  /* procedureCode */
+  //  if (0) {
+  //    ie->value.choice.CriticalityDiagnostics.procedureCode = (F1AP_ProcedureCode_t *)calloc(1, sizeof(F1AP_ProcedureCode_t));
+  //    ie->value.choice.CriticalityDiagnostics.procedureCode = 0L;
+  //  }
+
+  //  /* optional */
+  //  /* triggeringMessage */
+  //  if (0) {
+  //    ie->value.choice.CriticalityDiagnostics.triggeringMessage = (F1AP_TriggeringMessage_t *)calloc(1, sizeof(F1AP_TriggeringMessage_t));
+  //    ie->value.choice.CriticalityDiagnostics.triggeringMessage = (F1AP_TriggeringMessage_t *)F1AP_TriggeringMessage_successful_outcome;
+  //  }
+
+  //  /* optional */
+  //  /* procedureCriticality */
+  //  if (0) {
+  //    ie->value.choice.CriticalityDiagnostics.procedureCriticality = (F1AP_Criticality_t *)calloc(1, sizeof(F1AP_Criticality_t));
+  //    ie->value.choice.CriticalityDiagnostics.procedureCriticality = F1AP_Criticality_reject;
+  //  }
+
+  //  /* optional */
+  //  /* transactionID */
+  //  if (0) {
+  //    ie->value.choice.CriticalityDiagnostics.transactionID = (F1AP_TransactionID_t *)calloc(1, sizeof(F1AP_TransactionID_t));
+  //    ie->value.choice.CriticalityDiagnostics.transactionID = 0L;
+  //  }
+
+  //  /* optional */
+  //  /* F1AP_CriticalityDiagnostics_IE_List */
+  //  if (0) {
+  //    for (i=0;
+  //         i<0;
+  //         i++) {
+
+  //        F1AP_CriticalityDiagnostics_IE_Item_t *criticalityDiagnostics_ie_item = (F1AP_CriticalityDiagnostics_IE_Item_t *)calloc(1, sizeof(F1AP_CriticalityDiagnostics_IE_Item_t));;
+  //        criticalityDiagnostics_ie_item->iECriticality = F1AP_Criticality_reject;
+  //        criticalityDiagnostics_ie_item->iE_ID         = 0L;
+  //        criticalityDiagnostics_ie_item->typeOfError   = F1AP_TypeOfError_not_understood;
+
+  //        ASN_SEQUENCE_ADD(&ie->value.choice.CriticalityDiagnostics.iEsCriticalityDiagnostics->list,
+  //                    criticalityDiagnostics_ie_item);
+  //    }
+  //  }
+  //  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+  //}
+
+  /* encode */
+  uint8_t  *buffer;
+  uint32_t  len;
+  if (f1ap_encode_pdu(&pdu, &buffer, &len) < 0) {
+    LOG_E(F1AP, "Failed to encode F1 context release complete\n");
+    return -1;
+  }
+
+  du_f1ap_itti_send_sctp_data_req(instance,
+      f1ap_du_data->assoc_id,
+      buffer,
+      len,
+      f1ap_du_data->default_sctp_stream_id);
+
+  f1ap_remove_ue(&f1ap_du_inst[instance], cplt->rnti);
+  return 0;
+}
+
+
+int DU_handle_UE_CONTEXT_MODIFICATION_REQUEST(instance_t       instance,
+                                              uint32_t         assoc_id,
+                                              uint32_t         stream,
+                                              F1AP_F1AP_PDU_t *pdu) {
+  AssertFatal(1==0,"Not implemented yet\n");
+}
+
+//void DU_send_UE_CONTEXT_MODIFICATION_RESPONSE(F1AP_UEContextModificationResponse_t *UEContextModificationResponse) {
+int DU_send_UE_CONTEXT_MODIFICATION_RESPONSE(instance_t instance) {
+  F1AP_F1AP_PDU_t                        pdu;
+  F1AP_UEContextModificationResponse_t    *out;
+  F1AP_UEContextModificationResponseIEs_t *ie;
+
+  uint8_t  *buffer;
+  uint32_t  len;
+  int       i = 0;
+
+  /* Create */
+  /* 0. Message Type */
+  memset(&pdu, 0, sizeof(pdu));
+  pdu.present = F1AP_F1AP_PDU_PR_successfulOutcome;
+  pdu.choice.successfulOutcome = (F1AP_SuccessfulOutcome_t *)calloc(1, sizeof(F1AP_SuccessfulOutcome_t));
+  pdu.choice.successfulOutcome->procedureCode = F1AP_ProcedureCode_id_UEContextModification;
+  pdu.choice.successfulOutcome->criticality   = F1AP_Criticality_reject;
+  pdu.choice.successfulOutcome->value.present = F1AP_SuccessfulOutcome__value_PR_UEContextModificationResponse;
+  out = &pdu.choice.successfulOutcome->value.choice.UEContextModificationResponse;
+  
+  /* mandatory */
+  /* c1. GNB_CU_UE_F1AP_ID */
+  ie = (F1AP_UEContextModificationResponseIEs_t *)calloc(1, sizeof(F1AP_UEContextModificationResponseIEs_t));
+  ie->id                             = F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID;
+  ie->criticality                    = F1AP_Criticality_reject;
+  ie->value.present                  = F1AP_UEContextModificationResponseIEs__value_PR_GNB_CU_UE_F1AP_ID;
+  ie->value.choice.GNB_CU_UE_F1AP_ID = 126L;
+  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+
+  /* mandatory */
+  /* c2. GNB_DU_UE_F1AP_ID */
+  ie = (F1AP_UEContextModificationResponseIEs_t *)calloc(1, sizeof(F1AP_UEContextModificationResponseIEs_t));
+  ie->id                             = F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID;
+  ie->criticality                    = F1AP_Criticality_reject;
+  ie->value.present                  = F1AP_UEContextModificationResponseIEs__value_PR_GNB_DU_UE_F1AP_ID;
+  ie->value.choice.GNB_DU_UE_F1AP_ID = 651L;
+  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+
+  /* optional */
+  /* c3. ResourceCoordinationTransferContainer */
+  if (0) {
+    ie = (F1AP_UEContextModificationResponseIEs_t *)calloc(1, sizeof(F1AP_UEContextModificationResponseIEs_t));
+    ie->id                             = F1AP_ProtocolIE_ID_id_ResourceCoordinationTransferContainer;
+    ie->criticality                    = F1AP_Criticality_ignore;
+    ie->value.present                  = F1AP_UEContextModificationResponseIEs__value_PR_ResourceCoordinationTransferContainer;
+    OCTET_STRING_fromBuf(&ie->value.choice.ResourceCoordinationTransferContainer, "asdsa1d32sa1d31asd31as",
+                         strlen("asdsa1d32sa1d31asd31as"));
+    ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+  }
+
+  /* optional */
+  /* c4. DUtoCURRCInformation */
+  if (0) {
+    ie = (F1AP_UEContextModificationResponseIEs_t *)calloc(1, sizeof(F1AP_UEContextModificationResponseIEs_t));
+    ie->id                             = F1AP_ProtocolIE_ID_id_DUtoCURRCInformation;
+    ie->criticality                    = F1AP_Criticality_reject;
+    ie->value.present                  = F1AP_UEContextModificationResponseIEs__value_PR_DUtoCURRCInformation;
+
+    OCTET_STRING_fromBuf(&ie->value.choice.DUtoCURRCInformation.cellGroupConfig, "asdsa1d32sa1d31asd31as",
+                       strlen("asdsa1d32sa1d31asd31as"));
+    /* OPTIONAL */
+    if (1) {
+      ie->value.choice.DUtoCURRCInformation.measGapConfig = (F1AP_MeasGapConfig_t *)calloc(1, sizeof(F1AP_MeasGapConfig_t));
+      OCTET_STRING_fromBuf( ie->value.choice.DUtoCURRCInformation.measGapConfig, "asdsa1d32sa1d31asd31as",
+                           strlen("asdsa1d32sa1d31asd31as"));
+      ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+    }
+  }
+
+
+  /* mandatory */
+  /* c5. DRBs_SetupMod_List */
+  ie = (F1AP_UEContextModificationResponseIEs_t *)calloc(1, sizeof(F1AP_UEContextModificationResponseIEs_t));
+  ie->id                             = F1AP_ProtocolIE_ID_id_DRBs_SetupMod_List;
+  ie->criticality                    = F1AP_Criticality_reject;
+  ie->value.present                  = F1AP_UEContextModificationResponseIEs__value_PR_DRBs_SetupMod_List;
+
+  for (i=0;
+       i<1;
+       i++) {
+    //
+    F1AP_DRBs_SetupMod_ItemIEs_t *drbs_setupMod_item_ies;
+    drbs_setupMod_item_ies = (F1AP_DRBs_SetupMod_ItemIEs_t *)calloc(1, sizeof(F1AP_DRBs_SetupMod_ItemIEs_t));
+    drbs_setupMod_item_ies->id            = F1AP_ProtocolIE_ID_id_DRBs_SetupMod_Item;
+    drbs_setupMod_item_ies->criticality   = F1AP_Criticality_reject;
+    drbs_setupMod_item_ies->value.present = F1AP_DRBs_SetupMod_ItemIEs__value_PR_DRBs_SetupMod_Item;
+
+    /* 10.1 DRBs_SetupMod_Item */
+    F1AP_DRBs_SetupMod_Item_t drbs_setupMod_item;
+    memset((void *)&drbs_setupMod_item, 0, sizeof(F1AP_DRBs_SetupMod_Item_t));
+
+    /* dRBID */
+    drbs_setupMod_item.dRBID = 30L;
+
+    /* DLTunnels_SetupMod_List */
+    int j = 0;
+    int maxnoofDLUPTNLInformation = 1; // 2;
+    for (j=0;
+        j<maxnoofDLUPTNLInformation;
+        j++) {
+        /*  DLTunnels_ToBeSetup_Item */
+        F1AP_DLUPTNLInformation_ToBeSetup_Item_t *dLUPTNLInformation_ToBeSetup_Item;
+        dLUPTNLInformation_ToBeSetup_Item = (F1AP_DLUPTNLInformation_ToBeSetup_Item_t *)calloc(1, sizeof(F1AP_DLUPTNLInformation_ToBeSetup_Item_t));
+        dLUPTNLInformation_ToBeSetup_Item->dLUPTNLInformation.present = F1AP_UPTransportLayerInformation_PR_gTPTunnel;
+        F1AP_GTPTunnel_t *gTPTunnel = (F1AP_GTPTunnel_t *)calloc(1, sizeof(F1AP_GTPTunnel_t));
+
+        TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(1234, &gTPTunnel->transportLayerAddress);
+
+        OCTET_STRING_fromBuf(&gTPTunnel->gTP_TEID, "1204",
+                             strlen("1204"));
+
+        dLUPTNLInformation_ToBeSetup_Item->dLUPTNLInformation.choice.gTPTunnel = gTPTunnel;
+
+        ASN_SEQUENCE_ADD(&drbs_setupMod_item.dLUPTNLInformation_ToBeSetup_List.list, dLUPTNLInformation_ToBeSetup_Item);
+    }
+
+    /* ADD */
+    drbs_setupMod_item_ies->value.choice.DRBs_SetupMod_Item = drbs_setupMod_item;
+    ASN_SEQUENCE_ADD(&ie->value.choice.DRBs_SetupMod_List.list,
+                   drbs_setupMod_item_ies);
+  }
+  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+
+
+  /* mandatory */
+  /* c6. DRBs_Modified_List */
+  ie = (F1AP_UEContextModificationResponseIEs_t *)calloc(1, sizeof(F1AP_UEContextModificationResponseIEs_t));
+  ie->id                             = F1AP_ProtocolIE_ID_id_DRBs_Modified_List;
+  ie->criticality                    = F1AP_Criticality_reject;
+  ie->value.present                  = F1AP_UEContextModificationResponseIEs__value_PR_DRBs_Modified_List;
+
+  for (i=0;
+       i<1;
+       i++) {
+    //
+    F1AP_DRBs_Modified_ItemIEs_t *drbs_modified_item_ies;
+    drbs_modified_item_ies = (F1AP_DRBs_Modified_ItemIEs_t *)calloc(1, sizeof(F1AP_DRBs_Modified_ItemIEs_t));
+    drbs_modified_item_ies->id            = F1AP_ProtocolIE_ID_id_DRBs_Modified_Item;
+    drbs_modified_item_ies->criticality   = F1AP_Criticality_reject;
+    drbs_modified_item_ies->value.present = F1AP_DRBs_Modified_ItemIEs__value_PR_DRBs_Modified_Item;
+
+    /* 13.1 SRBs_modified_Item */
+    F1AP_DRBs_Modified_Item_t drbs_modified_item;
+    memset((void *)&drbs_modified_item, 0, sizeof(F1AP_DRBs_Modified_Item_t));
+
+    /* dRBID */
+    drbs_modified_item.dRBID = 25L;
+
+    /* ULTunnels_Modified_List */
+    int maxnoofULTunnels = 1; // 2;
+    int j = 0;
+    for (j=0;
+         j<maxnoofULTunnels;
+         j++) {
+      /*  DLTunnels_Modified_Item */
+        F1AP_DLUPTNLInformation_ToBeSetup_Item_t *dLUPTNLInformation_ToBeSetup_Item;
+        dLUPTNLInformation_ToBeSetup_Item = (F1AP_DLUPTNLInformation_ToBeSetup_Item_t *)calloc(1, sizeof(F1AP_DLUPTNLInformation_ToBeSetup_Item_t));
+        dLUPTNLInformation_ToBeSetup_Item->dLUPTNLInformation.present = F1AP_UPTransportLayerInformation_PR_gTPTunnel;
+        F1AP_GTPTunnel_t *gTPTunnel = (F1AP_GTPTunnel_t *)calloc(1, sizeof(F1AP_GTPTunnel_t));
+
+        TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(1234, &gTPTunnel->transportLayerAddress);
+
+        OCTET_STRING_fromBuf(&gTPTunnel->gTP_TEID, "1204",
+                              strlen("1204"));
+
+        dLUPTNLInformation_ToBeSetup_Item->dLUPTNLInformation.choice.gTPTunnel = gTPTunnel;
+
+        ASN_SEQUENCE_ADD(&drbs_modified_item.dLUPTNLInformation_ToBeSetup_List.list, dLUPTNLInformation_ToBeSetup_Item);
+    }
+
+    /* ADD */
+    drbs_modified_item_ies->value.choice.DRBs_Modified_Item = drbs_modified_item;
+    ASN_SEQUENCE_ADD(&ie->value.choice.DRBs_Modified_List.list,
+                    drbs_modified_item_ies);
+  }
+  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+
+  /* mandatory */
+  /* c7. SRBs_FailedToBeSetupMod_List */
+  ie = (F1AP_UEContextModificationResponseIEs_t *)calloc(1, sizeof(F1AP_UEContextModificationResponseIEs_t));
+  ie->id                             = F1AP_ProtocolIE_ID_id_SRBs_FailedToBeSetupMod_List;
+  ie->criticality                    = F1AP_Criticality_reject;
+  ie->value.present                  = F1AP_UEContextModificationResponseIEs__value_PR_SRBs_FailedToBeSetupMod_List;
+
+  for (i=0;
+       i<1;
+       i++) {
+    //
+    F1AP_SRBs_FailedToBeSetupMod_ItemIEs_t *srbs_failedToBeSetupMod_item_ies;
+    srbs_failedToBeSetupMod_item_ies = (F1AP_SRBs_FailedToBeSetupMod_ItemIEs_t *)calloc(1, sizeof(F1AP_SRBs_FailedToBeSetupMod_ItemIEs_t));
+    srbs_failedToBeSetupMod_item_ies->id            = F1AP_ProtocolIE_ID_id_SRBs_FailedToBeSetupMod_Item;
+    srbs_failedToBeSetupMod_item_ies->criticality   = F1AP_Criticality_ignore;
+    srbs_failedToBeSetupMod_item_ies->value.present = F1AP_SRBs_FailedToBeSetupMod_ItemIEs__value_PR_SRBs_FailedToBeSetupMod_Item;
+
+    /* 9.1 SRBs_FailedToBeSetupMod_Item */
+    F1AP_SRBs_FailedToBeSetupMod_Item_t srbs_failedToBeSetupMod_item;
+    memset((void *)&srbs_failedToBeSetupMod_item, 0, sizeof(F1AP_SRBs_FailedToBeSetupMod_Item_t));
+
+    /* - sRBID */
+    srbs_failedToBeSetupMod_item.sRBID = 50L;
+
+    srbs_failedToBeSetupMod_item.cause = (F1AP_Cause_t *)calloc(1, sizeof(F1AP_Cause_t));
+    srbs_failedToBeSetupMod_item.cause->present = F1AP_Cause_PR_radioNetwork;
+    srbs_failedToBeSetupMod_item.cause->choice.radioNetwork = F1AP_CauseRadioNetwork_unknown_or_already_allocated_gnd_du_ue_f1ap_id;
+
+    /* ADD */
+    srbs_failedToBeSetupMod_item_ies->value.choice.SRBs_FailedToBeSetupMod_Item = srbs_failedToBeSetupMod_item;
+    ASN_SEQUENCE_ADD(&ie->value.choice.SRBs_FailedToBeSetupMod_List.list,
+                     srbs_failedToBeSetupMod_item_ies);
+  }
+  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+
+  /* mandatory */
+  /* c8. DRBs_FailedToBeSetupMod_List */
+  ie = (F1AP_UEContextModificationResponseIEs_t *)calloc(1, sizeof(F1AP_UEContextModificationResponseIEs_t));
+  ie->id                             = F1AP_ProtocolIE_ID_id_DRBs_FailedToBeSetupMod_List;
+  ie->criticality                    = F1AP_Criticality_reject;
+  ie->value.present                  = F1AP_UEContextModificationResponseIEs__value_PR_DRBs_FailedToBeSetupMod_List;
+
+  for (i=0;
+       i<1;
+       i++) {
+    //
+    F1AP_DRBs_FailedToBeSetupMod_ItemIEs_t *drbs_failedToBeSetupMod_item_ies;
+    drbs_failedToBeSetupMod_item_ies = (F1AP_DRBs_FailedToBeSetupMod_ItemIEs_t *)calloc(1, sizeof(F1AP_DRBs_FailedToBeSetupMod_ItemIEs_t));
+    drbs_failedToBeSetupMod_item_ies->id            = F1AP_ProtocolIE_ID_id_DRBs_FailedToBeSetupMod_Item;
+    drbs_failedToBeSetupMod_item_ies->criticality   = F1AP_Criticality_reject;
+    drbs_failedToBeSetupMod_item_ies->value.present = F1AP_DRBs_FailedToBeSetupMod_ItemIEs__value_PR_DRBs_FailedToBeSetupMod_Item;
+
+    /* 10.1 DRBs_ToBeSetupMod_Item */
+    F1AP_DRBs_FailedToBeSetupMod_Item_t drbs_failedToBeSetupMod_item;
+    memset((void *)&drbs_failedToBeSetupMod_item, 0, sizeof(F1AP_DRBs_FailedToBeSetupMod_Item_t));
+
+    /* dRBID */
+    drbs_failedToBeSetupMod_item.dRBID = 30L;
+
+    drbs_failedToBeSetupMod_item.cause = (F1AP_Cause_t *)calloc(1, sizeof(F1AP_Cause_t));
+    drbs_failedToBeSetupMod_item.cause->present = F1AP_Cause_PR_radioNetwork;
+    drbs_failedToBeSetupMod_item.cause->choice.radioNetwork = F1AP_CauseRadioNetwork_unknown_or_already_allocated_gnd_du_ue_f1ap_id;
+
+    /* ADD */
+    drbs_failedToBeSetupMod_item_ies->value.choice.DRBs_FailedToBeSetupMod_Item = drbs_failedToBeSetupMod_item;
+    ASN_SEQUENCE_ADD(&ie->value.choice.DRBs_FailedToBeSetupMod_List.list,
+                     drbs_failedToBeSetupMod_item_ies);
+
+  }
+  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+
+
+  /* mandatory */
+  /* c9. SCell_FailedtoSetupMod_List */
+  ie = (F1AP_UEContextModificationResponseIEs_t *)calloc(1, sizeof(F1AP_UEContextModificationResponseIEs_t));
+  ie->id                             = F1AP_ProtocolIE_ID_id_SCell_FailedtoSetupMod_List;
+  ie->criticality                    = F1AP_Criticality_ignore;
+  ie->value.present                  = F1AP_UEContextModificationResponseIEs__value_PR_SCell_FailedtoSetupMod_List;
+
+  for (i=0;
+       i<1;
+       i++) {
+     //
+     F1AP_SCell_FailedtoSetupMod_ItemIEs_t *scell_failedtoSetupMod_item_ies;
+     scell_failedtoSetupMod_item_ies = (F1AP_SCell_FailedtoSetupMod_ItemIEs_t *)calloc(1, sizeof(F1AP_SCell_FailedtoSetupMod_ItemIEs_t));
+     scell_failedtoSetupMod_item_ies->id            = F1AP_ProtocolIE_ID_id_SCell_FailedtoSetupMod_Item;
+     scell_failedtoSetupMod_item_ies->criticality   = F1AP_Criticality_ignore;
+     scell_failedtoSetupMod_item_ies->value.present = F1AP_SCell_FailedtoSetupMod_ItemIEs__value_PR_SCell_FailedtoSetupMod_Item;
+
+     /* 8.1 SCell_ToBeSetup_Item */
+     F1AP_SCell_FailedtoSetupMod_Item_t scell_failedtoSetupMod_item;
+     memset((void *)&scell_failedtoSetupMod_item, 0, sizeof(F1AP_SCell_FailedtoSetupMod_Item_t));
+
+     /* - sCell_ID */
+     F1AP_NRCGI_t nRCGI;
+     MCC_MNC_TO_PLMNID(f1ap_du_data->mcc[i], f1ap_du_data->mnc[i], f1ap_du_data->mnc_digit_length[i],
+                                        &nRCGI.pLMN_Identity);
+
+     NR_CELL_ID_TO_BIT_STRING(f1ap_du_data->nr_cellid[0], &nRCGI.nRCellIdentity);
+
+     scell_failedtoSetupMod_item.sCell_ID = nRCGI;
+
+     scell_failedtoSetupMod_item.cause = (F1AP_Cause_t *)calloc(1, sizeof(F1AP_Cause_t));
+     scell_failedtoSetupMod_item.cause->present = F1AP_Cause_PR_radioNetwork;
+     scell_failedtoSetupMod_item.cause->choice.radioNetwork = F1AP_CauseRadioNetwork_unknown_or_already_allocated_gnd_du_ue_f1ap_id;
+
+        /* ADD */
+     scell_failedtoSetupMod_item_ies->value.choice.SCell_FailedtoSetupMod_Item = scell_failedtoSetupMod_item;
+     ASN_SEQUENCE_ADD(&ie->value.choice.SCell_FailedtoSetupMod_List.list,
+                      scell_failedtoSetupMod_item_ies);
+  }
+  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+
+  /* mandatory */
+  /* c10. DRBs_FailedToBeModified_List */
+  ie = (F1AP_UEContextModificationResponseIEs_t *)calloc(1, sizeof(F1AP_UEContextModificationResponseIEs_t));
+  ie->id                             = F1AP_ProtocolIE_ID_id_DRBs_FailedToBeModified_List;
+  ie->criticality                    = F1AP_Criticality_reject;
+  ie->value.present                  = F1AP_UEContextModificationResponseIEs__value_PR_DRBs_FailedToBeModified_List;
+
+  for (i=0;
+       i<1;
+       i++) {
+    //
+    F1AP_DRBs_FailedToBeModified_ItemIEs_t *drbs_failedToBeModified_item_ies;
+    drbs_failedToBeModified_item_ies = (F1AP_DRBs_FailedToBeModified_ItemIEs_t *)calloc(1, sizeof(F1AP_DRBs_FailedToBeModified_ItemIEs_t));
+    drbs_failedToBeModified_item_ies->id            = F1AP_ProtocolIE_ID_id_DRBs_FailedToBeModified_Item;
+    drbs_failedToBeModified_item_ies->criticality   = F1AP_Criticality_reject;
+    drbs_failedToBeModified_item_ies->value.present = F1AP_DRBs_FailedToBeModified_ItemIEs__value_PR_DRBs_FailedToBeModified_Item;
+
+    /* 13.1 DRBs_FailedToBeModified_Item */
+    F1AP_DRBs_FailedToBeModified_Item_t drbs_failedToBeModified_item;
+    memset((void *)&drbs_failedToBeModified_item, 0, sizeof(F1AP_DRBs_FailedToBeModified_Item_t));
+
+    /* dRBID */
+    drbs_failedToBeModified_item.dRBID = 30L;
+
+    drbs_failedToBeModified_item.cause = (F1AP_Cause_t *)calloc(1, sizeof(F1AP_Cause_t));
+    drbs_failedToBeModified_item.cause->present = F1AP_Cause_PR_radioNetwork;
+    drbs_failedToBeModified_item.cause->choice.radioNetwork = F1AP_CauseRadioNetwork_unknown_or_already_allocated_gnd_du_ue_f1ap_id;
+
+    /* ADD */
+    drbs_failedToBeModified_item_ies->value.choice.DRBs_FailedToBeModified_Item = drbs_failedToBeModified_item;
+    ASN_SEQUENCE_ADD(&ie->value.choice.DRBs_FailedToBeModified_List.list,
+                     drbs_failedToBeModified_item_ies);
+
+  }
+  ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+
+  // /*  */
+  /* c11. CriticalityDiagnostics */
+  if (0) {
+    ie = (F1AP_UEContextModificationResponseIEs_t *)calloc(1, sizeof(F1AP_UEContextModificationResponseIEs_t));
+    ie->id                             = F1AP_ProtocolIE_ID_id_CriticalityDiagnostics;
+    ie->criticality                    = F1AP_Criticality_ignore;
+    ie->value.present                  = F1AP_UEContextModificationResponseIEs__value_PR_CriticalityDiagnostics;
+
+    // dummy value
+    /* optional */
+    /* procedureCode */
+    if (0) {
+      ie->value.choice.CriticalityDiagnostics.procedureCode = (F1AP_ProcedureCode_t *)calloc(1, sizeof(F1AP_ProcedureCode_t));
+      ie->value.choice.CriticalityDiagnostics.procedureCode = 0L;
+    }
+
+    /* optional */
+    /* triggeringMessage */
+    if (0) {
+      ie->value.choice.CriticalityDiagnostics.triggeringMessage = (F1AP_TriggeringMessage_t *)calloc(1, sizeof(F1AP_TriggeringMessage_t));
+      ie->value.choice.CriticalityDiagnostics.triggeringMessage = (F1AP_TriggeringMessage_t *)F1AP_TriggeringMessage_successful_outcome;
+    }
+
+    /* optional */
+    /* procedureCriticality */
+    if (0) {
+      ie->value.choice.CriticalityDiagnostics.procedureCriticality = (F1AP_Criticality_t *)calloc(1, sizeof(F1AP_Criticality_t));
+      ie->value.choice.CriticalityDiagnostics.procedureCriticality = F1AP_Criticality_reject;
+    }
+
+    /* optional */
+    /* transactionID */
+    if (0) {
+      ie->value.choice.CriticalityDiagnostics.transactionID = (F1AP_TransactionID_t *)calloc(1, sizeof(F1AP_TransactionID_t));
+      ie->value.choice.CriticalityDiagnostics.transactionID = 0L;
+    }
+
+    /* optional */
+    /* F1AP_CriticalityDiagnostics_IE_List */
+    if (0) {
+      for (i=0;
+           i<0;
+           i++) {
+
+          F1AP_CriticalityDiagnostics_IE_Item_t *criticalityDiagnostics_ie_item = (F1AP_CriticalityDiagnostics_IE_Item_t *)calloc(1, sizeof(F1AP_CriticalityDiagnostics_IE_Item_t));;
+          criticalityDiagnostics_ie_item->iECriticality = F1AP_Criticality_reject;
+          criticalityDiagnostics_ie_item->iE_ID         = 0L;
+          criticalityDiagnostics_ie_item->typeOfError   = F1AP_TypeOfError_not_understood;
+
+          ASN_SEQUENCE_ADD(&ie->value.choice.CriticalityDiagnostics.iEsCriticalityDiagnostics->list,
+                      criticalityDiagnostics_ie_item);
+      }
+    }
+    ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+  }
+
+  /* encode */
+  if (f1ap_encode_pdu(&pdu, &buffer, &len) < 0) {
+    LOG_E(F1AP, "Failed to encode F1 setup request\n");
+    return -1;
+  }
+
+  //du_f1ap_itti_send_sctp_data_req(instance, f1ap_setup_req->assoc_id, buffer, len, 0);
+  return 0;
+
+}
+
+int DU_send_UE_CONTEXT_MODIFICATION_FAILURE(instance_t instance) {
+  AssertFatal(1==0,"Not implemented yet\n");
+}
+
+int DU_send_UE_CONTEXT_MODIFICATION_REQUIRED(instance_t instance) {
+  AssertFatal(1==0,"Not implemented yet\n");
+}
+
+int DU_handle_UE_CONTEXT_MODIFICATION_CONFIRM(instance_t       instance,
+                                              uint32_t         assoc_id,
+                                              uint32_t         stream,
+                                              F1AP_F1AP_PDU_t *pdu) {
+  AssertFatal(1==0,"Not implemented yet\n");
+}
diff --git a/openair2/F1AP/f1ap_du_ue_context_management.h b/openair2/F1AP/f1ap_du_ue_context_management.h
new file mode 100644
index 0000000000000000000000000000000000000000..2bb3ca95b9600cc552d616d9788e78bb79eccee4
--- /dev/null
+++ b/openair2/F1AP/f1ap_du_ue_context_management.h
@@ -0,0 +1,97 @@
+/*
+ * 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
+ */
+
+/*! \file f1ap_du_ue_context_management.h
+ * \brief f1ap ue context management for DU
+ * \author EURECOM/NTUST
+ * \date 2018
+ * \version 0.1
+ * \company Eurecom
+ * \email: navid.nikaein@eurecom.fr, bing-kai.hong@eurecom.fr
+ * \note
+ * \warning
+ */
+
+#ifndef F1AP_DU_UE_CONTEXT_MANAGEMENT_H_
+#define F1AP_DU_UE_CONTEXT_MANAGEMENT_H_
+
+/*
+ * UE Context Setup
+ */
+int DU_handle_UE_CONTEXT_SETUP_REQUEST(instance_t       instance,
+                                       uint32_t         assoc_id,
+                                       uint32_t         stream,
+                                       F1AP_F1AP_PDU_t *pdu);
+int DU_send_UE_CONTEXT_SETUP_RESPONSE(instance_t instance);
+int DU_send_UE_CONTEXT_SETUP_FAILURE(instance_t instance);
+
+
+/*
+ * UE Context Release Request (gNB-DU initiated)
+ */
+int DU_send_UE_CONTEXT_RELEASE_REQUEST(instance_t instance,
+                                       f1ap_ue_context_release_req_t *req);
+
+
+/*
+ * UE Context Release Command (gNB-CU initiated)
+ */
+int DU_handle_UE_CONTEXT_RELEASE_COMMAND(instance_t       instance,
+                                         uint32_t         assoc_id,
+                                         uint32_t         stream,
+                                         F1AP_F1AP_PDU_t *pdu);
+
+/*
+ * UE Context Release Complete (gNB-DU initiated)
+ */
+int DU_send_UE_CONTEXT_RELEASE_COMPLETE(instance_t instance,
+                                        f1ap_ue_context_release_cplt_t *cplt);
+
+
+/*
+ * UE Context Modification (gNB-CU initiated)
+ */
+int DU_handle_UE_CONTEXT_MODIFICATION_REQUEST(instance_t       instance,
+                                              uint32_t         assoc_id,
+                                              uint32_t         stream,
+                                              F1AP_F1AP_PDU_t *pdu);
+int DU_send_UE_CONTEXT_MODIFICATION_RESPONSE(instance_t instance);
+int DU_send_UE_CONTEXT_MODIFICATION_FAILURE(instance_t instance);
+
+
+/*
+ * UE Context Modification Required (gNB-DU initiated)
+ */
+int DU_send_UE_CONTEXT_MODIFICATION_REQUIRED(instance_t instance);
+int DU_handle_UE_CONTEXT_MODIFICATION_CONFIRM(instance_t       instance,
+                                              uint32_t         assoc_id,
+                                              uint32_t         stream,
+                                              F1AP_F1AP_PDU_t *pdu);
+
+/*
+ * UE Inactivity Notification
+ */
+
+/*
+ * Notify
+ */
+
+#endif /* F1AP_DU_UE_CONTEXT_MANAGEMENT_H_ */
diff --git a/openair2/F1AP/f1ap_du_warning_message_transmission.c b/openair2/F1AP/f1ap_du_warning_message_transmission.c
new file mode 100644
index 0000000000000000000000000000000000000000..b6bbedba2f0ed9c62704a0f9fdcf52c3e182ed60
--- /dev/null
+++ b/openair2/F1AP/f1ap_du_warning_message_transmission.c
@@ -0,0 +1,31 @@
+/*
+ * 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
+ */
+
+/*! \file f1ap_du_interface_management.h
+ * \brief f1ap interface management for DU
+ * \author EURECOM/NTUST
+ * \date 2018
+ * \version 0.1
+ * \company Eurecom
+ * \email: navid.nikaein@eurecom.fr, bing-kai.hong@eurecom.fr
+ * \note
+ * \warning
+ */
\ No newline at end of file
diff --git a/openair2/F1AP/f1ap_du_warning_message_transmission.h b/openair2/F1AP/f1ap_du_warning_message_transmission.h
new file mode 100644
index 0000000000000000000000000000000000000000..b6bbedba2f0ed9c62704a0f9fdcf52c3e182ed60
--- /dev/null
+++ b/openair2/F1AP/f1ap_du_warning_message_transmission.h
@@ -0,0 +1,31 @@
+/*
+ * 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
+ */
+
+/*! \file f1ap_du_interface_management.h
+ * \brief f1ap interface management for DU
+ * \author EURECOM/NTUST
+ * \date 2018
+ * \version 0.1
+ * \company Eurecom
+ * \email: navid.nikaein@eurecom.fr, bing-kai.hong@eurecom.fr
+ * \note
+ * \warning
+ */
\ No newline at end of file
diff --git a/openair2/F1AP/f1ap_encoder.c b/openair2/F1AP/f1ap_encoder.c
new file mode 100644
index 0000000000000000000000000000000000000000..e448690139f64ebb62a4a34394ffa29bf35d0683
--- /dev/null
+++ b/openair2/F1AP/f1ap_encoder.c
@@ -0,0 +1,376 @@
+/*
+ * 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
+ */
+
+/*! \file f1ap_encoder.c
+ * \brief f1ap pdu encode procedures
+ * \author EURECOM/NTUST
+ * \date 2018
+ * \version 0.1
+ * \company Eurecom
+ * \email: navid.nikaein@eurecom.fr, bing-kai.hong@eurecom.fr
+ * \note
+ * \warning
+ */
+
+#include "f1ap_common.h"
+#include "f1ap_encoder.h"
+
+int asn1_encoder_xer_print = 0;
+
+/*
+static inline int f1ap_encode_initiating(f1ap_message *message,
+    uint8_t **buffer,
+    uint32_t *len);
+
+static inline int f1ap_encode_successfull_outcome(f1ap_message *message,
+    uint8_t **buffer, uint32_t *len);
+
+static inline int f1ap_encode_unsuccessfull_outcome(f1ap_message *message,
+    uint8_t **buffer, uint32_t *len);
+
+static inline int f1ap_encode_f1_setup_request(
+  F1ap_F1SetupRequestIEs_t *f1SetupRequestIEs, uint8_t **buffer, uint32_t *length);
+
+static inline int f1ap_encode_trace_failure(F1ap_TraceFailureIndicationIEs_t
+    *trace_failure_ies_p, uint8_t **buffer,
+    uint32_t *length);
+
+static inline int f1ap_encode_initial_context_setup_response(
+  F1ap_InitialContextSetupResponseIEs_t *initialContextSetupResponseIEs,
+  uint8_t **buffer,
+  uint32_t *length);
+
+static inline
+int f1ap_encode_ue_context_release_complete(
+  F1ap_UEContextReleaseCompleteIEs_t *f1ap_UEContextReleaseCompleteIEs,
+  uint8_t                           **buffer,
+  uint32_t                           *length);
+
+static inline
+int f1ap_encode_ue_context_release_request(
+  F1ap_UEContextReleaseRequestIEs_t *f1ap_UEContextReleaseRequestIEs,
+  uint8_t                              **buffer,
+  uint32_t                              *length);
+  */
+
+int f1ap_encode_pdu(F1AP_F1AP_PDU_t *pdu, uint8_t **buffer, uint32_t *length)
+{
+  ssize_t    encoded;
+  DevAssert(pdu != NULL);
+  DevAssert(buffer != NULL);
+  DevAssert(length != NULL);
+
+  if (asn1_encoder_xer_print) {
+    LOG_E(F1AP, "----------------- ASN1 ENCODER PRINT START ----------------- \n");
+    xer_fprint(stdout, &asn_DEF_F1AP_F1AP_PDU, pdu);
+    LOG_E(F1AP, "----------------- ASN1 ENCODER PRINT END----------------- \n");
+  }
+
+  encoded = aper_encode_to_new_buffer(&asn_DEF_F1AP_F1AP_PDU, 0, pdu, (void **)buffer);
+
+  if (encoded < 0) {
+    LOG_E(F1AP, "Failed to encode F1AP message\n");
+    return -1;
+  }
+
+  *length = encoded;
+
+  return encoded;
+}
+
+/*
+static inline
+int f1ap_encode_initiating(f1ap_message *f1ap_message_p,
+                               uint8_t **buffer, uint32_t *len)
+{
+  int ret = -1;
+  MessageDef *message_p;
+  char       *message_string = NULL;
+  size_t      message_string_size;
+  MessagesIds message_id;
+
+  DevAssert(f1ap_message_p != NULL);
+
+  message_string = calloc(10000, sizeof(char));
+
+  f1ap_string_total_size = 0;
+
+  switch(f1ap_message_p->procedureCode) {
+  case F1ap_ProcedureCode_id_F1Setup:
+    ret = f1ap_encode_f1_setup_request(
+            &f1ap_message_p->msg.f1ap_F1SetupRequestIEs, buffer, len);
+    //f1ap_xer_print_f1ap_f1setuprequest(f1ap_xer__print2sp, message_string, f1ap_message_p);
+    message_id = F1AP_F1_SETUP_LOG;
+    break;
+
+  case F1ap_ProcedureCode_id_UEContextReleaseRequest:
+    ret = f1ap_encode_ue_context_release_request(
+            &f1ap_message_p->msg.f1ap_UEContextReleaseRequestIEs, buffer, len);
+    //f1ap_xer_print_f1ap_uecontextreleaserequest(f1ap_xer__print2sp,
+    //    message_string, f1ap_message_p);
+    message_id = F1AP_UE_CONTEXT_RELEASE_REQ_LOG;
+    break;
+
+
+  default:
+    F1AP_DEBUG("Unknown procedure ID (%d) for initiating message\n",
+               (int)f1ap_message_p->procedureCode);
+    return ret;
+    break;
+  }
+
+  message_string_size = strlen(message_string);
+
+  message_p = itti_alloc_new_message_sized(TASK_F1AP, message_id, message_string_size + sizeof (IttiMsgText));
+  message_p->ittiMsg.f1ap_f1_setup_log.size = message_string_size;
+  memcpy(&message_p->ittiMsg.f1ap_f1_setup_log.text, message_string, message_string_size);
+
+  itti_send_msg_to_task(TASK_UNKNOWN, INSTANCE_DEFAULT, message_p);
+
+  free(message_string);
+
+  return ret;
+}
+
+static inline
+int f1ap_encode_successfull_outcome(f1ap_message *f1ap_message_p,
+                                        uint8_t **buffer, uint32_t *len)
+{
+  int ret = -1;
+  MessageDef *message_p;
+  char       *message_string = NULL;
+  size_t      message_string_size;
+  MessagesIds message_id;
+
+  DevAssert(f1ap_message_p != NULL);
+
+  message_string = calloc(10000, sizeof(char));
+
+  f1ap_string_total_size = 0;
+  message_string_size = strlen(message_string);
+
+
+  switch(f1ap_message_p->procedureCode) {
+  case F1ap_ProcedureCode_id_InitialContextSetup:
+    ret = f1ap_encode_initial_context_setup_response(
+            &f1ap_message_p->msg.f1ap_InitialContextSetupResponseIEs, buffer, len);
+
+    f1ap_xer_print_f1ap_initialcontextsetupresponse(f1ap_xer__print2sp, message_string, f1ap_message_p);
+    message_id = F1AP_INITIAL_CONTEXT_SETUP_LOG;
+    message_p = itti_alloc_new_message_sized(TASK_F1AP, message_id, message_string_size + sizeof (IttiMsgText));
+    message_p->ittiMsg.f1ap_initial_context_setup_log.size = message_string_size;
+    memcpy(&message_p->ittiMsg.f1ap_initial_context_setup_log.text, message_string, message_string_size);
+    itti_send_msg_to_task(TASK_UNKNOWN, INSTANCE_DEFAULT, message_p);
+    free(message_string);
+    break;
+
+  case F1ap_ProcedureCode_id_UEContextRelease:
+    ret = f1ap_encode_ue_context_release_complete(
+            &f1ap_message_p->msg.f1ap_UEContextReleaseCompleteIEs, buffer, len);
+    f1ap_xer_print_f1ap_uecontextreleasecomplete(f1ap_xer__print2sp, message_string, f1ap_message_p);
+    message_id = F1AP_UE_CONTEXT_RELEASE_COMPLETE_LOG;
+    message_p = itti_alloc_new_message_sized(TASK_F1AP, message_id, message_string_size + sizeof (IttiMsgText));
+    message_p->ittiMsg.f1ap_ue_context_release_complete_log.size = message_string_size;
+    memcpy(&message_p->ittiMsg.f1ap_ue_context_release_complete_log.text, message_string, message_string_size);
+    itti_send_msg_to_task(TASK_UNKNOWN, INSTANCE_DEFAULT, message_p);
+    free(message_string);
+    break;
+
+  default:
+    F1AP_WARN("Unknown procedure ID (%d) for successfull outcome message\n",
+               (int)f1ap_message_p->procedureCode);
+    return ret;
+    break;
+  }
+
+
+  return ret;
+}
+
+static inline
+int f1ap_encode_unsuccessfull_outcome(f1ap_message *f1ap_message_p,
+    uint8_t **buffer, uint32_t *len)
+{
+  int ret = -1;
+  MessageDef *message_p;
+  char       *message_string = NULL;
+  size_t      message_string_size;
+  MessagesIds message_id;
+
+  DevAssert(f1ap_message_p != NULL);
+
+  message_string = calloc(10000, sizeof(char));
+
+  f1ap_string_total_size = 0;
+
+  switch(f1ap_message_p->procedureCode) {
+  case F1ap_ProcedureCode_id_InitialContextSetup:
+    //             ret = f1ap_encode_f1ap_initialcontextsetupfailureies(
+    //                 &f1ap_message_p->ittiMsg.f1ap_InitialContextSetupFailureIEs, buffer, len);
+    f1ap_xer_print_f1ap_initialcontextsetupfailure(f1ap_xer__print2sp, message_string, f1ap_message_p);
+    message_id = F1AP_INITIAL_CONTEXT_SETUP_LOG;
+    break;
+
+  default:
+    F1AP_DEBUG("Unknown procedure ID (%d) for unsuccessfull outcome message\n",
+               (int)f1ap_message_p->procedureCode);
+    return ret;
+    break;
+  }
+
+  message_string_size = strlen(message_string);
+
+  message_p = itti_alloc_new_message_sized(TASK_F1AP, message_id, message_string_size + sizeof (IttiMsgText));
+  message_p->ittiMsg.f1ap_initial_context_setup_log.size = message_string_size;
+  memcpy(&message_p->ittiMsg.f1ap_initial_context_setup_log.text, message_string, message_string_size);
+
+  itti_send_msg_to_task(TASK_UNKNOWN, INSTANCE_DEFAULT, message_p);
+
+  free(message_string);
+
+  return ret;
+}
+
+static inline
+int f1ap_encode_f1_setup_request(
+  F1ap_F1SetupRequestIEs_t *f1SetupRequestIEs,
+  uint8_t                 **buffer,
+  uint32_t                 *length)
+{
+  F1ap_F1SetupRequest_t  f1SetupRequest;
+  F1ap_F1SetupRequest_t *f1SetupRequest_p = &f1SetupRequest;
+
+  memset((void *)f1SetupRequest_p, 0, sizeof(f1SetupRequest));
+
+  if (f1ap_encode_f1ap_f1setuprequesties(f1SetupRequest_p, f1SetupRequestIEs) < 0) {
+    return -1;
+  }
+
+  return f1ap_generate_initiating_message(buffer,
+                                          length,
+                                          F1ap_ProcedureCode_id_F1Setup,
+                                          F1ap_Criticality_reject,
+                                          &asn_DEF_F1ap_F1SetupRequest,
+                                          f1SetupRequest_p);
+}
+
+static inline
+int f1ap_encode_trace_failure(
+  F1ap_TraceFailureIndicationIEs_t *trace_failure_ies_p,
+  uint8_t                         **buffer,
+  uint32_t                         *length)
+{
+  F1ap_TraceFailureIndication_t  trace_failure;
+  F1ap_TraceFailureIndication_t *trace_failure_p = &trace_failure;
+
+  memset((void *)trace_failure_p, 0, sizeof(trace_failure));
+
+  if (f1ap_encode_f1ap_tracefailureindicationies(
+        trace_failure_p, trace_failure_ies_p) < 0) {
+    return -1;
+  }
+
+  return f1ap_generate_initiating_message(buffer,
+                                          length,
+                                          F1ap_ProcedureCode_id_TraceFailureIndication,
+                                          F1ap_Criticality_reject,
+                                          &asn_DEF_F1ap_TraceFailureIndication,
+                                          trace_failure_p);
+}
+
+static inline
+int f1ap_encode_initial_context_setup_response(
+  F1ap_InitialContextSetupResponseIEs_t *initialContextSetupResponseIEs,
+  uint8_t                              **buffer,
+  uint32_t                              *length)
+{
+  F1ap_InitialContextSetupResponse_t  initial_context_setup_response;
+  F1ap_InitialContextSetupResponse_t *initial_context_setup_response_p =
+    &initial_context_setup_response;
+
+  memset((void *)initial_context_setup_response_p, 0,
+         sizeof(initial_context_setup_response));
+
+  if (f1ap_encode_f1ap_initialcontextsetupresponseies(
+        initial_context_setup_response_p, initialContextSetupResponseIEs) < 0) {
+    return -1;
+  }
+
+  return f1ap_generate_successfull_outcome(buffer,
+         length,
+         F1ap_ProcedureCode_id_InitialContextSetup,
+         F1ap_Criticality_reject,
+         &asn_DEF_F1ap_InitialContextSetupResponse,
+         initial_context_setup_response_p);
+}
+
+static inline
+int f1ap_encode_ue_context_release_complete(
+  F1ap_UEContextReleaseCompleteIEs_t *f1ap_UEContextReleaseCompleteIEs,
+  uint8_t                              **buffer,
+  uint32_t                              *length)
+{
+  F1ap_UEContextReleaseComplete_t  ue_context_release_complete;
+  F1ap_UEContextReleaseComplete_t *ue_context_release_complete_p =
+    &ue_context_release_complete;
+
+  memset((void *)ue_context_release_complete_p, 0,
+         sizeof(ue_context_release_complete));
+
+  if (f1ap_encode_f1ap_uecontextreleasecompleteies(
+        ue_context_release_complete_p, f1ap_UEContextReleaseCompleteIEs) < 0) {
+    return -1;
+  }
+
+  return f1ap_generate_successfull_outcome(buffer,
+         length,
+         F1ap_ProcedureCode_id_UEContextRelease,
+         F1ap_Criticality_reject,
+         &asn_DEF_F1ap_UEContextReleaseComplete,
+         ue_context_release_complete_p);
+}
+
+static inline
+int f1ap_encode_ue_context_release_request(
+  F1ap_UEContextReleaseRequestIEs_t *f1ap_UEContextReleaseRequestIEs,
+  uint8_t                              **buffer,
+  uint32_t                              *length)
+{
+  F1ap_UEContextReleaseRequest_t  ue_context_release_request;
+  F1ap_UEContextReleaseRequest_t *ue_context_release_request_p =
+    &ue_context_release_request;
+
+  memset((void *)ue_context_release_request_p, 0,
+         sizeof(ue_context_release_request));
+
+  if (f1ap_encode_f1ap_uecontextreleaserequesties(
+        ue_context_release_request_p, f1ap_UEContextReleaseRequestIEs) < 0) {
+    return -1;
+  }
+
+  return f1ap_generate_initiating_message(buffer,
+                                          length,
+                                          F1ap_ProcedureCode_id_UEContextReleaseRequest,
+                                          F1ap_Criticality_reject,
+                                          &asn_DEF_F1ap_UEContextReleaseRequest,
+                                          ue_context_release_request_p);
+}
+*/
diff --git a/openair2/F1AP/f1ap_encoder.h b/openair2/F1AP/f1ap_encoder.h
new file mode 100644
index 0000000000000000000000000000000000000000..695245d39b82a95febea987484f42cc7dfd61550
--- /dev/null
+++ b/openair2/F1AP/f1ap_encoder.h
@@ -0,0 +1,39 @@
+/*
+ * 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
+ */
+
+/*! \file f1ap_encoder.h
+ * \brief f1ap pdu encode procedures
+ * \author EURECOM/NTUST
+ * \date 2018
+ * \version 0.1
+ * \company Eurecom
+ * \email: navid.nikaein@eurecom.fr, bing-kai.hong@eurecom.fr
+ * \note
+ * \warning
+ */
+
+#ifndef F1AP_ENCODER_H_
+#define F1AP_ENCODER_H_
+
+int f1ap_encode_pdu(F1AP_F1AP_PDU_t *pdu, uint8_t **buffer, uint32_t *length)
+__attribute__ ((warn_unused_result));
+
+#endif /* F1AP_ENCODER_H_ */
diff --git a/openair2/F1AP/f1ap_handlers.c b/openair2/F1AP/f1ap_handlers.c
new file mode 100644
index 0000000000000000000000000000000000000000..a5b6a0996303da9c8b05e1beedf9cc7287fa2c92
--- /dev/null
+++ b/openair2/F1AP/f1ap_handlers.c
@@ -0,0 +1,127 @@
+/*
+ * 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
+ */
+
+/*! \file f1ap_handlers.c
+ * \brief f1ap messages handlers
+ * \author EURECOM/NTUST
+ * \date 2018
+ * \version 0.1
+ * \company Eurecom
+ * \email: navid.nikaein@eurecom.fr, bing-kai.hong@eurecom.fr
+ * \note
+ * \warning
+ */
+
+#include "f1ap_common.h"
+#include "f1ap_handlers.h"
+#include "f1ap_decoder.h"
+#include "f1ap_cu_interface_management.h"
+#include "f1ap_du_interface_management.h"
+#include "f1ap_cu_rrc_message_transfer.h"
+#include "f1ap_du_rrc_message_transfer.h"
+#include "f1ap_cu_ue_context_management.h"
+#include "f1ap_du_ue_context_management.h"
+
+extern f1ap_setup_req_t *f1ap_du_data_from_du;
+
+/* Handlers matrix. Only f1 related procedure present here */
+f1ap_message_decoded_callback f1ap_messages_callback[][3] = {
+  
+
+  { 0, 0, 0 }, /* Reset */
+  { CU_handle_F1_SETUP_REQUEST, DU_handle_F1_SETUP_RESPONSE, DU_handle_F1_SETUP_FAILURE }, /* F1Setup */
+  { 0, 0, 0 }, /* ErrorIndication */
+  { 0, 0, 0 }, /* gNBDUConfigurationUpdate */
+  { 0, 0, 0 }, /* gNBCUConfigurationUpdate */
+  { DU_handle_UE_CONTEXT_SETUP_REQUEST, CU_handle_UE_CONTEXT_SETUP_RESPONSE, 0 }, /* UEContextSetup */
+  { DU_handle_UE_CONTEXT_RELEASE_COMMAND, CU_handle_UE_CONTEXT_RELEASE_COMPLETE, 0 }, /* UEContextRelease */
+  { 0, 0, 0 }, /* UEContextModification */
+  { 0, 0, 0 }, /* UEContextModificationRequired */
+  { 0, 0, 0 }, /* UEMobilityCommand */
+  { CU_handle_UE_CONTEXT_RELEASE_REQUEST, 0, 0 }, /* UEContextReleaseRequest */
+  { CU_handle_INITIAL_UL_RRC_MESSAGE_TRANSFER, 0, 0 }, /* InitialULRRCMessageTransfer */
+  { DU_handle_DL_RRC_MESSAGE_TRANSFER, 0, 0 }, /* DLRRCMessageTransfer */
+  { CU_handle_UL_RRC_MESSAGE_TRANSFER, 0, 0 }, /* ULRRCMessageTransfer */
+  { 0, 0, 0 }, /* privateMessage */
+  { 0, 0, 0 }, /* UEInactivityNotification */
+  { 0, 0, 0 }, /* GNBDUResourceCoordination */
+  { 0, 0, 0 }, /* SystemInformationDeliveryCommand */
+  { 0, 0, 0 }, /* Paging */
+  { 0, 0, 0 }, /* Notify */
+  { 0, 0, 0 }, /* WriteReplaceWarning */
+  { 0, 0, 0 }, /* PWSCancel */
+  { 0, 0, 0 }, /* PWSRestartIndication */
+  { 0, 0, 0 }, /* PWSFailureIndication */
+};
+
+const char *f1ap_direction2String(int f1ap_dir) {
+static const char *f1ap_direction_String[] = {
+  "", /* Nothing */
+  "Initiating message", /* initiating message */
+  "Successfull outcome", /* successfull outcome */
+  "UnSuccessfull outcome", /* successfull outcome */
+};
+return(f1ap_direction_String[f1ap_dir]);
+}
+
+int f1ap_handle_message(instance_t instance, uint32_t assoc_id, int32_t stream,
+                            const uint8_t * const data, const uint32_t data_length)
+{
+  F1AP_F1AP_PDU_t pdu;
+  int ret;
+
+  DevAssert(data != NULL);
+
+  memset(&pdu, 0, sizeof(pdu));
+
+  if (f1ap_decode_pdu(&pdu, data, data_length) < 0) {
+    LOG_E(F1AP, "Failed to decode PDU\n");
+    return -1;
+  }
+
+  /* Checking procedure Code and direction of message */
+  if (pdu.choice.initiatingMessage->procedureCode > sizeof(f1ap_messages_callback) / (3 * sizeof(
+        f1ap_message_decoded_callback))
+      || (pdu.present > F1AP_F1AP_PDU_PR_unsuccessfulOutcome)) {
+    LOG_E(F1AP, "[SCTP %d] Either procedureCode %ld or direction %d exceed expected\n",
+               assoc_id, pdu.choice.initiatingMessage->procedureCode, pdu.present);
+    ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_F1AP_F1AP_PDU, &pdu);
+    return -1;
+  }
+
+  /* No handler present.
+   * This can mean not implemented or no procedure for eNB (wrong direction).
+   */
+  if (f1ap_messages_callback[pdu.choice.initiatingMessage->procedureCode][pdu.present - 1] == NULL) {
+    LOG_E(F1AP, "[SCTP %d] No handler for procedureCode %ld in %s\n",
+                assoc_id, pdu.choice.initiatingMessage->procedureCode,
+               f1ap_direction2String(pdu.present - 1));
+    ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_F1AP_F1AP_PDU, &pdu);
+    return -1;
+  }
+
+  /* Calling the right handler */
+  LOG_I(F1AP, "Calling handler with instance %d\n",instance);
+  ret = (*f1ap_messages_callback[pdu.choice.initiatingMessage->procedureCode][pdu.present - 1])
+        (instance, assoc_id, stream, &pdu);
+  ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_F1AP_F1AP_PDU, &pdu);
+  return ret;
+}
diff --git a/openair2/F1AP/f1ap_handlers.h b/openair2/F1AP/f1ap_handlers.h
new file mode 100644
index 0000000000000000000000000000000000000000..631249a324287607d7c2c3ea539f6aea85913a9d
--- /dev/null
+++ b/openair2/F1AP/f1ap_handlers.h
@@ -0,0 +1,39 @@
+/*
+ * 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
+ */
+
+/*! \file f1ap_handlers.h
+ * \brief f1ap messages handlers
+ * \author EURECOM/NTUST
+ * \date 2018
+ * \version 0.1
+ * \company Eurecom
+ * \email: navid.nikaein@eurecom.fr, bing-kai.hong@eurecom.fr
+ * \note
+ * \warning
+ */
+
+#ifndef F1AP_HANDLERS_H_
+#define F1AP_HANDLERS_H_
+
+int f1ap_handle_message(instance_t instance, uint32_t assoc_id, int32_t stream,
+                            const uint8_t * const data, const uint32_t data_length);
+
+#endif /* F1AP_HANDLERS_H_ */
diff --git a/openair2/F1AP/f1ap_itti_messaging.c b/openair2/F1AP/f1ap_itti_messaging.c
new file mode 100644
index 0000000000000000000000000000000000000000..fa8951536a913259553209491e3b137f6c50eb71
--- /dev/null
+++ b/openair2/F1AP/f1ap_itti_messaging.c
@@ -0,0 +1,73 @@
+/*
+ * 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
+ */
+
+#include "f1ap_common.h"
+#include "f1ap_itti_messaging.h"
+
+void cu_f1ap_itti_send_sctp_data_req(instance_t instance, int32_t assoc_id, uint8_t *buffer,
+                                      uint32_t buffer_length, uint16_t stream)
+{
+  MessageDef      *message_p;
+  sctp_data_req_t *sctp_data_req;
+
+  message_p = itti_alloc_new_message(TASK_CU_F1, SCTP_DATA_REQ);
+
+  sctp_data_req = &message_p->ittiMsg.sctp_data_req;
+
+  sctp_data_req->assoc_id      = assoc_id;
+  sctp_data_req->buffer        = buffer;
+  sctp_data_req->buffer_length = buffer_length;
+  sctp_data_req->stream        = stream;
+
+  itti_send_msg_to_task(TASK_SCTP, instance, message_p);
+}
+
+void du_f1ap_itti_send_sctp_data_req(instance_t instance, int32_t assoc_id, uint8_t *buffer,
+                                      uint32_t buffer_length, uint16_t stream)
+{
+  MessageDef      *message_p;
+  sctp_data_req_t *sctp_data_req;
+
+  message_p = itti_alloc_new_message(TASK_DU_F1, SCTP_DATA_REQ);
+
+  sctp_data_req = &message_p->ittiMsg.sctp_data_req;
+
+  sctp_data_req->assoc_id      = assoc_id;
+  sctp_data_req->buffer        = buffer;
+  sctp_data_req->buffer_length = buffer_length;
+  sctp_data_req->stream        = stream;
+
+  LOG_I(F1AP, "Sending ITTI message to SCTP Task\n");
+  itti_send_msg_to_task(TASK_SCTP, instance, message_p);
+}
+
+void f1ap_itti_send_sctp_close_association(instance_t instance, int32_t assoc_id)
+{
+  MessageDef               *message_p = NULL;
+  sctp_close_association_t *sctp_close_association_p = NULL;
+
+  message_p = itti_alloc_new_message(TASK_S1AP, SCTP_CLOSE_ASSOCIATION);
+  sctp_close_association_p = &message_p->ittiMsg.sctp_close_association;
+  sctp_close_association_p->assoc_id      = assoc_id;
+
+  itti_send_msg_to_task(TASK_SCTP, instance, message_p);
+}
+
diff --git a/openair2/F1AP/f1ap_itti_messaging.h b/openair2/F1AP/f1ap_itti_messaging.h
new file mode 100644
index 0000000000000000000000000000000000000000..66c59a72e72ee1f721aa7bd41b4b07e6c961073a
--- /dev/null
+++ b/openair2/F1AP/f1ap_itti_messaging.h
@@ -0,0 +1,35 @@
+/*
+ * 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
+ */
+
+#ifndef F1AP_ITTI_MESSAGING_H_
+#define F1AP_ITTI_MESSAGING_H_
+
+void cu_f1ap_itti_send_sctp_data_req(instance_t instance, int32_t assoc_id, uint8_t *buffer,
+                                      uint32_t buffer_length, uint16_t stream);
+
+void du_f1ap_itti_send_sctp_data_req(instance_t instance, int32_t assoc_id, uint8_t *buffer,
+                                      uint32_t buffer_length, uint16_t stream);
+
+void f1ap_eNB_itti_send_sctp_close_association(instance_t instance,
+    int32_t assoc_id);
+
+
+#endif /* F1AP_ITTI_MESSAGING_H_ */
diff --git a/openair2/F1AP/f1ap_messaging.c b/openair2/F1AP/f1ap_messaging.c
new file mode 100644
index 0000000000000000000000000000000000000000..fb189eaed3d28c9cc6c22c6bb7c8dd0110ab4814
--- /dev/null
+++ b/openair2/F1AP/f1ap_messaging.c
@@ -0,0 +1,66 @@
+/*
+ * 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
+ */
+
+/*! \file f1ap_messaging.c
+ * \brief f1ap procedures
+ * \author EURECOM/NTUST
+ * \date 2018
+ * \version 0.1
+ * \company Eurecom
+ * \email: navid.nikaein@eurecom.fr, bing-kai.hong@eurecom.fr
+ * \note
+ * \warning
+ */
+
+
+#include "f1ap_common.h"
+#include "f1ap_messaging.h"
+
+// void f1ap_send_sctp_data_req(instance_t instance, int32_t assoc_id, uint8_t *buffer,
+//                                       uint32_t buffer_length, uint16_t stream)
+// {
+//   MessageDef      *message_p;
+//   sctp_data_req_t *sctp_data_req;
+
+//   message_p = itti_alloc_new_message(TASK_F1AP, SCTP_DATA_REQ);
+
+//   sctp_data_req = &message_p->ittiMsg.sctp_data_req;
+
+//   sctp_data_req->assoc_id      = assoc_id;
+//   sctp_data_req->buffer        = buffer;
+//   sctp_data_req->buffer_length = buffer_length;
+//   sctp_data_req->stream        = stream;
+
+//   itti_send_msg_to_task(TASK_SCTP, instance, message_p);
+// }
+
+// void f1ap_send_sctp_close_association(instance_t instance, int32_t assoc_id)
+// {
+//   MessageDef               *message_p = NULL;
+//   sctp_close_association_t *sctp_close_association_p = NULL;
+
+//   message_p = itti_alloc_new_message(TASK_F1AP, SCTP_CLOSE_ASSOCIATION);
+//   sctp_close_association_p = &message_p->ittiMsg.sctp_close_association;
+//   sctp_close_association_p->assoc_id      = assoc_id;
+
+//   itti_send_msg_to_task(TASK_SCTP, instance, message_p);
+// }
+
diff --git a/openair2/F1AP/f1ap_messaging.h b/openair2/F1AP/f1ap_messaging.h
new file mode 100644
index 0000000000000000000000000000000000000000..9ad0388d0198179d164e0176b246aa98f154522d
--- /dev/null
+++ b/openair2/F1AP/f1ap_messaging.h
@@ -0,0 +1,44 @@
+/*
+ * 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
+ */
+
+/*! \file f1ap_messaging.h
+ * \brief f1ap procedures
+ * \author EURECOM/NTUST
+ * \date 2018
+ * \version 0.1
+ * \company Eurecom
+ * \email: navid.nikaein@eurecom.fr, bing-kai.hong@eurecom.fr
+ * \note
+ * \warning
+ */
+
+
+#ifndef F1AP_MESSAGING_H_
+#define F1AP_MESSAGING_H_
+
+void f1ap_send_sctp_data_req(instance_t instance, int32_t assoc_id, uint8_t *buffer,
+                                      uint32_t buffer_length, uint16_t stream);
+
+void f1ap_send_sctp_close_association(instance_t instance,
+    int32_t assoc_id);
+
+
+#endif /* F1AP_MESSAGING_H_ */
diff --git a/openair2/LAYER2/MAC/config.c b/openair2/LAYER2/MAC/config.c
index 312edea2c17b751f84d266bb3392c9475886ffe3..73d73c35566611e2da908b9f4d516e470fe22448 100644
--- a/openair2/LAYER2/MAC/config.c
+++ b/openair2/LAYER2/MAC/config.c
@@ -760,7 +760,7 @@ int rrc_mac_config_req_eNB(module_id_t Mod_idP,
 			   sib1_v13ext
 #endif
 			   ) {
-  
+
   int i;
 
   int UE_id = -1;
@@ -822,60 +822,42 @@ int rrc_mac_config_req_eNB(module_id_t Mod_idP,
       RC.mac[Mod_idP]->common_channels[CC_idP].sib1_v13ext = sib1_v13ext;
     }
 #endif
-    if (radioResourceConfigCommon != NULL) {
-      LOG_I(MAC, "[CONFIG]SIB2/3 Contents (partial)\n");
-      LOG_I(MAC, "[CONFIG]pusch_config_common.n_SB = %ld\n",
-	    radioResourceConfigCommon->
-	    pusch_ConfigCommon.pusch_ConfigBasic.n_SB);
-      LOG_I(MAC, "[CONFIG]pusch_config_common.hoppingMode = %ld\n",
-	    radioResourceConfigCommon->
-	    pusch_ConfigCommon.pusch_ConfigBasic.hoppingMode);
-      LOG_I(MAC,
-	    "[CONFIG]pusch_config_common.pusch_HoppingOffset = %ld\n",
-	    radioResourceConfigCommon->
-	    pusch_ConfigCommon.pusch_ConfigBasic.pusch_HoppingOffset);
-      LOG_I(MAC, "[CONFIG]pusch_config_common.enable64QAM = %d\n",
-	    radioResourceConfigCommon->
-	    pusch_ConfigCommon.pusch_ConfigBasic.enable64QAM);
-      LOG_I(MAC,
-	    "[CONFIG]pusch_config_common.groupHoppingEnabled = %d\n",
-	    radioResourceConfigCommon->
-	    pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.
-	    groupHoppingEnabled);
-      LOG_I(MAC,
-	    "[CONFIG]pusch_config_common.groupAssignmentPUSCH = %ld\n",
-	    radioResourceConfigCommon->
-	    pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.
-	    groupAssignmentPUSCH);
-      LOG_I(MAC,
-	    "[CONFIG]pusch_config_common.sequenceHoppingEnabled = %d\n",
-	    radioResourceConfigCommon->
-	    pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.
-	    sequenceHoppingEnabled);
-      LOG_I(MAC, "[CONFIG]pusch_config_common.cyclicShift  = %ld\n",
-	    radioResourceConfigCommon->
-	    pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.cyclicShift);
-
-      AssertFatal(radioResourceConfigCommon->
-		  rach_ConfigCommon.maxHARQ_Msg3Tx > 0,
-		  "radioResourceconfigCommon %d == 0\n",
-		  (int) radioResourceConfigCommon->rach_ConfigCommon.maxHARQ_Msg3Tx);
-
-      RC.mac[Mod_idP]->common_channels[CC_idP].radioResourceConfigCommon = radioResourceConfigCommon;
-      RC.mac[Mod_idP]->common_channels[CC_idP].radioResourceConfigCommon_BR = radioResourceConfigCommon_BR;
-      if (ul_CarrierFreq > 0) RC.mac[Mod_idP]->common_channels[CC_idP].ul_CarrierFreq        = ul_CarrierFreq;
-      if (ul_Bandwidth) 	RC.mac[Mod_idP]->common_channels[CC_idP].ul_Bandwidth        = *ul_Bandwidth;
-      else RC.mac[Mod_idP]->common_channels[CC_idP].ul_Bandwidth                             = RC.mac[Mod_idP]->common_channels[CC_idP].mib->message.dl_Bandwidth;
-
-      config_sib2(Mod_idP, CC_idP, radioResourceConfigCommon,
+    AssertFatal(radioResourceConfigCommon != NULL, "radioResourceConfigCommon is null\n");
+    LOG_I(MAC, "[CONFIG]SIB2/3 Contents (partial)\n");
+    LOG_I(MAC, "[CONFIG]pusch_config_common.n_SB = %ld\n",
+	        radioResourceConfigCommon->pusch_ConfigCommon.pusch_ConfigBasic.n_SB);
+    LOG_I(MAC, "[CONFIG]pusch_config_common.hoppingMode = %ld\n",
+	        radioResourceConfigCommon->pusch_ConfigCommon.pusch_ConfigBasic.hoppingMode);
+    LOG_I(MAC, "[CONFIG]pusch_config_common.pusch_HoppingOffset = %ld\n",
+          radioResourceConfigCommon->pusch_ConfigCommon.pusch_ConfigBasic.pusch_HoppingOffset);
+    LOG_I(MAC, "[CONFIG]pusch_config_common.enable64QAM = %d\n",
+          radioResourceConfigCommon->pusch_ConfigCommon.pusch_ConfigBasic.enable64QAM);
+    LOG_I(MAC, "[CONFIG]pusch_config_common.groupHoppingEnabled = %d\n",
+	        radioResourceConfigCommon->pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.groupHoppingEnabled);
+    LOG_I(MAC, "[CONFIG]pusch_config_common.groupAssignmentPUSCH = %ld\n",
+          radioResourceConfigCommon->pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.groupAssignmentPUSCH);
+    LOG_I(MAC, "[CONFIG]pusch_config_common.sequenceHoppingEnabled = %d\n",
+	        radioResourceConfigCommon->pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.sequenceHoppingEnabled);
+    LOG_I(MAC, "[CONFIG]pusch_config_common.cyclicShift  = %ld\n",
+          radioResourceConfigCommon->pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.cyclicShift);
+    
+    AssertFatal(radioResourceConfigCommon->rach_ConfigCommon.maxHARQ_Msg3Tx > 0,
+                "radioResourceconfigCommon %d == 0\n",
+		            (int) radioResourceConfigCommon->rach_ConfigCommon.maxHARQ_Msg3Tx);
+    
+    RC.mac[Mod_idP]->common_channels[CC_idP].radioResourceConfigCommon = radioResourceConfigCommon;
+    RC.mac[Mod_idP]->common_channels[CC_idP].radioResourceConfigCommon_BR = radioResourceConfigCommon_BR;
+    if (ul_CarrierFreq > 0) RC.mac[Mod_idP]->common_channels[CC_idP].ul_CarrierFreq = ul_CarrierFreq;
+    if (ul_Bandwidth) RC.mac[Mod_idP]->common_channels[CC_idP].ul_Bandwidth = *ul_Bandwidth;
+    else RC.mac[Mod_idP]->common_channels[CC_idP].ul_Bandwidth = RC.mac[Mod_idP]->common_channels[CC_idP].mib->message.dl_Bandwidth;
+    
+    config_sib2(Mod_idP, CC_idP, radioResourceConfigCommon,
 #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
-		  radioResourceConfigCommon_BR,
+                radioResourceConfigCommon_BR,
 #endif
-		  NULL, ul_Bandwidth, additionalSpectrumEmission,
-		  mbsfn_SubframeConfigList);
-
-
-    }
+                NULL, ul_Bandwidth, additionalSpectrumEmission,
+                mbsfn_SubframeConfigList);
+    
   } // mib != NULL
 
   if (mobilityControlInfo !=NULL){
@@ -896,7 +878,7 @@ int rrc_mac_config_req_eNB(module_id_t Mod_idP,
   if (logicalChannelConfig != NULL) {	// check for eMTC specific things
     UE_id = find_UE_id(Mod_idP, rntiP);
 
-    if (UE_id<0) { 
+    if (UE_id<0) {
       LOG_E(MAC,"Configuration received for unknown UE (%x), shouldn't happen\n",rntiP);
       return(-1);
     }
@@ -905,10 +887,10 @@ int rrc_mac_config_req_eNB(module_id_t Mod_idP,
 	UE_list->UE_template[CC_idP][UE_id].lcgidpriority[logicalChannelIdentity] =  logicalChannelConfig->ul_SpecificParameters->priority;
     } else UE_list->UE_template[CC_idP][UE_id].lcgidmap[logicalChannelIdentity]   =  0;
   }
-  
+
   if (physicalConfigDedicated != NULL) {
     UE_id = find_UE_id(Mod_idP, rntiP);
-    if (UE_id<0) { 
+    if (UE_id<0) {
       LOG_E(MAC,"Configuration received for unknown UE (%x), shouldn't happen\n",rntiP);
       return(-1);
     }
@@ -920,7 +902,7 @@ int rrc_mac_config_req_eNB(module_id_t Mod_idP,
 #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0))
 
   if (sCellToAddMod_r10 != NULL) {
-    if (UE_id<0) { 
+    if (UE_id<0) {
       LOG_E(MAC,"Configuration received for unknown UE (%x), shouldn't happen\n",rntiP);
       return(-1);
     }
diff --git a/openair2/LAYER2/MAC/defs.h b/openair2/LAYER2/MAC/defs.h
index 0ec0f6a723c97e1432a49981ca3c8bb4a9c964a2..2416fab7f1ce59e2666dea30692bd3b48b59ac24 100644
--- a/openair2/LAYER2/MAC/defs.h
+++ b/openair2/LAYER2/MAC/defs.h
@@ -132,7 +132,7 @@
 /*!\brief size of buffer status report table */
 #define BSR_TABLE_SIZE 64
 /*!\brief The power headroom reporting range is from -23 ...+40 dB and beyond, with step 1 */
-#define PHR_MAPPING_OFFSET 23  // if ( x>= -23 ) val = floor (x + 23) 
+#define PHR_MAPPING_OFFSET 23  // if ( x>= -23 ) val = floor (x + 23)
 /*!\brief maximum number of resource block groups */
 #define N_RBG_MAX 25 // for 20MHz channel BW
 /*!\brief minimum value for channel quality indicator */
@@ -140,9 +140,9 @@
 /*!\brief maximum value for channel quality indicator */
 #define MAX_CQI_VALUE  15
 /*!\briefmaximum number of supported bandwidth (1.4, 5, 10, 20 MHz) */
-#define MAX_SUPPORTED_BW  4  
+#define MAX_SUPPORTED_BW  4
 /*!\brief CQI values range from 1 to 15 (4 bits) */
-#define CQI_VALUE_RANGE 16 
+#define CQI_VALUE_RANGE 16
 
 /*!\brief value for indicating BSR Timer is not running */
 #define MAC_UE_BSR_TIMER_NOT_RUNNING   (0xFFFF)
@@ -157,16 +157,16 @@
 #define MIN_MAC_HDR_RLC_SIZE    (1 + MIN_RLC_PDU_SIZE)
 
 /*!\brief maximum number of slices / groups */
-#define MAX_NUM_SLICES 4 
+#define MAX_NUM_SLICES 4
 
-/* 
- * eNB part 
- */ 
+/*
+ * eNB part
+ */
 
 
-/* 
- * UE/ENB common part 
- */ 
+/*
+ * UE/ENB common part
+ */
 /*!\brief MAC header of Random Access Response for Random access preamble identifier (RAPID) */
 typedef struct {
   uint8_t RAPID:6;
@@ -306,18 +306,18 @@ typedef struct {
   uint8_t stop_sf_LSB:8;
 } __attribute__((__packed__))MSI_ELEMENT;
 #endif
-/*! \brief Values of CCCH LCID for DLSCH */ 
+/*! \brief Values of CCCH LCID for DLSCH */
 #define CCCH_LCHANID 0
 /*!\brief Values of BCCH logical channel (fake)*/
-#define BCCH 3  // SI 
+#define BCCH 3  // SI
 /*!\brief Values of PCCH logical channel (fake)*/
-#define PCCH 4  // Paging 
+#define PCCH 4  // Paging
 /*!\brief Values of PCCH logical channel (fake) */
-#define MIBCH 5  // MIB 
+#define MIBCH 5  // MIB
 /*!\brief Values of BCCH SIB1_BR logical channel (fake) */
-#define BCCH_SIB1_BR 6  // SIB1_BR 
+#define BCCH_SIB1_BR 6  // SIB1_BR
 /*!\brief Values of BCCH SIB_BR logical channel (fake) */
-#define BCCH_SI_BR 7  // SI-BR 
+#define BCCH_SI_BR 7  // SI-BR
 /*!\brief Value of CCCH / SRB0 logical channel */
 #define CCCH 0  // srb0
 /*!\brief DCCH / SRB1 logical channel */
@@ -327,9 +327,9 @@ typedef struct {
 /*!\brief DTCH DRB1  logical channel */
 #define DTCH 3 // LCID
 /*!\brief MCCH logical channel */
-#define MCCH 4 
+#define MCCH 4
 /*!\brief MTCH logical channel */
-#define MTCH 1 
+#define MTCH 1
 // DLSCH LCHAN ID
 /*!\brief LCID of UE contention resolution identity for DLSCH*/
 #define UE_CONT_RES 28
@@ -441,20 +441,20 @@ typedef struct {
 } eNB_DLSCH_INFO;
 /*! \brief eNB overall statistics */
 typedef struct {
-  /// num BCCH PDU per CC 
+  /// num BCCH PDU per CC
   uint32_t total_num_bcch_pdu;
-  /// BCCH buffer size  
+  /// BCCH buffer size
   uint32_t bcch_buffer;
-  /// total BCCH buffer size  
+  /// total BCCH buffer size
   uint32_t total_bcch_buffer;
   /// BCCH MCS
   uint32_t bcch_mcs;
 
-  /// num CCCH PDU per CC 
+  /// num CCCH PDU per CC
   uint32_t total_num_ccch_pdu;
-  /// BCCH buffer size  
+  /// BCCH buffer size
   uint32_t ccch_buffer;
-  /// total BCCH buffer size  
+  /// total BCCH buffer size
   uint32_t total_ccch_buffer;
   /// BCCH MCS
   uint32_t ccch_mcs;
@@ -481,22 +481,22 @@ typedef struct {
   uint32_t total_dlsch_bytes_tx;
   //
   uint32_t total_dlsch_pdus_tx;
-  
+
   // here for RX
   //
   uint32_t ulsch_bitrate;
   //
   uint32_t ulsch_bytes_rx;
   //
-  uint64_t ulsch_pdus_rx; 
+  uint64_t ulsch_pdus_rx;
 
   uint32_t total_ulsch_bitrate;
   //
   uint32_t total_ulsch_bytes_rx;
   //
   uint32_t total_ulsch_pdus_rx;
-  
-  
+
+
   /// MAC agent-related stats
   /// total number of scheduling decisions
   int sched_decisions;
@@ -600,9 +600,9 @@ typedef struct {
   uint32_t rbs_used_retx_rx;
   ///  total rb used for a new uplink transmission
   uint32_t total_rbs_used_rx;
-  /// normalized rx power 
+  /// normalized rx power
   int32_t      normalized_rx_power;
-   /// target rx power 
+   /// target rx power
   int32_t    target_rx_power;
 
   /// num rx pdu
@@ -613,7 +613,7 @@ typedef struct {
   //  uint32_t tti_goodput[NB_RB_MAX];
   /// errors
   uint32_t num_errors_rx;
-  
+
   uint64_t overhead_bytes_rx;
   /// headers+ CE +  padding bytes for a MAC PDU
   uint64_t total_overhead_bytes_rx;
@@ -732,12 +732,12 @@ typedef struct {
   uint32_t dl_buffer_head_sdu_creation_time[MAX_NUM_LCID];
   /// maximum creation time of the downlink buffer head across all LCID
   uint32_t  dl_buffer_head_sdu_creation_time_max;
-  /// a flag indicating that the downlink head SDU is segmented  
+  /// a flag indicating that the downlink head SDU is segmented
   uint8_t    dl_buffer_head_sdu_is_segmented[MAX_NUM_LCID];
   /// size of remaining size to send for the downlink head SDU
   uint32_t dl_buffer_head_sdu_remaining_size_to_send[MAX_NUM_LCID];
 
-  /// total uplink buffer size 
+  /// total uplink buffer size
   uint32_t ul_total_buffer;
   /// uplink buffer creation time for each LCID
   uint32_t ul_buffer_creation_time[MAX_NUM_LCGID];
@@ -797,7 +797,7 @@ typedef struct {
   uint16_t priority[MAX_NUM_LCID];
 
   // resource scheduling information
-  
+
   /// Current DL harq round per harq_pid on each CC
   uint8_t       round[MAX_NUM_CCs][10];
   /// Current Active TBs per harq_pid on each CC
@@ -813,7 +813,7 @@ typedef struct {
   int32_t       context_active_timer;
   int32_t       cqi_req_timer;
   int32_t       ul_inactivity_timer;
-  int32_t       ul_failure_timer; 
+  int32_t       ul_failure_timer;
   int32_t       ul_scheduled;
   int32_t       ra_pdcch_order_sent;
   int32_t       ul_out_of_sync;
@@ -943,25 +943,25 @@ typedef struct {
   uint8_t sb_size;
   uint8_t nb_active_sb;
 } SBMAP_CONF;
-/*! \brief UE list used by eNB to order UEs/CC for scheduling*/ 
+/*! \brief UE list used by eNB to order UEs/CC for scheduling*/
 typedef struct {
   /// Dedicated information for UEs
   struct PhysicalConfigDedicated  *physicalConfigDedicated[MAX_NUM_CCs][NUMBER_OF_UE_MAX];
-  /// DLSCH pdu 
+  /// DLSCH pdu
   DLSCH_PDU DLSCH_pdu[MAX_NUM_CCs][2][NUMBER_OF_UE_MAX];
   /// DCI template and MAC connection parameters for UEs
   UE_TEMPLATE UE_template[MAX_NUM_CCs][NUMBER_OF_UE_MAX];
   /// DCI template and MAC connection for RA processes
   int pCC_id[NUMBER_OF_UE_MAX];
-  /// sorted downlink component carrier for the scheduler 
+  /// sorted downlink component carrier for the scheduler
   int ordered_CCids[MAX_NUM_CCs][NUMBER_OF_UE_MAX];
-  /// number of downlink active component carrier 
+  /// number of downlink active component carrier
   int numactiveCCs[NUMBER_OF_UE_MAX];
-  /// sorted uplink component carrier for the scheduler 
+  /// sorted uplink component carrier for the scheduler
   int ordered_ULCCids[MAX_NUM_CCs][NUMBER_OF_UE_MAX];
-  /// number of uplink active component carrier 
+  /// number of uplink active component carrier
   int numactiveULCCs[NUMBER_OF_UE_MAX];
-  /// number of downlink active component carrier 
+  /// number of downlink active component carrier
   uint8_t dl_CC_bitmap[NUMBER_OF_UE_MAX];
   /// eNB to UE statistics
   eNB_UE_STATS eNB_UE_stats[MAX_NUM_CCs][NUMBER_OF_UE_MAX];
@@ -976,7 +976,7 @@ typedef struct {
   boolean_t active[NUMBER_OF_UE_MAX];
 } UE_list_t;
 
-/*! \brief eNB common channels */ 
+/*! \brief eNB common channels */
 typedef struct {
   int                              physCellId;
   int                              p_eNB;
@@ -986,7 +986,7 @@ typedef struct {
   BCCH_BCH_Message_t               *mib;
   RadioResourceConfigCommonSIB_t   *radioResourceConfigCommon;
 #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
-  RadioResourceConfigCommonSIB_t   *radioResourceConfigCommon_BR;  
+  RadioResourceConfigCommonSIB_t   *radioResourceConfigCommon_BR;
 #endif
   TDD_Config_t                     *tdd_Config;
   SchedulingInfoList_t             *schedulingInfoList;
@@ -1043,7 +1043,7 @@ typedef struct {
   BCCH_PDU BCCH_BR_pdu[20];
 #endif
 } COMMON_channels_t;
-/*! \brief top level eNB MAC structure */ 
+/*! \brief top level eNB MAC structure */
 typedef struct eNB_MAC_INST_s {
   /// Ethernet parameters for northbound midhaul interface
   eth_params_t         eth_params_n;
@@ -1076,7 +1076,7 @@ typedef struct eNB_MAC_INST_s {
   nfapi_ul_config_request_t UL_req[MAX_NUM_CCs];
   /// NFAPI "Temporary" UL Config Request Structure, holds future UL_config requests
   nfapi_ul_config_request_t UL_req_tmp[MAX_NUM_CCs][10];
-  /// Preallocated HI_DCI0 pdu list 
+  /// Preallocated HI_DCI0 pdu list
   nfapi_hi_dci0_request_pdu_t hi_dci0_pdu_list[MAX_NUM_CCs][MAX_NUM_HI_DCI0_PDU];
   /// NFAPI HI/DCI0 Config Request Structure
   nfapi_hi_dci0_request_t HI_DCI0_req[MAX_NUM_CCs];
@@ -1097,29 +1097,29 @@ typedef struct eNB_MAC_INST_s {
   /// eNB stats
   eNB_STATS eNB_stats[MAX_NUM_CCs];
   // MAC function execution peformance profiler
-  /// processing time of eNB scheduler 
+  /// processing time of eNB scheduler
   time_stats_t eNB_scheduler;
-  /// processing time of eNB scheduler for SI 
+  /// processing time of eNB scheduler for SI
   time_stats_t schedule_si;
   /// processing time of eNB scheduler for Random access
   time_stats_t schedule_ra;
-  /// processing time of eNB ULSCH scheduler 
+  /// processing time of eNB ULSCH scheduler
   time_stats_t schedule_ulsch;
   /// processing time of eNB DCI generation
   time_stats_t fill_DLSCH_dci;
   /// processing time of eNB MAC preprocessor
   time_stats_t schedule_dlsch_preprocessor;
-  /// processing time of eNB DLSCH scheduler 
+  /// processing time of eNB DLSCH scheduler
   time_stats_t schedule_dlsch; // include rlc_data_req + MAC header + preprocessor
-  /// processing time of eNB MCH scheduler 
+  /// processing time of eNB MCH scheduler
   time_stats_t schedule_mch;
   /// processing time of eNB ULSCH reception
   time_stats_t rx_ulsch_sdu; // include rlc_data_ind
 } eNB_MAC_INST;
 
-/* 
- * UE part 
- */ 
+/*
+ * UE part
+ */
 
 typedef enum {
   TYPE0,
@@ -1311,25 +1311,25 @@ typedef struct {
   uint8_t msi_status;// could be an array if there are >1 MCH in one MBSFN area
 #endif
   //#ifdef CBA
-  /// CBA RNTI for each group 
+  /// CBA RNTI for each group
   uint16_t cba_rnti[NUM_MAX_CBA_GROUP];
-  /// last SFN for CBA channel access 
+  /// last SFN for CBA channel access
   uint8_t cba_last_access[NUM_MAX_CBA_GROUP];
   //#endif
-  /// total UE scheduler processing time 
+  /// total UE scheduler processing time
   time_stats_t ue_scheduler; // total
-  /// UE ULSCH tx  processing time inlcuding RLC interface (rlc_data_req) and mac header generation 
-  time_stats_t tx_ulsch_sdu;  
+  /// UE ULSCH tx  processing time inlcuding RLC interface (rlc_data_req) and mac header generation
+  time_stats_t tx_ulsch_sdu;
   /// UE DLSCH rx  processing time inlcuding RLC interface (mac_rrc_data_ind or mac_rlc_status_ind+mac_rlc_data_ind) and mac header parser
-  time_stats_t rx_dlsch_sdu ; 
-  /// UE query for MCH subframe processing time 
+  time_stats_t rx_dlsch_sdu ;
+  /// UE query for MCH subframe processing time
   time_stats_t ue_query_mch;
-  /// UE MCH rx processing time 
+  /// UE MCH rx processing time
   time_stats_t rx_mch_sdu;
-  /// UE BCCH rx processing time including RLC interface (mac_rrc_data_ind) 
-  time_stats_t rx_si; 
-  /// UE PCCH rx processing time including RLC interface (mac_rrc_data_ind) 
-  time_stats_t rx_p; 
+  /// UE BCCH rx processing time including RLC interface (mac_rrc_data_ind)
+  time_stats_t rx_si;
+  /// UE PCCH rx processing time including RLC interface (mac_rrc_data_ind)
+  time_stats_t rx_p;
 } UE_MAC_INST;
 /*! \brief ID of the neighboring cells used for HO*/
 typedef struct {
@@ -1340,6 +1340,3 @@ typedef struct {
 #include "proto.h"
 /*@}*/
 #endif /*__LAYER2_MAC_DEFS_H__ */
-
-
-
diff --git a/openair2/LAYER2/MAC/eNB_scheduler.c b/openair2/LAYER2/MAC/eNB_scheduler.c
index 42f09dc90f66d1779d39b99e7b02cd9b98cfa761..ab2856c40ce8c8d993c9fed51bbef4bea47ac980 100644
--- a/openair2/LAYER2/MAC/eNB_scheduler.c
+++ b/openair2/LAYER2/MAC/eNB_scheduler.c
@@ -404,20 +404,23 @@ check_ul_failure(module_id_t module_idP, int CC_id, int UE_id,
     // check threshold
     if (UE_list->UE_sched_ctrl[UE_id].ul_failure_timer > 4000) {
       // note: probably ul_failure_timer should be less than UE radio link failure time(see T310/N310/N311)
-      // inform RRC of failure and clear timer
-      LOG_I(MAC,
-	    "UE %d rnti %x: UL Failure after repeated PDCCH orders: Triggering RRC \n",
-	    UE_id, rnti);
-      mac_eNB_rrc_ul_failure(module_idP, CC_id, frameP, subframeP,rnti);
+      if (NODE_IS_DU(RC.rrc[module_idP]->node_type)) {
+        MessageDef *m = itti_alloc_new_message(TASK_MAC_ENB, F1AP_UE_CONTEXT_RELEASE_REQ);
+        F1AP_UE_CONTEXT_RELEASE_REQ(m).rnti = rnti;
+        F1AP_UE_CONTEXT_RELEASE_REQ(m).cause = F1AP_CAUSE_RADIO_NETWORK;
+        F1AP_UE_CONTEXT_RELEASE_REQ(m).cause_value = 1; // 1 = F1AP_CauseRadioNetwork_rl_failure
+        F1AP_UE_CONTEXT_RELEASE_REQ(m).rrc_container = NULL;
+        F1AP_UE_CONTEXT_RELEASE_REQ(m).rrc_container_length = 0;
+        itti_send_msg_to_task(TASK_DU_F1, module_idP, m);
+      } else {
+        // inform RRC of failure and clear timer
+        LOG_I(MAC,
+        "UE %d rnti %x: UL Failure after repeated PDCCH orders: Triggering RRC \n",
+        UE_id, rnti);
+        mac_eNB_rrc_ul_failure(module_idP, CC_id, frameP, subframeP,rnti);
+      }
       UE_list->UE_sched_ctrl[UE_id].ul_failure_timer = 0;
       UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync   = 1;
-
-      //Inform the controller about the UE deactivation. Should be moved to RRC agent in the future
-      if (rrc_agent_registered[module_idP]) {
-        LOG_W(MAC, "notify flexran Agent of UE state change\n");
-        agent_rrc_xface[module_idP]->flexran_agent_notify_ue_state_change(module_idP,
-            rnti, PROTOCOL__FLEX_UE_STATE_CHANGE_TYPE__FLUESC_DEACTIVATED);
-      }
     }
   }				// ul_failure_timer>0
 }
@@ -695,16 +698,13 @@ eNB_dlsch_ulsch_scheduler(module_id_t module_idP, frame_t frameP,
     schedule_ue_spec_phy_test(module_idP,frameP,subframeP,mbsfn_status);
   }
 
-  if (RC.flexran[module_idP]->enabled)
-    flexran_agent_send_update_stats(module_idP);
-  
   // Allocate CCEs for good after scheduling is done
   for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
     if(cc[CC_id].tdd_Config == NULL || !(is_UL_sf(&cc[CC_id],subframeP)))
       allocate_CCEs(module_idP, CC_id, frameP, subframeP, 2);
   }
 
-  if (mac_agent_registered[module_idP] && subframeP == 9) {
+  if (flexran_agent_get_mac_xface(module_idP) && subframeP == 9) {
     flexran_agent_slice_update(module_idP);
   }
 
diff --git a/openair2/LAYER2/MAC/eNB_scheduler_RA.c b/openair2/LAYER2/MAC/eNB_scheduler_RA.c
index 2ebb45e68ec2e68aeb66f68b91c01bc47bdedb96..79d791c55850a39e64251282babc25ae94dabb91 100644
--- a/openair2/LAYER2/MAC/eNB_scheduler_RA.c
+++ b/openair2/LAYER2/MAC/eNB_scheduler_RA.c
@@ -153,7 +153,7 @@ add_msg3(module_id_t module_idP, int CC_id, RA_t * ra, frame_t frameP,
     ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.repetition_number = 1;
     ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.initial_transmission_sf_io = (ra->Msg3_frame * 10) + ra->Msg3_subframe;
     ul_req_body->number_of_pdus++;
-  }                             //  if (ra->rach_resource_type>0) {         
+  }                             //  if (ra->rach_resource_type>0) {
   else
 #endif
     {
@@ -252,7 +252,7 @@ void generate_Msg2(module_id_t module_idP,
 {
   eNB_MAC_INST *mac = RC.mac[module_idP];
   COMMON_channels_t *cc = mac->common_channels;
-  
+
   uint8_t *vrb_map = NULL;
   int first_rb = 0;
   int N_RB_DL = 0;
@@ -260,25 +260,25 @@ void generate_Msg2(module_id_t module_idP,
   nfapi_dl_config_request_pdu_t *dl_config_pdu = NULL;
   nfapi_tx_request_pdu_t *TX_req = NULL;
   nfapi_dl_config_request_body_t *dl_req_body = NULL;
-  
+
   vrb_map = cc[CC_idP].vrb_map;
   dl_req_body = &mac->DL_req[CC_idP].dl_config_request_body;
   dl_config_pdu = &dl_req_body->dl_config_pdu_list[dl_req_body->number_pdu];
   N_RB_DL = to_prb(cc[CC_idP].mib->message.dl_Bandwidth);
-  
+
 #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
-  int rmax = 0;
-  int rep = 0;
-  int reps = 0;
-  int num_nb = 0;
+  int             rmax = 0;
+  int             rep = 0;
+  int             reps = 0;
+  int             num_nb = 0;
 
   first_rb = 0;
   struct LTE_PRACH_ConfigSIB_v1310 *ext4_prach = NULL;
   LTE_PRACH_ParametersListCE_r13_t *prach_ParametersListCE_r13 = NULL;
   LTE_PRACH_ParametersCE_r13_t *p[4] = { NULL, NULL, NULL, NULL };
 
-  uint16_t absSF = (10 * frameP) + subframeP;
-  uint16_t absSF_Msg2 = (10 * ra->Msg2_frame) + ra->Msg2_subframe;
+  uint16_t        absSF = (10 * frameP) + subframeP;
+  uint16_t        absSF_Msg2 = (10 * ra->Msg2_frame) + ra->Msg2_subframe;
 
   if (absSF > absSF_Msg2) {
     return; // we're not ready yet
@@ -289,18 +289,18 @@ void generate_Msg2(module_id_t module_idP,
     prach_ParametersListCE_r13 = &ext4_prach->prach_ParametersListCE_r13;
 
     switch (prach_ParametersListCE_r13->list.count) {
-      case 4:
-        p[3] = prach_ParametersListCE_r13->list.array[3];
-      case 3:
-        p[2] = prach_ParametersListCE_r13->list.array[2];
-      case 2:
-        p[1] = prach_ParametersListCE_r13->list.array[1];
-      case 1:
-        p[0] = prach_ParametersListCE_r13->list.array[0];
-        break;
-      default:
-        AssertFatal (1 == 0, "Illegal count for prach_ParametersListCE_r13 %d\n", (int) prach_ParametersListCE_r13->list.count);
-        break;
+    case 4:
+      p[3] = prach_ParametersListCE_r13->list.array[3];
+    case 3:
+      p[2] = prach_ParametersListCE_r13->list.array[2];
+    case 2:
+      p[1] = prach_ParametersListCE_r13->list.array[1];
+    case 1:
+      p[0] = prach_ParametersListCE_r13->list.array[0];
+      break;
+    default:
+      AssertFatal (1 == 0, "Illegal count for prach_ParametersListCE_r13 %d\n", (int) prach_ParametersListCE_r13->list.count);
+      break;
     }
   }
 
@@ -348,7 +348,7 @@ void generate_Msg2(module_id_t module_idP,
       dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.mpdcch_narrow_band = ra->msg2_narrowband;
       dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.number_of_prb_pairs = 6;
       dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.resource_block_assignment = 0; // Note: this can be dynamic
-      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.mpdcch_tansmission_type = 1;   // imposed (9.1.5 in 213) for Type 2 Common search space  
+      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.mpdcch_tansmission_type = 1;   // imposed (9.1.5 in 213) for Type 2 Common search space
       
       AssertFatal (cc[CC_idP].sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13 != NULL, "cc[CC_idP].sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13 is null\n");
 
@@ -396,15 +396,15 @@ void generate_Msg2(module_id_t module_idP,
 
     if (ra->msg2_mpdcch_repetition_cnt > 0) {  // we're in a stream of repetitions
       if ((ra->msg2_mpdcch_repetition_cnt == reps) && (ra->msg2_mpdcch_done == 0)) {  // this is the last mpdcch repetition
-	      ra->msg2_mpdcch_done = 1;
+	ra->msg2_mpdcch_done = 1;
 
-        if (cc[CC_idP].tdd_Config == NULL) { // FDD case
+        if (cc[CC_idP].tdd_Config == NULL) {    // FDD case
           // wait 2 subframes for PDSCH transmission
           if (subframeP > 7)
             ra->Msg2_frame = (frameP + 1) & 1023;
           else
             ra->Msg2_frame = frameP;
-            ra->Msg2_subframe = (subframeP + 2) % 10; // +2 is the "n+x" from Section 7.1.11  in 36.213
+          ra->Msg2_subframe = (subframeP + 2) % 10;    // +2 is the "n+x" from Section 7.1.11  in 36.213
           
           LOG_D(MAC, "[eNB %d][RAPROC] Frame %d, Subframe %d : In generate_Msg2, programmed Msg2 for %d.%d\n", 
                 module_idP, 
@@ -441,11 +441,11 @@ void generate_Msg2(module_id_t module_idP,
         dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index = mac->pdu_index[CC_idP];
         dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.rnti = ra->RA_rnti;
         dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type = 2;
-        dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.virtual_resource_block_assignment_flag = 0; // localized
+        dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.virtual_resource_block_assignment_flag = 0;     // localized
         dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_block_coding = getRIV(N_RB_DL, first_rb, 6);
         dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.modulation = 2; // QPSK
         dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.redundancy_version = 0;
-        dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_blocks = 1; // first block
+        dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_blocks = 1;   // first block
         dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_block_to_codeword_swap_flag = 0;
         dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_scheme = (cc[CC_idP].p_eNB == 1) ? 0 : 1;
         dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_layers = 1;
@@ -459,14 +459,14 @@ void generate_Msg2(module_id_t module_idP,
         dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_mode = (cc[CC_idP].p_eNB == 1) ? 1 : 2;
         dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_prb_per_subband = 1;
         dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_vector = 1;
-        //      dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.bf_vector                    = ; 
+        //      dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.bf_vector                    = ;
 
         /* Rel10 fields */
         dl_config_pdu->dlsch_pdu.dlsch_pdu_rel10.pdsch_start = cc[CC_idP].sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13->startSymbolBR_r13;
 
         /* Rel13 fields */
         dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.ue_type = (ra->rach_resource_type < 3) ? 1 : 2;;
-        dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.pdsch_payload_type = 2; // not SI message
+        dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.pdsch_payload_type = 2;        // not SI message
         dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.initial_transmission_sf_io = (10 * frameP) + subframeP;
         dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.drms_table_flag = 0;
         dl_req_body->number_pdu++;
@@ -477,7 +477,7 @@ void generate_Msg2(module_id_t module_idP,
         get_Msg3alloc (&cc[CC_idP], subframeP, frameP, &ra->Msg3_frame, &ra->Msg3_subframe);
         add_msg3 (module_idP, CC_idP, ra, frameP, subframeP);
 
-	      ra->state = WAITMSG3;
+	ra->state = WAITMSG3;
 
         /* DL request */
         LOG_D(MAC, "[eNB %d][RAPROC] Frame %d, Subframe %d : In generate_Msg2, Programming TX Req\n", 
@@ -487,7 +487,7 @@ void generate_Msg2(module_id_t module_idP,
 
         mac->TX_req[CC_idP].sfn_sf = (frameP << 4) + subframeP;
         TX_req = &mac->TX_req[CC_idP].tx_request_body.tx_pdu_list[mac->TX_req[CC_idP].tx_request_body.number_of_pdus];
-        TX_req->pdu_length = 7; // This should be changed if we have more than 1 preamble 
+        TX_req->pdu_length = 7; // This should be changed if we have more than 1 preamble
         TX_req->pdu_index = mac->pdu_index[CC_idP]++;
         TX_req->num_segments = 1;
         TX_req->segments[0].segment_length = 7;
@@ -618,7 +618,7 @@ generate_Msg4(module_id_t module_idP,
 	            sub_frame_t subframeP, 
               RA_t * ra)
 //------------------------------------------------------------------------------
-{  
+{
   eNB_MAC_INST *mac = RC.mac[module_idP];
   COMMON_channels_t *cc = mac->common_channels;
   UE_list_t *UE_list = &(mac->UE_list);
@@ -633,7 +633,7 @@ generate_Msg4(module_id_t module_idP,
   uint8_t lcid = 0;
   uint8_t offset = 0;
   uint8_t *vrb_map = NULL;
-  
+
   nfapi_dl_config_request_pdu_t   *dl_config_pdu = NULL;
   nfapi_ul_config_request_pdu_t   *ul_config_pdu = NULL;
   nfapi_tx_request_pdu_t          *TX_req = NULL;
@@ -643,9 +643,9 @@ generate_Msg4(module_id_t module_idP,
   nfapi_ul_config_request_body_t *ul_req_body = NULL;
 
 #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
-  int rmax = 0;
-  int rep = 0;
-  int reps = 0;
+  int             rmax = 0;
+  int             rep = 0;
+  int             reps = 0;
 
   first_rb = 0;
 
@@ -672,29 +672,29 @@ generate_Msg4(module_id_t module_idP,
     AssertFatal (prach_ParametersListCE_r13->list.count == pucch_N1PUCCH_AN_InfoList_r13->list.count, "prach_ParametersListCE_r13->list.count!= pucch_N1PUCCH_AN_InfoList_r13->list.count\n");
 
     switch (prach_ParametersListCE_r13->list.count) {
-      case 4:
-        p[3] = prach_ParametersListCE_r13->list.array[3];
-        n1pucchan[3] = *pucch_N1PUCCH_AN_InfoList_r13->list.array[3];
+    case 4:
+      p[3] = prach_ParametersListCE_r13->list.array[3];
+      n1pucchan[3] = *pucch_N1PUCCH_AN_InfoList_r13->list.array[3];
         AssertFatal(ext4_pucch->pucch_NumRepetitionCE_Msg4_Level3_r13 != NULL, "pucch_NumRepetitionCE_Msg4_Level3 shouldn't be NULL\n");
-        pucchreps[3] = (int) (4 << *ext4_pucch->pucch_NumRepetitionCE_Msg4_Level3_r13);
+      pucchreps[3] = (int) (4 << *ext4_pucch->pucch_NumRepetitionCE_Msg4_Level3_r13);
 
-      case 3:
-        p[2] = prach_ParametersListCE_r13->list.array[2];
-        n1pucchan[2] = *pucch_N1PUCCH_AN_InfoList_r13->list.array[2];
+    case 3:
+      p[2] = prach_ParametersListCE_r13->list.array[2];
+      n1pucchan[2] = *pucch_N1PUCCH_AN_InfoList_r13->list.array[2];
         AssertFatal(ext4_pucch->pucch_NumRepetitionCE_Msg4_Level2_r13 != NULL, "pucch_NumRepetitionCE_Msg4_Level2 shouldn't be NULL\n");
-        pucchreps[2] = (int) (4 << *ext4_pucch->pucch_NumRepetitionCE_Msg4_Level2_r13);
-      case 2:
-        p[1] = prach_ParametersListCE_r13->list.array[1];
-        n1pucchan[1] = *pucch_N1PUCCH_AN_InfoList_r13->list.array[1];
+      pucchreps[2] = (int) (4 << *ext4_pucch->pucch_NumRepetitionCE_Msg4_Level2_r13);
+    case 2:
+      p[1] = prach_ParametersListCE_r13->list.array[1];
+      n1pucchan[1] = *pucch_N1PUCCH_AN_InfoList_r13->list.array[1];
         AssertFatal(ext4_pucch->pucch_NumRepetitionCE_Msg4_Level1_r13 != NULL, "pucch_NumRepetitionCE_Msg4_Level1 shouldn't be NULL\n");
-        pucchreps[1] = (int) (1 << *ext4_pucch->pucch_NumRepetitionCE_Msg4_Level1_r13);
-      case 1:
-        p[0] = prach_ParametersListCE_r13->list.array[0];
-        n1pucchan[0] = *pucch_N1PUCCH_AN_InfoList_r13->list.array[0];
+      pucchreps[1] = (int) (1 << *ext4_pucch->pucch_NumRepetitionCE_Msg4_Level1_r13);
+    case 1:
+      p[0] = prach_ParametersListCE_r13->list.array[0];
+      n1pucchan[0] = *pucch_N1PUCCH_AN_InfoList_r13->list.array[0];
         AssertFatal(ext4_pucch->pucch_NumRepetitionCE_Msg4_Level0_r13 != NULL, "pucch_NumRepetitionCE_Msg4_Level0 shouldn't be NULL\n");
-        pucchreps[0] = (int) (1 << *ext4_pucch->pucch_NumRepetitionCE_Msg4_Level0_r13);
-        break;
-      default:
+      pucchreps[0] = (int) (1 << *ext4_pucch->pucch_NumRepetitionCE_Msg4_Level0_r13);
+      break;
+    default:
         AssertFatal(1 == 0, "Illegal count for prach_ParametersListCE_r13 %d\n", prach_ParametersListCE_r13->list.count);
     }
   }
@@ -754,7 +754,7 @@ generate_Msg4(module_id_t module_idP,
 
     // rmax from SIB2 information
     rmax = 1<<p[ra->rach_resource_type - 1]->mpdcch_NumRepetition_RA_r13;
-    
+
 
     // choose r3 by default for Msg4 (this is ok from table 9.1.5-3 for rmax = >=4, if we choose rmax <4 it has to be less
     rep = 0;
@@ -765,14 +765,15 @@ generate_Msg4(module_id_t module_idP,
 
     if ((ra->msg4_mpdcch_repetition_cnt == 0) && (mpdcch_sf_condition (mac, CC_idP, frameP, subframeP, rmax, TYPE2, -1) > 0)) {
       // Get RRCConnectionSetup for Piggyback
-      ra->msg4_rrc_sdu_length = mac_rrc_data_req (module_idP, CC_idP, frameP, CCCH, 1,       // 1 transport block
-							   &cc[CC_idP].CCCH_pdu.payload[0], 0);     // not used in this case
-      
+      ra->msg4_rrc_sdu_length = mac_rrc_data_req (module_idP, CC_idP, frameP, CCCH,
+                                                  UE_RNTI(module_idP, UE_id), 1,        // 1 transport block
+                                                  &cc[CC_idP].CCCH_pdu.payload[0], 0);  // not used in this case
+
       AssertFatal (ra->msg4_rrc_sdu_length > 0, "[MAC][eNB Scheduler] CCCH not allocated\n");
-      
-      
+
+
       LOG_D (MAC, "[eNB %d][RAPROC] CC_id %d Frame %d, subframeP %d: UE_id %d, rrc_sdu_length %d, dl_req->num_pdu %d\n", module_idP, CC_idP, frameP, subframeP, UE_id, ra->msg4_rrc_sdu_length,dl_req_body->number_pdu);
-      
+
       // MPDCCH configuration for Msg4
       ra->msg4_mpdcch_done=0;
       memset ((void *) dl_config_pdu, 0, sizeof (nfapi_dl_config_request_pdu_t));
@@ -782,7 +783,7 @@ generate_Msg4(module_id_t module_idP,
       dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.mpdcch_narrow_band = ra->msg2_narrowband;
       dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.number_of_prb_pairs = 6;
       dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.resource_block_assignment = 0; // Note: this can be dynamic
-      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.mpdcch_tansmission_type = 1;   // imposed (9.1.5 in 213) for Type 2 Common search space  
+      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.mpdcch_tansmission_type = 1;   // imposed (9.1.5 in 213) for Type 2 Common search space
       AssertFatal (cc[CC_idP].sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13 != NULL, "cc[CC_idP].sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13 is null\n");
       dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.start_symbol = cc[CC_idP].sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13->startSymbolBR_r13;
       dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.ecce_index = 0;        // Note: this should be dynamic
@@ -826,7 +827,7 @@ generate_Msg4(module_id_t module_idP,
       ra->msg4_TBsize = get_TBS_DL(dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.mcs,
 					    6);
     }                           //repetition_count==0 && SF condition met
-    
+
     if ((ra->msg4_mpdcch_repetition_cnt > 0)&&
 	(ra->msg4_mpdcch_done==0)) {     // we're in a stream of repetitions
       LOG_D(MAC,"SFN.SF %d.%d : msg4 mpdcch repetition number %d/%d\n",
@@ -851,13 +852,13 @@ generate_Msg4(module_id_t module_idP,
     }
 // mpdcch_repetition_count == reps
     else if ((ra->Msg4_frame == frameP) && (ra->Msg4_subframe == subframeP)) {
-      
+
       // Program PDSCH
-      
+
       LOG_D (MAC, "[eNB %d][RAPROC] CC_id %d Frame %d, subframeP %d: Generating Msg4 BR with RRC Piggyback (ce_level %d RNTI %x)\n",
 	     module_idP, CC_idP, frameP, subframeP, ra->rach_resource_type - 1, ra->rnti);
-      
-      
+
+
       dl_config_pdu = &dl_req_body->dl_config_pdu_list[dl_req_body->number_pdu];
       memset ((void *) dl_config_pdu, 0, sizeof (nfapi_dl_config_request_pdu_t));
       dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DLSCH_PDU_TYPE;
@@ -883,21 +884,21 @@ generate_Msg4(module_id_t module_idP,
       dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_mode = (cc[CC_idP].p_eNB == 1) ? 1 : 2;
       dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_prb_per_subband = 1;
       dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_vector = 1;
-      //      dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.bf_vector                    = ; 
-      
+      //      dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.bf_vector                    = ;
+
       dl_config_pdu->dlsch_pdu.dlsch_pdu_rel10.pdsch_start = cc[CC_idP].sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13->startSymbolBR_r13;
-      
+
       dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.ue_type = (ra->rach_resource_type < 3) ? 1 : 2;
       dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.pdsch_payload_type = 2;        // not SI message
       dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.initial_transmission_sf_io = (10 * frameP) + subframeP;
       dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.drms_table_flag = 0;
       dl_req_body->number_pdu++;
-      
+
 
       ra->state = WAITMSG4ACK;
-      
+
       lcid = 0;
-      
+
       UE_list->UE_sched_ctrl[UE_id].round[CC_idP][ra->harq_pid] = 0;
       msg4_header = 1 + 6 + 1;        // CR header, CR CE, SDU header
       AssertFatal((ra->msg4_TBsize - ra->msg4_rrc_sdu_length - msg4_header)>=0,
@@ -909,7 +910,7 @@ generate_Msg4(module_id_t module_idP,
 	msg4_padding = 0;
 	msg4_post_padding = ra->msg4_TBsize - ra->msg4_rrc_sdu_length - msg4_header - 1;
       }
-      
+
       LOG_D (MAC, "[eNB %d][RAPROC] CC_id %d Frame %d subframeP %d Msg4 : TBS %d, sdu_len %d, msg4_header %d, msg4_padding %d, msg4_post_padding %d\n",
 	     module_idP, CC_idP, frameP, subframeP, ra->msg4_TBsize, ra->msg4_rrc_sdu_length, msg4_header, msg4_padding, msg4_post_padding);
       DevAssert (UE_id != UE_INDEX_INVALID);  // FIXME not sure how to gracefully return
@@ -922,9 +923,9 @@ generate_Msg4(module_id_t module_idP,
 				      ra->cont_res_id,       // contention res id
 				      msg4_padding,   // no padding
 				      msg4_post_padding);
-      
+
       memcpy ((void *) &mac->UE_list.DLSCH_pdu[CC_idP][0][(unsigned char) UE_id].payload[0][(unsigned char) offset], &cc[CC_idP].CCCH_pdu.payload[0], ra->msg4_rrc_sdu_length);
-      
+
       // DL request
       mac->TX_req[CC_idP].sfn_sf = (frameP << 4) + subframeP;
       TX_req = &mac->TX_req[CC_idP].tx_request_body.tx_pdu_list[mac->TX_req[CC_idP].tx_request_body.number_of_pdus];
@@ -934,7 +935,7 @@ generate_Msg4(module_id_t module_idP,
       TX_req->segments[0].segment_length = ra->msg4_TBsize;
       TX_req->segments[0].segment_data = mac->UE_list.DLSCH_pdu[CC_idP][0][(unsigned char) UE_id].payload[0];
       mac->TX_req[CC_idP].tx_request_body.number_of_pdus++;
-      
+
       // Program ACK/NAK for Msg4 PDSCH
       int             absSF = (frameP * 10) + subframeP;
       // see Section 10.2 from 36.213
@@ -942,7 +943,7 @@ generate_Msg4(module_id_t module_idP,
       AssertFatal (reps == 1, "Have to handle programming of ACK when PDSCH repetitions is > 1\n");
       ul_req_body = &mac->UL_req_tmp[CC_idP][ackNAK_absSF % 10].ul_config_request_body;
       ul_config_pdu = &ul_req_body->ul_config_pdu_list[ul_req_body->number_of_pdus];
-      
+
       ul_config_pdu->pdu_type = NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE;
       ul_config_pdu->pdu_size = (uint8_t) (2 + sizeof (nfapi_ul_config_uci_harq_pdu));
       ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel8.handle = 0;      // don't know how to use this
@@ -966,72 +967,74 @@ generate_Msg4(module_id_t module_idP,
       ul_req_body->number_of_pdus++;
       T (T_ENB_MAC_UE_DL_PDU_WITH_DATA, T_INT (module_idP), T_INT (CC_idP), T_INT (ra->rnti), T_INT (frameP), T_INT (subframeP),
 	 T_INT (0 /*harq_pid always 0? */ ), T_BUFFER (&mac->UE_list.DLSCH_pdu[CC_idP][0][UE_id].payload[0], ra->msg4_TBsize));
-      
+
       if (opt_enabled == 1) {
 	trace_pdu (1, (uint8_t *) mac->UE_list.DLSCH_pdu[CC_idP][0][(unsigned char) UE_id].payload[0], ra->msg4_rrc_sdu_length, UE_id, 3, UE_RNTI (module_idP, UE_id), mac->frame, mac->subframe, 0, 0);
 	LOG_D (OPT, "[eNB %d][DLSCH] CC_id %d Frame %d trace pdu for rnti %x with size %d\n", module_idP, CC_idP, frameP, UE_RNTI (module_idP, UE_id), ra->msg4_rrc_sdu_length);
       }
-    }                           // Msg4 frame/subframe  
-  }                             // rach_resource_type > 0 
+    }                           // Msg4 frame/subframe
+  }                             // rach_resource_type > 0
   else
 #endif
     {
     // This is normal LTE case
-	LOG_D(MAC, "generate_Msg4 1 ra->Msg4_frame SFN/SF: %d.%d,  frameP SFN/SF: %d.%d FOR eNB_Mod: %d \n", ra->Msg4_frame, ra->Msg4_subframe, frameP, subframeP, module_idP);
+	LOG_I(MAC, "generate_Msg4 ra->Msg4_frame SFN/SF: %d.%d,  frameP SFN/SF: %d.%d FOR eNB_Mod: %d \n", ra->Msg4_frame, ra->Msg4_subframe, frameP, subframeP, module_idP);
     	if ((ra->Msg4_frame == frameP) && (ra->Msg4_subframe == subframeP)) {
 
     	    // Get RRCConnectionSetup for Piggyback
     	    /*rrc_sdu_length = mac_rrc_data_req(module_idP, CC_idP, frameP, CCCH, 1,	// 1 transport block
     					      &cc[CC_idP].CCCH_pdu.payload[0], ENB_FLAG_YES, module_idP, 0);	// not used in this case*/
 
-    		rrc_sdu_length = mac_rrc_data_req(module_idP, CC_idP, frameP, CCCH, 1,	// 1 transport block
-    						      &cc[CC_idP].CCCH_pdu.payload[0], 0);	// not used in this case
+	  // check if there's data on the CCCH to send with Msg4
+	  rrc_sdu_length = mac_rrc_data_req(module_idP, CC_idP, frameP, CCCH, 
+					    UE_RNTI(module_idP,UE_id),1,	// 1 transport block
+					    &cc[CC_idP].CCCH_pdu.payload[0], 0);	// not used in this case
 
-    	    LOG_D(MAC,
+	  if (rrc_sdu_length > 0) { 
+	    LOG_D(MAC,
     	    	  "[eNB %d][RAPROC] CC_id %d Frame %d, subframeP %d: UE_id %d, rrc_sdu_length %d\n",
     	    	  module_idP, CC_idP, frameP, subframeP, UE_id, rrc_sdu_length);
-
-    	    AssertFatal(rrc_sdu_length > 0,
-    			"[MAC][eNB Scheduler] CCCH not allocated, rrc_sdu_length: %d\n", rrc_sdu_length);
-
-
-
-	    LOG_D(MAC,
-		  "[eNB %d][RAPROC] CC_id %d Frame %d, subframeP %d: Generating Msg4 with RRC Piggyback (RNTI %x)\n",
+	    
+	    //    	    AssertFatal(rrc_sdu_length > 0,
+	    //    			"[MAC][eNB Scheduler] CCCH not allocated, rrc_sdu_length: %d\n", rrc_sdu_length);
+	    
+	    
+	    
+	    LOG_I(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d, subframeP %d: Generating Msg4 with RRC Piggyback (RNTI %x)\n",
 		  module_idP, CC_idP, frameP, subframeP, ra->rnti);
-
+	  
 	    /// Choose first 4 RBs for Msg4, should really check that these are free!
 	    first_rb = 0;
-
+	    
 	    vrb_map[first_rb] = 1;
 	    vrb_map[first_rb + 1] = 1;
 	    vrb_map[first_rb + 2] = 1;
 	    vrb_map[first_rb + 3] = 1;
-
-
+	    
+	    
 	    // Compute MCS/TBS for 3 PRB (coded on 4 vrb)
 	    msg4_header = 1 + 6 + 1;	// CR header, CR CE, SDU header
-
+	    
 	    if ((rrc_sdu_length + msg4_header) <= 22) {
-		ra->msg4_mcs = 4;
-		ra->msg4_TBsize = 22;
+	      ra->msg4_mcs = 4;
+	      ra->msg4_TBsize = 22;
 	    } else if ((rrc_sdu_length + msg4_header) <= 28) {
-		ra->msg4_mcs = 5;
-		ra->msg4_TBsize = 28;
+	      ra->msg4_mcs = 5;
+	      ra->msg4_TBsize = 28;
 	    } else if ((rrc_sdu_length + msg4_header) <= 32) {
-		ra->msg4_mcs = 6;
-		ra->msg4_TBsize = 32;
+	      ra->msg4_mcs = 6;
+	      ra->msg4_TBsize = 32;
 	    } else if ((rrc_sdu_length + msg4_header) <= 41) {
-		ra->msg4_mcs = 7;
-		ra->msg4_TBsize = 41;
+	      ra->msg4_mcs = 7;
+	      ra->msg4_TBsize = 41;
 	    } else if ((rrc_sdu_length + msg4_header) <= 49) {
-		ra->msg4_mcs = 8;
-		ra->msg4_TBsize = 49;
+	      ra->msg4_mcs = 8;
+	      ra->msg4_TBsize = 49;
 	    } else if ((rrc_sdu_length + msg4_header) <= 57) {
-		ra->msg4_mcs = 9;
-		ra->msg4_TBsize = 57;
+	      ra->msg4_mcs = 9;
+	      ra->msg4_TBsize = 57;
 	    }
-
+	    
 	    fill_nfapi_dl_dci_1A(dl_config_pdu, 4,	// aggregation_level
 				 ra->rnti,	// rnti
 				 1,	// rnti_type, CRNTI
@@ -1042,7 +1045,7 @@ generate_Msg4(module_id_t module_idP,
 				 1,	// ndi
 				 0,	// rv
 				 0);	// vrb_flag
-
+	    
 	    LOG_D(MAC,
 		  "Frame %d, subframe %d: Msg4 DCI pdu_num %d (rnti %x,rnti_type %d,harq_pid %d, resource_block_coding (%p) %d\n",
 		  frameP, subframeP, dl_req_body->number_pdu,
@@ -1096,7 +1099,9 @@ generate_Msg4(module_id_t module_idP,
 		      msg4_padding, msg4_post_padding);
 		DevAssert(UE_id != UE_INDEX_INVALID);	// FIXME not sure how to gracefully return
 		// CHECK THIS: &cc[CC_idP].CCCH_pdu.payload[0]
-		offset = generate_dlsch_header((unsigned char *) mac->UE_list.DLSCH_pdu[CC_idP][0][(unsigned char) UE_id].payload[0], 1,	//num_sdus
+		int num_sdus = rrc_sdu_length > 0 ? 1 : 0;							       
+		offset = generate_dlsch_header((unsigned char *) mac->UE_list.DLSCH_pdu[CC_idP][0][(unsigned char) UE_id].payload[0], 
+							       num_sdus,	//num_sdus
 					       (unsigned short *) &rrc_sdu_length,	//
 					       &lcid,	// sdu_lcid
 					       255,	// no drx
@@ -1178,6 +1183,21 @@ generate_Msg4(module_id_t module_idP,
         	  set_dl_ue_select_msg4(CC_idP, 4, UE_id, ra->rnti);
 		}
 	    }			// CCE Allocation feasible
+	  }
+	  else {
+	    LOG_I(MAC,
+		     "eNB %d][RAPROC] CC_id %d Frame %d, subframeP %d: Delaying Msg4 for RRC Piggyback (RNTI %x)\n",
+		     module_idP, CC_idP, frameP, subframeP, ra->rnti);
+	    ra->Msg4_subframe ++;
+	    ra->Msg4_delay_cnt++;
+	    if (ra->Msg4_delay_cnt==10) cancel_ra_proc(module_idP, CC_idP, frameP, ra->rnti);
+
+	    if (ra->Msg4_subframe == 10) {
+	      ra->Msg4_frame++;
+	      ra->Msg4_frame&=1023;
+	      ra->Msg4_subframe = 0;
+	    }
+	  }
 	}			// msg4 frame/subframe
     }				// else rach_resource_type
 }
@@ -1476,6 +1496,7 @@ initiate_ra_proc(module_id_t module_idP,
 	    LOG_D(MAC, "Frame %d, Subframe %d: Activating RA process %d\n",
 		  frameP, subframeP, i);
 	    ra[i].state = MSG2;
+	    ra[i].Msg4_delay_cnt=0;
 	    ra[i].timing_offset = timing_offset;
 	    ra[i].preamble_subframe = subframeP;
 #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
diff --git a/openair2/LAYER2/MAC/eNB_scheduler_bch.c b/openair2/LAYER2/MAC/eNB_scheduler_bch.c
index 339d4102aa48416bfe4b498c3219c55c4f3c7f0a..d49ebbb264134e44e5aabe97320bc171b23ec77c 100644
--- a/openair2/LAYER2/MAC/eNB_scheduler_bch.c
+++ b/openair2/LAYER2/MAC/eNB_scheduler_bch.c
@@ -193,7 +193,7 @@ schedule_SIB1_BR(module_id_t module_idP,
 	n_NB = Sj[((cc->physCellId % N_S_NB) + (i * N_S_NB / m)) % N_S_NB];
 
 
-	bcch_sdu_length = mac_rrc_data_req(module_idP, CC_id, frameP, BCCH_SIB1_BR, 1, &cc->BCCH_BR_pdu[0].payload[0], 0);	// not used in this case
+	bcch_sdu_length = mac_rrc_data_req(module_idP, CC_id, frameP, BCCH_SIB1_BR, 0xFFFF, 1, &cc->BCCH_BR_pdu[0].payload[0], 0);	// not used in this case
 
 	AssertFatal(cc->mib->message.schedulingInfoSIB1_BR_r13 < 19,
 		    "schedulingInfoSIB1_BR_r13 %d > 18\n",
@@ -310,7 +310,6 @@ schedule_SI_BR(module_id_t module_idP, frame_t frameP,
 	       sub_frame_t subframeP)
 //------------------------------------------------------------------------------
 {
-
   int8_t                                  bcch_sdu_length;
   int                                     CC_id;
   eNB_MAC_INST                            *eNB = RC.mac[module_idP];
@@ -348,7 +347,7 @@ schedule_SI_BR(module_id_t module_idP, frame_t frameP,
       LTE_SchedulingInfoList_t *schedulingInfoList = cc->schedulingInfoList;
       AssertFatal(schedulingInfoList_BR_r13->list.count==schedulingInfoList->list.count,
 		  "schedulingInfolist_BR.r13->list.count %d != schedulingInfoList.list.count %d\n",
-		  schedulingInfoList_BR_r13->list.count,schedulingInfoList->list.count); 
+		  schedulingInfoList_BR_r13->list.count,schedulingInfoList->list.count);
 
       AssertFatal(cc->sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13->si_WindowLength_BR_r13<=LTE_SystemInformationBlockType1_v1310_IEs__bandwidthReducedAccessRelatedInfo_r13__si_WindowLength_BR_r13_ms200,
 		  "si_WindowLength_BR_r13 %d > %d\n",
@@ -368,130 +367,140 @@ schedule_SI_BR(module_id_t module_idP, frame_t frameP,
       // cycle through SIB list
 
       for (i=0;i<schedulingInfoList_BR_r13->list.count;i++) {
-	long si_Periodicity           = schedulingInfoList->list.array[i]->si_Periodicity;
-	long si_Narrowband_r13        = schedulingInfoList_BR_r13->list.array[i]->si_Narrowband_r13;
-	long si_TBS_r13               = si_TBS_r13tab[schedulingInfoList_BR_r13->list.array[i]->si_TBS_r13];
-
-	// check if the SI is to be scheduled now
-	int period_in_sf              = 80<<si_Periodicity; // 2^i * 80 subframes, note: si_Periodicity is 2^i * 80ms
-	int sf_mod_period             = absSF%period_in_sf;
-	int k                         = sf_mod_period&3;
-	// Note: definition of k and rvidx from 36.321 section 5.3.1
-	rvidx = (((3*k)>>1) + (k&1))&3;
-	
-        if ((sf_mod_period < si_WindowLength_BR_r13) &&
-	    ((frameP&(((1<<si_RepetitionPattern_r13)-1)))==0)) { // this SIB is to be scheduled
-
-	  bcch_sdu_length = mac_rrc_data_req(module_idP,
-					     CC_id,
-					     frameP,
-					     BCCH_SI_BR+i,1,
-					     &cc->BCCH_BR_pdu[i+1].payload[0],
-					     0); // not used in this case
-	  
-	  AssertFatal(bcch_sdu_length>0,"RRC returned 0 bytes for SI-BR %d\n",i);
-	  
-	  if (bcch_sdu_length > 0) {
-	    AssertFatal(bcch_sdu_length <= (si_TBS_r13>>3),
-			"RRC provided bcch with length %d > %d (si_TBS_r13 %d)\n",
-			bcch_sdu_length,(int)(si_TBS_r13>>3),(int)schedulingInfoList_BR_r13->list.array[i]->si_TBS_r13);
-
-	    // allocate all 6 PRBs in narrowband for SIB1_BR
-
-	    // check that SIB1 didn't take this narrowband
-	    if (vrb_map[first_rb] > 0) continue;
-
-	    first_rb = narrowband_to_first_rb(cc,si_Narrowband_r13-1);
-	    vrb_map[first_rb]   = 1;
-	    vrb_map[first_rb+1] = 1;
-	    vrb_map[first_rb+2] = 1;
-	    vrb_map[first_rb+4] = 1;
-	    vrb_map[first_rb+5] = 1;
-
-	    if ((frameP&1023) < 200) 
-	      LOG_D(MAC,"[eNB %d] Frame %d Subframe %d: SI_BR->DLSCH CC_id %d, Narrowband %d rvidx %d (sf_mod_period %d : si_WindowLength_BR_r13 %d : si_RepetitionPattern_r13 %d) bcch_sdu_length %d\n",
-					   module_idP,frameP,subframeP,CC_id,(int)si_Narrowband_r13-1,rvidx,
-					   sf_mod_period,(int)si_WindowLength_BR_r13,(int)si_RepetitionPattern_r13,
-					   bcch_sdu_length);	    
-
-
-
-	    
-	    dl_config_pdu                                                                  = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; 
-	    memset((void*)dl_config_pdu,0,sizeof(nfapi_dl_config_request_pdu_t));
-	    dl_config_pdu->pdu_type                                                        = NFAPI_DL_CONFIG_DLSCH_PDU_TYPE; 
-	    dl_config_pdu->pdu_size                                                        = (uint8_t)(2+sizeof(nfapi_dl_config_dlsch_pdu));
-	    dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.length                                 = si_TBS_r13>>3;
-	    dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index                              = eNB->pdu_index[CC_id];
-	    dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.rnti                                   = 0xFFFF;
-	    dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type               = 2;   // format 1A/1B/1D
-	    dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.virtual_resource_block_assignment_flag = 0;   // localized
-	    dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_block_coding                  = getRIV(N_RB_DL,first_rb,6);
-	    dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.modulation                             = 2; //QPSK
-	    dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.redundancy_version                     = rvidx;
-	    dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_blocks                       = 1;// first block
-	    dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_block_to_codeword_swap_flag  = 0;
-	    dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_scheme                    = (cc->p_eNB==1 ) ? 0 : 1;
-	    dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_layers                       = 1;
-	    dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_subbands                     = 1;
-	    //	dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.codebook_index                         = ;
-	    dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ue_category_capacity                   = 1;
-	    dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pa                                     = 4; // 0 dB
-	    dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.delta_power_offset_index               = 0;
-	    dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ngap                                   = 0;
-	    dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.nprb                                   = get_subbandsize(cc->mib->message.dl_Bandwidth); // ignored
-	    dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_mode                      = (cc->p_eNB==1 ) ? 1 : 2;
-	    dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_prb_per_subband                 = 1;
-	    dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_vector                          = 1;
-	    // Rel10 fields (for PDSCH starting symbol)
-	    dl_config_pdu->dlsch_pdu.dlsch_pdu_rel10.pdsch_start                           = cc[CC_id].sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13->startSymbolBR_r13;
-	    // Rel13 fields
-	    dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.ue_type                               = 1; // CEModeA UE
-	    dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.pdsch_payload_type                    = 1; // SI-BR
-	    dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.initial_transmission_sf_io            = absSF - sf_mod_period; 
-	    
-	    //	dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.bf_vector                    = ; 
-	    dl_req->number_pdu++;
-	    
-	    // Program TX Request
-	    TX_req                                                                = &eNB->TX_req[CC_id].tx_request_body.tx_pdu_list[eNB->TX_req[CC_id].tx_request_body.number_of_pdus]; 
-	    TX_req->pdu_length                                                    = bcch_sdu_length;
-	    TX_req->pdu_index                                                     = eNB->pdu_index[CC_id]++;
-	    TX_req->num_segments                                                  = 1;
-	    TX_req->segments[0].segment_length                                    = bcch_sdu_length;
-	    TX_req->segments[0].segment_data                                      = cc->BCCH_BR_pdu[i+1].payload;
-	    eNB->TX_req[CC_id].tx_request_body.number_of_pdus++;
-	    
-	    if (opt_enabled == 1) {
-	      trace_pdu(1,
-			&cc->BCCH_BR_pdu[i+1].payload[0],
-			bcch_sdu_length,
-			0xffff,
-			4,
-			0xffff,
-			eNB->frame,
-			eNB->subframe,
-			0,
-			0);
-	      LOG_D(OPT,"[eNB %d][BCH] Frame %d trace pdu for CC_id %d rnti %x with size %d\n",
-		    module_idP, frameP, CC_id, 0xffff, bcch_sdu_length);
-	    }
-	    if (cc->tdd_Config!=NULL) { //TDD
-	      LOG_D(MAC,"[eNB] Frame %d : Scheduling BCCH-BR %d->DLSCH (TDD) for CC_id %d SI-BR %d bytes\n",
-		    frameP,i,
-		    CC_id,
-		    bcch_sdu_length);
-	    } else {
-	      LOG_D(MAC,"[eNB] Frame %d : Scheduling BCCH-BR %d->DLSCH (FDD) for CC_id %d SI-BR %d bytes\n",
-		    frameP,i,
-		    CC_id,
-		    bcch_sdu_length);
-	    }
-	  }
-	} // scheduling in current frame/subframe
-      } //for SI List
-    } // eMTC is activated
-  } // CC_id
+        long si_Periodicity = schedulingInfoList->list.array[i]->si_Periodicity;
+        long si_Narrowband_r13 = schedulingInfoList_BR_r13->list.array[i]->si_Narrowband_r13;
+        long si_TBS_r13 = si_TBS_r13tab[schedulingInfoList_BR_r13->list.array[i]->si_TBS_r13];
+
+        // check if the SI is to be scheduled now
+        int period_in_sf;
+        if ((si_Periodicity >= 0) && (si_Periodicity < 25)) {
+          // 2^i * 80 subframes, note: si_Periodicity is 2^i * 80ms
+          period_in_sf = 80 << ((int) si_Periodicity);
+        } else if (si_Periodicity < 0) {
+          period_in_sf = 80;
+        } else if (si_Periodicity > 24) {
+          period_in_sf = 80 << 24;
+        }
+        int sf_mod_period = absSF % period_in_sf;
+        int k = sf_mod_period & 3;
+        // Note: definition of k and rvidx from 36.321 section 5.3.1
+        rvidx = (((3 * k) >> 1) + (k & 1)) & 3;
+
+        if ((sf_mod_period < si_WindowLength_BR_r13)
+            && ((frameP & (((1 << si_RepetitionPattern_r13) - 1))) == 0)) {	// this SIB is to be scheduled
+
+          bcch_sdu_length = mac_rrc_data_req(module_idP, CC_id, frameP, BCCH_SI_BR + i, 0xFFFF, 1, &cc->BCCH_BR_pdu[i + 1].payload[0], 0);	// not used in this case
+
+
+          AssertFatal(bcch_sdu_length > 0,
+          "RRC returned 0 bytes for SI-BR %d\n", i);
+
+          if (bcch_sdu_length > 0) {
+            AssertFatal(bcch_sdu_length <= (si_TBS_r13 >> 3),
+                        "RRC provided bcch with length %d > %d (si_TBS_r13 %d)\n",
+                        bcch_sdu_length,
+                        (int) (si_TBS_r13 >> 3),
+                        (int) schedulingInfoList_BR_r13->list.array[i]->si_TBS_r13);
+
+            // allocate all 6 PRBs in narrowband for SIB1_BR
+
+            // check that SIB1 didn't take this narrowband
+            if (vrb_map[first_rb] > 0) continue;
+
+            first_rb = narrowband_to_first_rb(cc,si_Narrowband_r13 - 1);
+            vrb_map[first_rb] = 1;
+            vrb_map[first_rb + 1] = 1;
+            vrb_map[first_rb + 2] = 1;
+            vrb_map[first_rb + 4] = 1;
+            vrb_map[first_rb + 5] = 1;
+
+            if ((frameP&1023) < 200)
+              LOG_D(MAC,"[eNB %d] Frame %d Subframe %d: SI_BR->DLSCH CC_id %d, Narrowband %d rvidx %d (sf_mod_period %d : si_WindowLength_BR_r13 %d : si_RepetitionPattern_r13 %d) bcch_sdu_length %d\n",
+                   module_idP,frameP,subframeP,CC_id,(int)si_Narrowband_r13-1,rvidx,
+                   sf_mod_period,(int)si_WindowLength_BR_r13,(int)si_RepetitionPattern_r13,
+                   bcch_sdu_length);
+
+
+            //// Rel10 fields (for PDSCH starting symbol)
+            //dl_config_pdu->dlsch_pdu.dlsch_pdu_rel10.pdsch_start = cc[CC_id].sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13->startSymbolBR_r13;
+            //// Rel13 fields
+            //                  dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.tl.tag = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL13_TAG;
+            //dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.ue_type = 1;	// CEModeA UE
+            //dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.pdsch_payload_type = 1;	// SI-BR
+            //dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.initial_transmission_sf_io = absSF - sf_mod_period;
+
+            ////  dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.bf_vector                    = ;
+            //dl_req->number_pdu++;
+            //                  dl_req->tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG;
+
+            dl_config_pdu                                                                  = &dl_req->dl_config_pdu_list[dl_req->number_pdu];
+            memset((void *) dl_config_pdu, 0, sizeof(nfapi_dl_config_request_pdu_t));
+            dl_config_pdu->pdu_type                                                        = NFAPI_DL_CONFIG_DLSCH_PDU_TYPE;
+            dl_config_pdu->pdu_size                                                        = (uint8_t)(2+sizeof(nfapi_dl_config_dlsch_pdu));
+            dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.length                                 = si_TBS_r13>>3;
+            dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index                              = eNB->pdu_index[CC_id];
+            dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.rnti                                   = 0xFFFF;
+            dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type               = 2;   // format 1A/1B/1D
+            dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.virtual_resource_block_assignment_flag = 0;   // localized
+            dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_block_coding                  = getRIV(N_RB_DL,first_rb,6);
+            dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.modulation                             = 2; //QPSK
+            dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.redundancy_version                     = rvidx;
+            dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_blocks                       = 1;// first block
+            dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_block_to_codeword_swap_flag  = 0;
+            dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_scheme                    = (cc->p_eNB==1 ) ? 0 : 1;
+            dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_layers                       = 1;
+            dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_subbands                     = 1;
+            //	dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.codebook_index                         = ;
+            dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ue_category_capacity                   = 1;
+            dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pa                                     = 4; // 0 dB
+            dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.delta_power_offset_index               = 0;
+            dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ngap                                   = 0;
+            dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.nprb                                   = get_subbandsize(cc->mib->message.dl_Bandwidth); // ignored
+            dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_mode                      = (cc->p_eNB==1 ) ? 1 : 2;
+            dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_prb_per_subband                 = 1;
+            dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_vector                          = 1;
+            // Rel10 fields (for PDSCH starting symbol)
+            dl_config_pdu->dlsch_pdu.dlsch_pdu_rel10.pdsch_start                           = cc[CC_id].sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13->startSymbolBR_r13;
+            // Rel13 fields
+            dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.ue_type                               = 1; // CEModeA UE
+            dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.pdsch_payload_type                    = 1; // SI-BR
+            dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.initial_transmission_sf_io            = absSF - sf_mod_period;
+
+            //	dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.bf_vector                    = ;
+            dl_req->number_pdu++;
+
+            // Program TX Request
+            TX_req                                                                = &eNB->TX_req[CC_id].tx_request_body.tx_pdu_list[eNB->TX_req[CC_id].tx_request_body.number_of_pdus];
+            TX_req->pdu_length                                                    = bcch_sdu_length;
+            TX_req->pdu_index                                                     = eNB->pdu_index[CC_id]++;
+            TX_req->num_segments                                                  = 1;
+            TX_req->segments[0].segment_length                                    = bcch_sdu_length;
+            TX_req->segments[0].segment_data                                      = cc->BCCH_BR_pdu[i+1].payload;
+            eNB->TX_req[CC_id].tx_request_body.number_of_pdus++;
+
+            if (opt_enabled == 1) {
+                trace_pdu(DIRECTION_DOWNLINK,
+                    &cc->BCCH_BR_pdu[i + 1].payload[0],
+                    bcch_sdu_length,
+                    0xffff,
+                    WS_SI_RNTI,
+                    0xffff, eNB->frame, eNB->subframe, 0,
+                    0);
+                LOG_D(OPT, "[eNB %d][BCH] Frame %d trace pdu for CC_id %d rnti %x with size %d\n",
+                      module_idP, frameP, CC_id, 0xffff, bcch_sdu_length);
+            }
+            if (cc->tdd_Config != NULL) {	//TDD
+                LOG_D(MAC, "[eNB] Frame %d : Scheduling BCCH-BR %d->DLSCH (TDD) for CC_id %d SI-BR %d bytes\n",
+                      frameP, i, CC_id, bcch_sdu_length);
+            } else {
+                LOG_D(MAC, "[eNB] Frame %d : Scheduling BCCH-BR %d->DLSCH (FDD) for CC_id %d SI-BR %d bytes\n",
+                      frameP, i, CC_id, bcch_sdu_length);
+            }
+          }
+        }		// scheduling in current frame/subframe
+	    }			//for SI List
+    }			// eMTC is activated
+  }				// CC_id
   return;
 }
 #endif
@@ -518,7 +527,7 @@ schedule_mib(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP)
 	dl_req = &dl_config_request->dl_config_request_body;
 	cc = &eNB->common_channels[CC_id];
 
-	mib_sdu_length = mac_rrc_data_req(module_idP, CC_id, frameP, MIBCH, 1, &cc->MIB_pdu.payload[0], 0);	// not used in this case
+	mib_sdu_length = mac_rrc_data_req(module_idP, CC_id, frameP, MIBCH, 0xFFFF, 1, &cc->MIB_pdu.payload[0], 0);	// not used in this case
 
 	LOG_D(MAC, "Frame %d, subframe %d: BCH PDU length %d\n", frameP, subframeP, mib_sdu_length);
 
@@ -605,7 +614,7 @@ schedule_SI(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP)
 	    dl_req = &eNB->DL_req[CC_id].dl_config_request_body;
 
 
-	    bcch_sdu_length = mac_rrc_data_req(module_idP, CC_id, frameP, BCCH, 1, &cc->BCCH_pdu.payload[0], 0);	// not used in this case
+	    bcch_sdu_length = mac_rrc_data_req(module_idP, CC_id, frameP, BCCH, 0xFFFF,1, &cc->BCCH_pdu.payload[0], 0);	// not used in this case
 
 	    if (bcch_sdu_length > 0) {
 		LOG_D(MAC, "[eNB %d] Frame %d : BCCH->DLSCH CC_id %d, Received %d bytes \n", module_idP, frameP, CC_id, bcch_sdu_length);
diff --git a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c
index f848207b7bfe4207c394c79832b24752b16286f4..274b169bf650b0c366fb87d7681222221e8e551e 100644
--- a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c
+++ b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c
@@ -88,7 +88,7 @@ add_ue_dlsch_info(module_id_t module_idP,
 
 //------------------------------------------------------------------------------
 int
-schedule_next_dlue(module_id_t module_idP, 
+schedule_next_dlue(module_id_t module_idP,
                    int CC_id,
                    sub_frame_t subframeP)
 //------------------------------------------------------------------------------
@@ -174,10 +174,10 @@ generate_dlsch_header(unsigned char *mac_header,
     last_size = 1;
     //    msg("last_size %d,mac_header_ptr %p\n",last_size,mac_header_ptr);
     ((TIMING_ADVANCE_CMD *) ce_ptr)->R = 0;
-    AssertFatal(timing_advance_cmd < 64, "timing_advance_cmd %d > 63\n", 
+    AssertFatal(timing_advance_cmd < 64, "timing_advance_cmd %d > 63\n",
                 timing_advance_cmd);
     ((TIMING_ADVANCE_CMD *) ce_ptr)->TA = timing_advance_cmd;    //(timing_advance_cmd+31)&0x3f;
-    LOG_D(MAC, "timing advance =%d (%d)\n", 
+    LOG_D(MAC, "timing advance =%d (%d)\n",
           timing_advance_cmd,
           ((TIMING_ADVANCE_CMD *) ce_ptr)->TA);
     ce_ptr += sizeof(TIMING_ADVANCE_CMD);
@@ -203,14 +203,14 @@ generate_dlsch_header(unsigned char *mac_header,
     mac_header_ptr->LCID = UE_CONT_RES;
     last_size = 1;
     LOG_T(MAC, "[eNB ][RAPROC] Generate contention resolution msg: %x.%x.%x.%x.%x.%x\n",
-          ue_cont_res_id[0], 
-          ue_cont_res_id[1], 
+          ue_cont_res_id[0],
+          ue_cont_res_id[1],
           ue_cont_res_id[2],
-          ue_cont_res_id[3], 
-          ue_cont_res_id[4], 
+          ue_cont_res_id[3],
+          ue_cont_res_id[4],
           ue_cont_res_id[5]);
-    memcpy(ce_ptr, 
-           ue_cont_res_id, 
+    memcpy(ce_ptr,
+           ue_cont_res_id,
            6);
     ce_ptr += 6;
     // msg("(cont_res) : offset %d\n",ce_ptr-mac_header_control_elements);
@@ -220,7 +220,7 @@ generate_dlsch_header(unsigned char *mac_header,
 
   for (i = 0; i < num_sdus; i++) {
     LOG_T(MAC, "[eNB] Generate DLSCH header num sdu %d len sdu %d\n",
-          num_sdus, 
+          num_sdus,
           sdu_lengths[i]);
 
     if (first_element > 0) {
@@ -295,7 +295,7 @@ generate_dlsch_header(unsigned char *mac_header,
 
   if ((ce_ptr - mac_header_control_elements) > 0) {
     // printf("Copying %d bytes for control elements\n",ce_ptr-mac_header_control_elements);
-    memcpy((void *) mac_header_ptr, 
+    memcpy((void *) mac_header_ptr,
            mac_header_control_elements,
            ce_ptr - mac_header_control_elements);
     mac_header_ptr += (unsigned char) (ce_ptr - mac_header_control_elements);
@@ -424,9 +424,9 @@ schedule_dlsch(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP, in
 
   for (i = 0; i < sli->n_dl; i++) {
     // Run each enabled slice-specific schedulers one by one
-    sli->dl[i].sched_cb(module_idP, 
-                        i, 
-                        frameP, 
+    sli->dl[i].sched_cb(module_idP,
+                        i,
+                        frameP,
                         subframeP,
                         mbsfn_flag/*, dl_info*/);
   }
@@ -512,7 +512,7 @@ schedule_ue_spec(module_id_t module_idP,
   long dl_Bandwidth;
 
   start_meas(&eNB->schedule_dlsch);
-  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_SCHEDULE_DLSCH, 
+  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_SCHEDULE_DLSCH,
                                           VCD_FUNCTION_IN);
 
   // for TDD: check that we have to act here, otherwise return
@@ -570,7 +570,7 @@ schedule_ue_spec(module_id_t module_idP,
   for (CC_id = 0, eNB_stats = &eNB->eNB_stats[0]; CC_id < nb_mac_CC; CC_id++, eNB_stats++) {
     dl_Bandwidth = cc[CC_id].mib->message.dl_Bandwidth;
     N_RB_DL[CC_id] = to_prb(dl_Bandwidth);
-    min_rb_unit[CC_id] = get_min_rb_unit(module_idP, 
+    min_rb_unit[CC_id] = get_min_rb_unit(module_idP,
                                          CC_id);
     // get number of PRBs less those used by common channels
     total_nb_available_rb[CC_id] = N_RB_DL[CC_id];
@@ -590,7 +590,7 @@ schedule_ue_spec(module_id_t module_idP,
 
   // CALLING Pre_Processor for downlink scheduling
   // (Returns estimation of RBs required by each UE and the allocation on sub-band)
-  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_PREPROCESSOR, 
+  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_PREPROCESSOR,
                                           VCD_FUNCTION_IN);
   start_meas(&eNB->schedule_dlsch_preprocessor);
   dlsch_scheduler_pre_processor(module_idP,
@@ -600,7 +600,7 @@ schedule_ue_spec(module_id_t module_idP,
                                 mbsfn_flag,
                                 eNB->slice_info.rballoc_sub);
   stop_meas(&eNB->schedule_dlsch_preprocessor);
-  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_PREPROCESSOR, 
+  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_PREPROCESSOR,
                                           VCD_FUNCTION_OUT);
 
   //RC.mac[module_idP]->slice_info.slice_counter--;
@@ -642,7 +642,7 @@ schedule_ue_spec(module_id_t module_idP,
       ue_template = &UE_list->UE_template[CC_id][UE_id];
 
       if (ue_template->rach_resource_type > 0) continue_flag = 1;
-	
+
       if (&(UE_list->eNB_UE_stats[CC_id][UE_id]) == NULL) {
         LOG_D(MAC, "[eNB] Cannot find eNB_UE_stats\n");
         continue_flag = 1;
@@ -651,20 +651,20 @@ schedule_ue_spec(module_id_t module_idP,
       }
 
       if (continue_flag != 1) {
-        switch (get_tmode(module_idP, 
-                          CC_id, 
+        switch (get_tmode(module_idP,
+                          CC_id,
                           UE_id)) {
           case 1:
           case 2:
           case 7:
-            aggregation = get_aggregation(get_bw_index(module_idP, 
+            aggregation = get_aggregation(get_bw_index(module_idP,
                                                        CC_id),
                                           ue_sched_ctrl->dl_cqi[CC_id],
                                           format1);
             break;
 
           case 3:
-            aggregation = get_aggregation(get_bw_index(module_idP, 
+            aggregation = get_aggregation(get_bw_index(module_idP,
                                                        CC_id),
                                           ue_sched_ctrl->dl_cqi[CC_id],
                                           format2A);
@@ -679,11 +679,11 @@ schedule_ue_spec(module_id_t module_idP,
 
       /* if (continue_flag != 1 */
       if (ue_sched_ctrl->pre_nb_available_rbs[CC_id] == 0 || // no RBs allocated
-          CCE_allocation_infeasible(module_idP, 
-                                    CC_id, 
-                                    1, 
-                                    subframeP, 
-                                    aggregation, 
+          CCE_allocation_infeasible(module_idP,
+                                    CC_id,
+                                    1,
+                                    subframeP,
+                                    aggregation,
                                     rnti)) {
         LOG_D(MAC, "[eNB %d] Frame %d : no RB allocated for UE %d on CC_id %d: continue \n",
               module_idP,
@@ -759,13 +759,13 @@ schedule_ue_spec(module_id_t module_idP,
       }
 
       LOG_D(MAC, "[eNB %d] Frame %d: Scheduling UE %d on CC_id %d (rnti %x, harq_pid %d, round %d, rb %d, cqi %d, mcs %d, rrc %d)\n",
-            module_idP, 
-            frameP, UE_id, 
-            CC_id, 
-            rnti, 
+            module_idP,
+            frameP, UE_id,
+            CC_id,
+            rnti,
             harq_pid,
              round,
-            nb_available_rb, 
+            nb_available_rb,
             ue_sched_ctrl->dl_cqi[CC_id],
             eNB_UE_stats->dlsch_mcs1,
             eNB_UE_stats->rrc_status);
@@ -774,20 +774,20 @@ schedule_ue_spec(module_id_t module_idP,
       if (round != 8) {
         // get freq_allocation
         nb_rb = ue_template->nb_rb[harq_pid];
-        TBS = get_TBS_DL(ue_template->oldmcs1[harq_pid], 
+        TBS = get_TBS_DL(ue_template->oldmcs1[harq_pid],
                          nb_rb);
 
         if (nb_rb <= nb_available_rb) {
           if (cc[CC_id].tdd_Config != NULL) {
             ue_template->DAI++;
-            update_ul_dci(module_idP, 
-                          CC_id, 
+            update_ul_dci(module_idP,
+                          CC_id,
                           rnti,
-                          ue_template->DAI, 
+                          ue_template->DAI,
                           subframeP);
             LOG_D(MAC, "DAI update: CC_id %d subframeP %d: UE %d, DAI %d\n",
-                  CC_id, 
-                  subframeP, 
+                  CC_id,
+                  subframeP,
                   UE_id,
                   ue_template->DAI);
           }
@@ -830,18 +830,18 @@ schedule_ue_spec(module_id_t module_idP,
             case 2:
             case 7:
             default:
-              LOG_D(MAC, "retransmission DL_REQ: rnti:%x\n", 
+              LOG_D(MAC, "retransmission DL_REQ: rnti:%x\n",
                     rnti);
               dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu];
-              memset((void *) dl_config_pdu, 
-                     0, 
+              memset((void *) dl_config_pdu,
+                     0,
                      sizeof(nfapi_dl_config_request_pdu_t));
               dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE;
               dl_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_dl_config_dci_dl_pdu));
               dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL8_TAG;
               dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format = NFAPI_DL_DCI_FORMAT_1;
               dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level =
-                get_aggregation(get_bw_index(module_idP, 
+                get_aggregation(get_bw_index(module_idP,
                                              CC_id),
                                 ue_sched_ctrl->dl_cqi[CC_id],
                                 format1);
@@ -858,37 +858,37 @@ schedule_ue_spec(module_id_t module_idP,
               if (cc[CC_id].tdd_Config != NULL) {
                 dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.downlink_assignment_index = (ue_template->DAI - 1) & 3;
                 LOG_D(MAC, "[eNB %d] Retransmission CC_id %d : harq_pid %d, round %d, dai %d, mcs %d\n",
-                      module_idP, 
-                      CC_id, 
-                      harq_pid, 
+                      module_idP,
+                      CC_id,
+                      harq_pid,
                       round,
                       ue_template->DAI - 1,
                       ue_template->oldmcs1[harq_pid]);
               } else {
                 LOG_D(MAC, "[eNB %d] Retransmission CC_id %d : harq_pid %d, round %d, mcs %d\n",
-                      module_idP, 
-                      CC_id, 
-                      harq_pid, 
+                      module_idP,
+                      CC_id,
+                      harq_pid,
                       round,
                       ue_template->oldmcs1[harq_pid]);
               }
 
-              if (!CCE_allocation_infeasible(module_idP, 
-                                             CC_id, 
-                                             1, 
+              if (!CCE_allocation_infeasible(module_idP,
+                                             CC_id,
+                                             1,
                                              subframeP,
-                                             dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level, 
+                                             dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level,
                                              rnti)) {
                 dl_req->number_dci++;
                 dl_req->number_pdu++;
                 dl_req->tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG;
                 eNB->DL_req[CC_id].sfn_sf = frameP<<4 | subframeP;
                 eNB->DL_req[CC_id].header.message_id = NFAPI_DL_CONFIG_REQUEST;
-                fill_nfapi_dlsch_config(eNB, 
-                                        dl_req, 
-                                        TBS, 
-                                        -1,   // retransmission, no pdu_index 
-                                        rnti, 
+                fill_nfapi_dlsch_config(eNB,
+                                        dl_req,
+                                        TBS,
+                                        -1,   // retransmission, no pdu_index
+                                        rnti,
                                         0,    // type 0 allocation from 7.1.6 in 36.213
                                         0,    // virtual_resource_block_assignment_flag, unused here
                                         0,    // resource_block_coding, to be filled in later
@@ -908,30 +908,30 @@ schedule_ue_spec(module_id_t module_idP,
                                         cc[CC_id].p_eNB == 1 ? 1 : 2,    // transmission mode
                                         0,    //number of PRBs treated as one subband, not used here
                                         0);   // number of beamforming vectors, not used here
-                                       
+
                 LOG_D(MAC, "Filled NFAPI configuration for DCI/DLSCH %d, retransmission round %d\n",
-                      eNB->pdu_index[CC_id], 
+                      eNB->pdu_index[CC_id],
                       round);
-                program_dlsch_acknak(module_idP, 
-                                     CC_id, 
-                                     UE_id, 
-                                     frameP, 
+                program_dlsch_acknak(module_idP,
+                                     CC_id,
+                                     UE_id,
+                                     frameP,
                                      subframeP,
                                      dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.cce_idx);
                 // No TX request for retransmission (check if null request for FAPI)
               } else {
                 LOG_W(MAC, "Frame %d, Subframe %d: Dropping DLSCH allocation for UE %d\%x, infeasible CCE allocation\n",
-                      frameP, 
-                      subframeP, 
-                      UE_id, 
+                      frameP,
+                      subframeP,
+                      UE_id,
                       rnti);
               }
           }
 
-          add_ue_dlsch_info(module_idP, 
-                            CC_id, UE_id, 
-                            subframeP, 
-                            S_DL_SCHEDULED, 
+          add_ue_dlsch_info(module_idP,
+                            CC_id, UE_id,
+                            subframeP,
+                            S_DL_SCHEDULED,
                             rnti);
           //eNB_UE_stats->dlsch_trials[round]++;
           eNB_UE_stats->num_retransmission += 1;
@@ -941,16 +941,16 @@ schedule_ue_spec(module_id_t module_idP,
         } else {
           LOG_D(MAC,
                 "[eNB %d] Frame %d CC_id %d : don't schedule UE %d, its retransmission takes more resources than we have\n",
-                module_idP, 
-                frameP, 
-                CC_id, 
+                module_idP,
+                frameP,
+                CC_id,
                 UE_id);
         }
       } else {    /* This is a potentially new SDU opportunity */
         rlc_status.bytes_in_buffer = 0;
         // Now check RLC information to compute number of required RBs
         // get maximum TBS size for RLC request
-        TBS = get_TBS_DL(eNB_UE_stats->dlsch_mcs1, 
+        TBS = get_TBS_DL(eNB_UE_stats->dlsch_mcs1,
                          nb_available_rb);
 
         // add the length for  all the control elements (timing adv, drx, etc) : header + payload
@@ -972,13 +972,13 @@ schedule_ue_spec(module_id_t module_idP,
 
         // RLC data on DCCH
         if (TBS - ta_len - header_length_total - sdu_length_total - 3 > 0) {
-          rlc_status = mac_rlc_status_ind(module_idP, 
-                                          rnti, 
-                                          module_idP, 
-                                          frameP, 
-                                          subframeP, 
-                                          ENB_FLAG_YES, 
-                                          MBMS_FLAG_NO, 
+          rlc_status = mac_rlc_status_ind(module_idP,
+                                          rnti,
+                                          module_idP,
+                                          frameP,
+                                          subframeP,
+                                          ENB_FLAG_YES,
+                                          MBMS_FLAG_NO,
                                           DCCH,
                                           TBS - ta_len - header_length_total - sdu_length_total - 3
 #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
@@ -990,17 +990,17 @@ schedule_ue_spec(module_id_t module_idP,
 
           if (rlc_status.bytes_in_buffer > 0) {
             LOG_D(MAC, "[eNB %d] SFN/SF %d.%d, DL-DCCH->DLSCH CC_id %d, Requesting %d bytes from RLC (RRC message)\n",
-                  module_idP, 
-                  frameP, 
-                  subframeP, 
+                  module_idP,
+                  frameP,
+                  subframeP,
                   CC_id,
                   TBS - ta_len - header_length_total - sdu_length_total - 3);
-            sdu_lengths[0] = mac_rlc_data_req(module_idP, 
-                                              rnti, 
-                                              module_idP, 
-                                              frameP, 
-                                              ENB_FLAG_YES, 
-                                              MBMS_FLAG_NO, 
+            sdu_lengths[0] = mac_rlc_data_req(module_idP,
+                                              rnti,
+                                              module_idP,
+                                              frameP,
+                                              ENB_FLAG_YES,
+                                              MBMS_FLAG_NO,
                                               DCCH,
                                               TBS, //not used
                                               (char *)&dlsch_buffer[0]
@@ -1014,8 +1014,8 @@ schedule_ue_spec(module_id_t module_idP,
             if((rrc_release_info.num_UEs > 0) && (rlc_am_mui.rrc_mui_num > 0)) {
               uint16_t release_total = 0;
 
-              for (release_num = 0, release_ctrl = &rrc_release_info.RRC_release_ctrl[0]; 
-                   release_num < NUMBER_OF_UE_MAX; 
+              for (release_num = 0, release_ctrl = &rrc_release_info.RRC_release_ctrl[0];
+                   release_num < NUMBER_OF_UE_MAX;
                    release_num++, release_ctrl++) {
                 if(release_ctrl->flag > 0) {
                   release_total++;
@@ -1074,18 +1074,18 @@ schedule_ue_spec(module_id_t module_idP,
               }
             }
 
-            T(T_ENB_MAC_UE_DL_SDU, 
+            T(T_ENB_MAC_UE_DL_SDU,
               T_INT(module_idP),
-              T_INT(CC_id), 
-              T_INT(rnti), 
+              T_INT(CC_id),
+              T_INT(rnti),
               T_INT(frameP),
-              T_INT(subframeP), 
-              T_INT(harq_pid), 
+              T_INT(subframeP),
+              T_INT(harq_pid),
               T_INT(DCCH),
               T_INT(sdu_lengths[0]));
             LOG_D(MAC, "[eNB %d][DCCH] CC_id %d Got %d bytes from RLC\n",
-                  module_idP, 
-                  CC_id, 
+                  module_idP,
+                  CC_id,
                   sdu_lengths[0]);
             sdu_length_total = sdu_lengths[0];
             sdu_lcids[0] = DCCH;
@@ -1098,11 +1098,11 @@ schedule_ue_spec(module_id_t module_idP,
             num_sdus = 1;
 #ifdef DEBUG_eNB_SCHEDULER
             LOG_T(MAC, "[eNB %d][DCCH] CC_id %d Got %d bytes :",
-                  module_idP, 
-                  CC_id, 
+                  module_idP,
+                  CC_id,
                   sdu_lengths[0]);
             for (j = 0; j < sdu_lengths[0]; ++j) {
-              LOG_T(MAC, "%x ", 
+              LOG_T(MAC, "%x ",
                     dlsch_buffer[j]);
             }
             LOG_T(MAC, "\n");
@@ -1112,13 +1112,13 @@ schedule_ue_spec(module_id_t module_idP,
 
         // RLC data on DCCH1
         if (TBS - ta_len - header_length_total - sdu_length_total - 3 > 0) {
-          rlc_status = mac_rlc_status_ind(module_idP, 
-                                          rnti, 
-                                          module_idP, 
-                                          frameP, 
-                                          subframeP, 
-                                          ENB_FLAG_YES, 
-                                          MBMS_FLAG_NO, 
+          rlc_status = mac_rlc_status_ind(module_idP,
+                                          rnti,
+                                          module_idP,
+                                          frameP,
+                                          subframeP,
+                                          ENB_FLAG_YES,
+                                          MBMS_FLAG_NO,
                                           DCCH + 1,
                                           TBS - ta_len - header_length_total - sdu_length_total - 3
 #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
@@ -1133,11 +1133,11 @@ schedule_ue_spec(module_id_t module_idP,
             LOG_D(MAC, "[eNB %d], Frame %d, DCCH1->DLSCH, CC_id %d, Requesting %d bytes from RLC (RRC message)\n",
                   module_idP, frameP, CC_id,
                   TBS - ta_len - header_length_total - sdu_length_total - 3);
-            sdu_lengths[num_sdus] += mac_rlc_data_req(module_idP, 
-                                                      rnti, 
-                                                      module_idP, 
-                                                      frameP, 
-                                                      ENB_FLAG_YES, 
+            sdu_lengths[num_sdus] += mac_rlc_data_req(module_idP,
+                                                      rnti,
+                                                      module_idP,
+                                                      frameP,
+                                                      ENB_FLAG_YES,
                                                       MBMS_FLAG_NO, DCCH + 1,
                                                       TBS, //not used
                                                       (char *) &dlsch_buffer[sdu_length_total]
@@ -1146,14 +1146,14 @@ schedule_ue_spec(module_id_t module_idP,
                                                       , 0
 #endif
                                                       );
-            T(T_ENB_MAC_UE_DL_SDU, 
+            T(T_ENB_MAC_UE_DL_SDU,
               T_INT(module_idP),
-              T_INT(CC_id), 
-              T_INT(rnti), 
+              T_INT(CC_id),
+              T_INT(rnti),
               T_INT(frameP),
-              T_INT(subframeP), 
+              T_INT(subframeP),
               T_INT(harq_pid),
-              T_INT(DCCH + 1), 
+              T_INT(DCCH + 1),
               T_INT(sdu_lengths[num_sdus]));
             sdu_lcids[num_sdus] = DCCH1;
             sdu_length_total += sdu_lengths[num_sdus];
@@ -1166,11 +1166,11 @@ schedule_ue_spec(module_id_t module_idP,
             num_sdus++;
 #ifdef DEBUG_eNB_SCHEDULER
             LOG_T(MAC, "[eNB %d][DCCH1] CC_id %d Got %d bytes :",
-                  module_idP, 
-                  CC_id, 
+                  module_idP,
+                  CC_id,
                   sdu_lengths[num_sdus]);
             for (j = 0; j < sdu_lengths[num_sdus]; ++j) {
-              LOG_T(MAC, "%x ", 
+              LOG_T(MAC, "%x ",
                     dlsch_buffer[j]);
             }
             LOG_T(MAC, "\n");
@@ -1291,13 +1291,13 @@ schedule_ue_spec(module_id_t module_idP,
 
             if (nb_rb > nb_available_rb) {  // if we've gone beyond the maximum number of RBs
               // (can happen if N_RB_DL is odd)
-              TBS = get_TBS_DL(eNB_UE_stats->dlsch_mcs1, 
+              TBS = get_TBS_DL(eNB_UE_stats->dlsch_mcs1,
                                nb_available_rb);
               nb_rb = nb_available_rb;
               break;
             }
 
-            TBS = get_TBS_DL(eNB_UE_stats->dlsch_mcs1, 
+            TBS = get_TBS_DL(eNB_UE_stats->dlsch_mcs1,
                              nb_rb);
           }
 
@@ -1327,26 +1327,26 @@ schedule_ue_spec(module_id_t module_idP,
           // decrease mcs until TBS falls below required length
           while ((TBS > sdu_length_total + header_length_total + ta_len) && (mcs > 0)) {
             mcs--;
-            TBS = get_TBS_DL(mcs, 
+            TBS = get_TBS_DL(mcs,
                              nb_rb);
           }
 
           // if we have decreased too much or we don't have enough RBs, increase MCS
-          while (TBS < sdu_length_total + header_length_total + ta_len && 
+          while (TBS < sdu_length_total + header_length_total + ta_len &&
                  ((ue_sched_ctrl->dl_pow_off[CC_id] > 0 && mcs < 28) || (ue_sched_ctrl->dl_pow_off[CC_id] == 0 && mcs <= 15))) {
             mcs++;
-            TBS = get_TBS_DL(mcs, 
+            TBS = get_TBS_DL(mcs,
                              nb_rb);
           }
 
           LOG_D(MAC, "dlsch_mcs before and after the rate matching = (%d, %d)\n",
-                eNB_UE_stats->dlsch_mcs1, 
+                eNB_UE_stats->dlsch_mcs1,
                 mcs);
 #ifdef DEBUG_eNB_SCHEDULER
           LOG_D(MAC, "[eNB %d] CC_id %d Generated DLSCH header (mcs %d, TBS %d, nb_rb %d)\n",
-                module_idP, 
-                CC_id, 
-                mcs, TBS, 
+                module_idP,
+                CC_id,
+                mcs, TBS,
                 nb_rb);
           // msg("[MAC][eNB ] Reminder of DLSCH with random data %d %d %d %d \n",
           //  TBS, sdu_length_total, offset, TBS-sdu_length_total-offset);
@@ -1363,31 +1363,31 @@ schedule_ue_spec(module_id_t module_idP,
           offset = generate_dlsch_header((unsigned char *) UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0],
                                          num_sdus,    //num_sdus
                                          sdu_lengths,    //
-                                         sdu_lcids, 
+                                         sdu_lcids,
                                          255,    // no drx
                                          ta_update,    // timing advance
                                          NULL,    // contention res id
-                                         padding, 
+                                         padding,
                                          post_padding);
 
           //#ifdef DEBUG_eNB_SCHEDULER
           if (ta_update != 31) {
-            LOG_D(MAC, 
+            LOG_D(MAC,
                   "[eNB %d][DLSCH] Frame %d Generate header for UE_id %d on CC_id %d: sdu_length_total %d, num_sdus %d, sdu_lengths[0] %d, sdu_lcids[0] %d => payload offset %d,timing advance value : %d, padding %d,post_padding %d,(mcs %d, TBS %d, nb_rb %d),header_length %d\n",
-                  module_idP, 
-                  frameP, 
-                  UE_id, 
+                  module_idP,
+                  frameP,
+                  UE_id,
                   CC_id,
-                  sdu_length_total, 
-                  num_sdus, 
+                  sdu_length_total,
+                  num_sdus,
                   sdu_lengths[0],
-                  sdu_lcids[0], 
-                  offset, 
-                  ta_update, 
+                  sdu_lcids[0],
+                  offset,
+                  ta_update,
                   padding,
-                  post_padding, 
-                  mcs, 
-                  TBS, 
+                  post_padding,
+                  mcs,
+                  TBS,
                   nb_rb,
                   header_length_total);
           }
@@ -1396,15 +1396,15 @@ schedule_ue_spec(module_id_t module_idP,
 #ifdef DEBUG_eNB_SCHEDULER
           LOG_T(MAC, "[eNB %d] First 16 bytes of DLSCH : \n");
           for (i = 0; i < 16; i++) {
-            LOG_T(MAC, "%x.", 
+            LOG_T(MAC, "%x.",
                   dlsch_buffer[i]);
           }
           LOG_T(MAC, "\n");
 #endif
           // cycle through SDUs and place in dlsch_buffer
           dlsch_pdu = &UE_list->DLSCH_pdu[CC_id][0][UE_id];
-          memcpy(&dlsch_pdu->payload[0][offset], 
-                 dlsch_buffer, 
+          memcpy(&dlsch_pdu->payload[0][offset],
+                 dlsch_buffer,
                  sdu_length_total);
           // memcpy(RC.mac[0].DLSCH_pdu[0][0].payload[0][offset],dcch_buffer,sdu_lengths[0]);
 
@@ -1416,39 +1416,39 @@ schedule_ue_spec(module_id_t module_idP,
           if (opt_enabled == 1) {
             trace_pdu(DIRECTION_DOWNLINK,
                       (uint8_t *) dlsch_pdu->payload[0],
-                      TBS, 
-                      module_idP, 
+                      TBS,
+                      module_idP,
                       WS_C_RNTI,
-                      UE_RNTI(module_idP, 
-                              UE_id), 
+                      UE_RNTI(module_idP,
+                              UE_id),
                       eNB->frame,
-                      eNB->subframe, 
-                      0, 
+                      eNB->subframe,
+                      0,
                       0);
             LOG_D(OPT, "[eNB %d][DLSCH] CC_id %d Frame %d  rnti %x  with size %d\n",
-                  module_idP, 
-                  CC_id, 
+                  module_idP,
+                  CC_id,
                   frameP,
-                  UE_RNTI(module_idP, 
-                          UE_id), 
+                  UE_RNTI(module_idP,
+                          UE_id),
                   TBS);
           }
 
-          T(T_ENB_MAC_UE_DL_PDU_WITH_DATA, 
+          T(T_ENB_MAC_UE_DL_PDU_WITH_DATA,
             T_INT(module_idP),
-            T_INT(CC_id), 
-            T_INT(rnti), 
+            T_INT(CC_id),
+            T_INT(rnti),
             T_INT(frameP),
-            T_INT(subframeP), 
+            T_INT(subframeP),
             T_INT(harq_pid),
-            T_BUFFER(dlsch_pdu->payload[0], 
+            T_BUFFER(dlsch_pdu->payload[0],
                      TBS));
           ue_template->nb_rb[harq_pid] = nb_rb;
-          add_ue_dlsch_info(module_idP, 
-                            CC_id, 
-                            UE_id, 
-                            subframeP, 
-                            S_DL_SCHEDULED, 
+          add_ue_dlsch_info(module_idP,
+                            CC_id,
+                            UE_id,
+                            subframeP,
+                            S_DL_SCHEDULED,
                             rnti);
           // store stats
           eNB->eNB_stats[CC_id].dlsch_bytes_tx += sdu_length_total;
@@ -1465,8 +1465,8 @@ schedule_ue_spec(module_id_t module_idP,
 
           if (cc[CC_id].tdd_Config != NULL) { // TDD
             ue_template->DAI++;
-            update_ul_dci(module_idP, 
-                          CC_id, 
+            update_ul_dci(module_idP,
+                          CC_id,
                           rnti,
                           ue_template->DAI,
                           subframeP);
@@ -1474,7 +1474,7 @@ schedule_ue_spec(module_id_t module_idP,
 
           // do PUCCH power control
           // this is the normalized RX power
-          // unit is not dBm, it's special from nfapi 
+          // unit is not dBm, it's special from nfapi
           // converting to dBm: ToDo: Noise power hard coded to 30
           normalized_rx_power = (((5 * ue_sched_ctrl->pucch1_snr[CC_id]) - 640) / 10) + 30;
           target_rx_power= (eNB->puCch10xSnr / 10) + 30;
@@ -1498,12 +1498,12 @@ schedule_ue_spec(module_id_t module_idP,
               }
 
               LOG_D(MAC, "[eNB %d] DLSCH scheduler: frame %d, subframe %d, harq_pid %d, tpc %d, normalized/target rx power %d/%d\n",
-                    module_idP, 
-                    frameP, 
-                    subframeP, 
-                    harq_pid, 
+                    module_idP,
+                    frameP,
+                    subframeP,
+                    harq_pid,
                     tpc,
-                    normalized_rx_power, 
+                    normalized_rx_power,
                     target_rx_power);
             } // Po_PUCCH has been updated
             else {
@@ -1514,16 +1514,16 @@ schedule_ue_spec(module_id_t module_idP,
           }
 
           dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu];
-          memset((void *) dl_config_pdu, 
-                 0, 
+          memset((void *) dl_config_pdu,
+                 0,
                  sizeof(nfapi_dl_config_request_pdu_t));
           dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE;
           dl_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_dl_config_dci_dl_pdu));
           dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format = NFAPI_DL_DCI_FORMAT_1;
           dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level =
-            get_aggregation(get_bw_index(module_idP, 
-                                        CC_id), 
-                            ue_sched_ctrl->dl_cqi[CC_id], 
+            get_aggregation(get_bw_index(module_idP,
+                                        CC_id),
+                            ue_sched_ctrl->dl_cqi[CC_id],
                             format1);
           dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL8_TAG;
           dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti = rnti;
@@ -1541,27 +1541,27 @@ schedule_ue_spec(module_id_t module_idP,
           if (cc[CC_id].tdd_Config != NULL) {    //TDD
             dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.downlink_assignment_index = (ue_template->DAI - 1) & 3;
             LOG_D(MAC, "[eNB %d] Initial transmission CC_id %d : harq_pid %d, dai %d, mcs %d\n",
-                  module_idP, 
-                  CC_id, 
+                  module_idP,
+                  CC_id,
                   harq_pid,
                   (ue_template->DAI - 1),
                   mcs);
           } else {
             LOG_D(MAC, "[eNB %d] Initial transmission CC_id %d : harq_pid %d, mcs %d\n",
-                  module_idP, 
-                  CC_id, 
-                  harq_pid, 
+                  module_idP,
+                  CC_id,
+                  harq_pid,
                   mcs);
           }
 
           LOG_D(MAC, "Checking feasibility pdu %d (new sdu)\n",
                 dl_req->number_pdu);
 
-          if (!CCE_allocation_infeasible(module_idP, 
-                                         CC_id, 
-                                         1, 
+          if (!CCE_allocation_infeasible(module_idP,
+                                         CC_id,
+                                         1,
                                          subframeP,
-                                         dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level, 
+                                         dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level,
                                          rnti)) {
             ue_sched_ctrl->round[CC_id][harq_pid] = 0;
             dl_req->number_dci++;
@@ -1571,11 +1571,11 @@ schedule_ue_spec(module_id_t module_idP,
             eNB->DL_req[CC_id].header.message_id = NFAPI_DL_CONFIG_REQUEST;
             // Toggle NDI for next time
             LOG_D(MAC, "CC_id %d Frame %d, subframeP %d: Toggling Format1 NDI for UE %d (rnti %x/%d) oldNDI %d\n",
-                  CC_id, 
-                  frameP, 
-                  subframeP, 
-                  UE_id, 
-                  rnti, 
+                  CC_id,
+                  frameP,
+                  subframeP,
+                  UE_id,
+                  rnti,
                   harq_pid,
                   ue_template->oldNDI[harq_pid]);
             ue_template->oldNDI[harq_pid] = 1 - ue_template->oldNDI[harq_pid];
@@ -1584,15 +1584,15 @@ schedule_ue_spec(module_id_t module_idP,
             AssertFatal(ue_template->physicalConfigDedicated != NULL, "physicalConfigDedicated is NULL\n");
             AssertFatal(ue_template->physicalConfigDedicated->pdsch_ConfigDedicated != NULL,
                         "physicalConfigDedicated->pdsch_ConfigDedicated is NULL\n");
-            fill_nfapi_dlsch_config(eNB, 
-                                    dl_req, 
-                                    TBS, 
-                                    eNB->pdu_index[CC_id], 
-                                    rnti, 
+            fill_nfapi_dlsch_config(eNB,
+                                    dl_req,
+                                    TBS,
+                                    eNB->pdu_index[CC_id],
+                                    rnti,
                                     0, // type 0 allocation from 7.1.6 in 36.213
                                     0,  // virtual_resource_block_assignment_flag, unused here
                                     0,  // resource_block_coding, to be filled in later
-                                    getQm(mcs), 
+                                    getQm(mcs),
                                     0,  // redundancy version
                                     1,  // transport blocks
                                     0,  // transport block to codeword swap flag
@@ -1601,33 +1601,33 @@ schedule_ue_spec(module_id_t module_idP,
                                     1,  // number of subbands
                                     //                       uint8_t codebook_index,
                                     4,  // UE category capacity
-                                    ue_template->physicalConfigDedicated->pdsch_ConfigDedicated->p_a, 
+                                    ue_template->physicalConfigDedicated->pdsch_ConfigDedicated->p_a,
                                     0,  // delta_power_offset for TM5
                                     0,  // ngap
                                     0,  // nprb
                                     cc[CC_id].p_eNB == 1 ? 1 : 2, // transmission mode
                                     0,  //number of PRBs treated as one subband, not used here
                                     0); // number of beamforming vectors, not used here
-                                    
+
             eNB->TX_req[CC_id].sfn_sf = fill_nfapi_tx_req(&eNB->TX_req[CC_id].tx_request_body,
                                                           (frameP * 10) + subframeP,
-                                                          TBS, 
+                                                          TBS,
                                                           eNB->pdu_index[CC_id],
                                                           dlsch_pdu->payload[0]);
             LOG_D(MAC, "Filled NFAPI configuration for DCI/DLSCH/TXREQ %d, new SDU\n",
                   eNB->pdu_index[CC_id]);
             eNB->pdu_index[CC_id]++;
-            program_dlsch_acknak(module_idP, 
-                                 CC_id, 
+            program_dlsch_acknak(module_idP,
+                                 CC_id,
                                  UE_id,
-                                 frameP, 
+                                 frameP,
                                  subframeP,
                                  dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.cce_idx);
           } else {
             LOG_W(MAC, "Frame %d, Subframe %d: Dropping DLSCH allocation for UE %d/%x, infeasible CCE allocations\n",
-                  frameP, 
-                  subframeP, 
-                  UE_id, 
+                  frameP,
+                  subframeP,
+                  UE_id,
                   rnti);
           }
         } else {  // There is no data from RLC or MAC header, so don't schedule
@@ -1635,26 +1635,26 @@ schedule_ue_spec(module_id_t module_idP,
       }
 
       if (cc[CC_id].tdd_Config != NULL) {    // TDD
-        set_ul_DAI(module_idP, 
-                   UE_id, 
-                   CC_id, 
-                   frameP, 
+        set_ul_DAI(module_idP,
+                   UE_id,
+                   CC_id,
+                   frameP,
                    subframeP);
       }
     }     // UE_id loop
   }       // CC_id loop
 
-  fill_DLSCH_dci(module_idP, 
-                 frameP, 
-                 subframeP, 
+  fill_DLSCH_dci(module_idP,
+                 frameP,
+                 subframeP,
                  mbsfn_flag);
   stop_meas(&eNB->schedule_dlsch);
-  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_SCHEDULE_DLSCH, 
+  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_SCHEDULE_DLSCH,
                                           VCD_FUNCTION_OUT);
 }
 
 //------------------------------------------------------------------------------
-void 
+void
 dlsch_scheduler_interslice_multiplexing(module_id_t Mod_id,
                                         int frameP,
                                         sub_frame_t subframeP,
@@ -1680,7 +1680,7 @@ dlsch_scheduler_interslice_multiplexing(module_id_t Mod_id,
   uint16_t (*nb_rbs_remaining)[MAX_MOBILES_PER_ENB];
   uint16_t (*nb_rbs_required)[MAX_MOBILES_PER_ENB];
   uint8_t  (*MIMO_mode_indicator)[N_RBG_MAX];
-   
+
   // Initialize the free RBGs map
   // free_rbgs_map[CC_id][rbg] = -1 if RBG is allocated,
   // otherwise it contains the id of the slice it belongs to.
@@ -1718,14 +1718,14 @@ dlsch_scheduler_interslice_multiplexing(module_id_t Mod_id,
     }
   }
 
-  slice_priority_sort(Mod_id, 
+  slice_priority_sort(Mod_id,
                       slice_sorted_list);
 
   // MULTIPLEXING
   // This part is an adaptation of dlsch_scheduler_pre_processor_allocate() code
   for (CC_id = 0; CC_id < nb_mac_CC; ++CC_id) {
     N_RB_DL = to_prb(eNB->common_channels[CC_id].mib->message.dl_Bandwidth);
-    min_rb_unit = get_min_rb_unit(Mod_id, 
+    min_rb_unit = get_min_rb_unit(Mod_id,
                                   CC_id);
 
     for (i = 0; i < sli->n_dl; ++i) {
@@ -1754,9 +1754,9 @@ dlsch_scheduler_interslice_multiplexing(module_id_t Mod_id,
       // Sort UE again
       // (UE list gets sorted every time pre_processor is called so it is probably dirty at this point)
       // FIXME: There is only one UE_list for all slices, so it must be sorted again each time we use it
-      sort_UEs(Mod_id, 
-               slice_idx, 
-               frameP, 
+      sort_UEs(Mod_id,
+               slice_idx,
+               frameP,
                subframeP);
       nb_rbs_remaining = sli->pre_processor_results[slice_idx].nb_rbs_remaining;
       nb_rbs_required = sli->pre_processor_results[slice_idx].nb_rbs_required;
@@ -1765,8 +1765,8 @@ dlsch_scheduler_interslice_multiplexing(module_id_t Mod_id,
       // Allocation
       for (UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) {
         ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id];
-        tm = get_tmode(Mod_id, 
-                       CC_id, 
+        tm = get_tmode(Mod_id,
+                       CC_id,
                        UE_id);
 
         for (rbg = 0; rbg < N_RBG[CC_id]; ++rbg) {
@@ -1825,7 +1825,7 @@ dlsch_scheduler_interslice_multiplexing(module_id_t Mod_id,
 void dlsch_scheduler_qos_multiplexing(module_id_t Mod_id, int frameP, sub_frame_t subframeP)
 //------------------------------------------------------------------------------
 {
-  // int UE_id; 
+  // int UE_id;
   int CC_id, i;
   // UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list;
   slice_info_t *sli = &RC.mac[Mod_id]->slice_info;
@@ -1835,9 +1835,9 @@ void dlsch_scheduler_qos_multiplexing(module_id_t Mod_id, int frameP, sub_frame_
     for (i = 0; i < sli->n_dl; i++) {
       // Sort UE again
       // FIXME: There is only one UE_list for all slices, so it must be sorted again each time we use it
-      sort_UEs(Mod_id, 
-               (uint8_t)i, 
-               frameP, 
+      sort_UEs(Mod_id,
+               (uint8_t)i,
+               frameP,
                subframeP);
       /*
       for (UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) {
@@ -1858,7 +1858,7 @@ void dlsch_scheduler_qos_multiplexing(module_id_t Mod_id, int frameP, sub_frame_
  */
 void
 schedule_ue_spec_br(module_id_t module_idP,
-		                frame_t     frameP,
+		    frame_t       frameP,
 		                sub_frame_t subframeP) 
 //------------------------------------------------------------------------------        
 {
@@ -1877,7 +1877,7 @@ schedule_ue_spec_br(module_id_t module_idP,
   uint16_t rnti = 0;
   uint16_t padding = 0;
   uint16_t post_padding = 0;
-  uint16_t sdu_length_total = 0;
+  uint16_t                       sdu_length_total = 0;
 
   mac_rlc_status_resp_t rlc_status;
   rrc_eNB_ue_context_t *ue_contextP = NULL;
@@ -1909,10 +1909,10 @@ schedule_ue_spec_br(module_id_t module_idP,
   struct LTE_PUCCH_ConfigCommon_v1310 *ext4_pucch = NULL;
   LTE_PRACH_ParametersListCE_r13_t *prach_ParametersListCE_r13 = NULL;
   struct LTE_N1PUCCH_AN_InfoList_r13 *pucch_N1PUCCH_AN_InfoList_r13 = NULL;
-  int pucchreps[4] = { 1, 1, 1, 1 };
-  int n1pucchan[4] = { 0, 0, 0, 0 }; 
-  uint32_t ackNAK_absSF;
-  int first_rb;
+  int             pucchreps[4] = { 1, 1, 1, 1 };
+  int             n1pucchan[4] = { 0, 0, 0, 0 };
+  uint32_t        ackNAK_absSF;
+  int             first_rb;
 
   dl_req = &(mac->DL_req[CC_id].dl_config_request_body);
   dl_config_pdu = &(dl_req->dl_config_pdu_list[dl_req->number_pdu]);
@@ -1938,26 +1938,26 @@ schedule_ue_spec_br(module_id_t module_idP,
     AssertFatal (prach_ParametersListCE_r13->list.count == pucch_N1PUCCH_AN_InfoList_r13->list.count, "prach_ParametersListCE_r13->list.count!= pucch_N1PUCCH_AN_InfoList_r13->list.count\n");
 
     switch (prach_ParametersListCE_r13->list.count) {
-      case 4:
-        n1pucchan[3] = *pucch_N1PUCCH_AN_InfoList_r13->list.array[3];
-        AssertFatal (ext4_pucch->pucch_NumRepetitionCE_Msg4_Level3_r13 != NULL, "pucch_NumRepetitionCE_Msg4_Level3 shouldn't be NULL\n");
-        pucchreps[3] = (int) (4 << *ext4_pucch->pucch_NumRepetitionCE_Msg4_Level3_r13);
+    case 4:
+      n1pucchan[3] = *pucch_N1PUCCH_AN_InfoList_r13->list.array[3];
+      AssertFatal (ext4_pucch->pucch_NumRepetitionCE_Msg4_Level3_r13 != NULL, "pucch_NumRepetitionCE_Msg4_Level3 shouldn't be NULL\n");
+      pucchreps[3] = (int) (4 << *ext4_pucch->pucch_NumRepetitionCE_Msg4_Level3_r13);
 
-      case 3:
-        n1pucchan[2] = *pucch_N1PUCCH_AN_InfoList_r13->list.array[2];
-        AssertFatal (ext4_pucch->pucch_NumRepetitionCE_Msg4_Level2_r13 != NULL, "pucch_NumRepetitionCE_Msg4_Level2 shouldn't be NULL\n");
-        pucchreps[2] = (int) (4 << *ext4_pucch->pucch_NumRepetitionCE_Msg4_Level2_r13);
-      case 2:
-        n1pucchan[1] = *pucch_N1PUCCH_AN_InfoList_r13->list.array[1];
-        AssertFatal (ext4_pucch->pucch_NumRepetitionCE_Msg4_Level1_r13 != NULL, "pucch_NumRepetitionCE_Msg4_Level1 shouldn't be NULL\n");
-        pucchreps[1] = (int) (1 << *ext4_pucch->pucch_NumRepetitionCE_Msg4_Level1_r13);
-      case 1:
-        n1pucchan[0] = *pucch_N1PUCCH_AN_InfoList_r13->list.array[0];
-        AssertFatal (ext4_pucch->pucch_NumRepetitionCE_Msg4_Level0_r13 != NULL, "pucch_NumRepetitionCE_Msg4_Level0 shouldn't be NULL\n");
-        pucchreps[0] = (int) (1 << *ext4_pucch->pucch_NumRepetitionCE_Msg4_Level0_r13);
-        break;
-      default:
-        AssertFatal (1 == 0, "Illegal count for prach_ParametersListCE_r13 %d\n", prach_ParametersListCE_r13->list.count);
+    case 3:
+      n1pucchan[2] = *pucch_N1PUCCH_AN_InfoList_r13->list.array[2];
+      AssertFatal (ext4_pucch->pucch_NumRepetitionCE_Msg4_Level2_r13 != NULL, "pucch_NumRepetitionCE_Msg4_Level2 shouldn't be NULL\n");
+      pucchreps[2] = (int) (4 << *ext4_pucch->pucch_NumRepetitionCE_Msg4_Level2_r13);
+    case 2:
+      n1pucchan[1] = *pucch_N1PUCCH_AN_InfoList_r13->list.array[1];
+      AssertFatal (ext4_pucch->pucch_NumRepetitionCE_Msg4_Level1_r13 != NULL, "pucch_NumRepetitionCE_Msg4_Level1 shouldn't be NULL\n");
+      pucchreps[1] = (int) (1 << *ext4_pucch->pucch_NumRepetitionCE_Msg4_Level1_r13);
+    case 1:
+      n1pucchan[0] = *pucch_N1PUCCH_AN_InfoList_r13->list.array[0];
+      AssertFatal (ext4_pucch->pucch_NumRepetitionCE_Msg4_Level0_r13 != NULL, "pucch_NumRepetitionCE_Msg4_Level0 shouldn't be NULL\n");
+      pucchreps[0] = (int) (1 << *ext4_pucch->pucch_NumRepetitionCE_Msg4_Level0_r13);
+      break;
+    default:
+      AssertFatal (1 == 0, "Illegal count for prach_ParametersListCE_r13 %d\n", prach_ParametersListCE_r13->list.count);
     }
   }
 
@@ -1976,7 +1976,7 @@ schedule_ue_spec_br(module_id_t module_idP,
     if (UE_template->rach_resource_type == 0) {
       continue;
     }
-    
+
     uint8_t rrc_status = mac_eNB_get_rrc_status(module_idP, rnti);
 
     if (rrc_status < RRC_CONNECTED) {
@@ -1988,10 +1988,10 @@ schedule_ue_spec_br(module_id_t module_idP,
     AssertFatal (UE_template->physicalConfigDedicated != NULL, "UE_template->physicalConfigDedicated is null\n");
     AssertFatal (UE_template->physicalConfigDedicated->ext4 != NULL, "UE_template->physicalConfigDedicated->ext4 is null\n");
     AssertFatal (UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11 != NULL, "UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11 is null\n");
-    AssertFatal (UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.present == LTE_EPDCCH_Config_r11__config_r11_PR_setup, 
-		             "UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.present != setup\n");
+    AssertFatal (UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.present == LTE_EPDCCH_Config_r11__config_r11_PR_setup,
+		 "UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.present != setup\n");
     AssertFatal (UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.setConfigToAddModList_r11 != NULL,
-		             "UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.setConfigToAddModList_r11 = NULL\n");
+		 "UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.setConfigToAddModList_r11 = NULL\n");
 
     LTE_EPDCCH_SetConfig_r11_t *epdcch_setconfig_r11 = UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.setConfigToAddModList_r11->list.array[0];
 
@@ -2000,11 +2000,11 @@ schedule_ue_spec_br(module_id_t module_idP,
     AssertFatal(epdcch_setconfig_r11->ext2->mpdcch_config_r13 != NULL, "epdcch_setconfig_r11->ext2->mpdcch_config_r13 is null");
     AssertFatal(epdcch_setconfig_r11->ext2->mpdcch_config_r13 != NULL, "epdcch_setconfig_r11->ext2->mpdcch_config_r13 is null");
     AssertFatal(epdcch_setconfig_r11->ext2->mpdcch_config_r13->present == LTE_EPDCCH_SetConfig_r11__ext2__mpdcch_config_r13_PR_setup, 
-		            "epdcch_setconfig_r11->ext2->mpdcch_config_r13->present is not setup\n");
+		"epdcch_setconfig_r11->ext2->mpdcch_config_r13->present is not setup\n");
     AssertFatal(epdcch_setconfig_r11->ext2->numberPRB_Pairs_v1310 != NULL, "epdcch_setconfig_r11->ext2->numberPRB_Pairs_v1310 is null");
     AssertFatal(epdcch_setconfig_r11->ext2->numberPRB_Pairs_v1310->present == LTE_EPDCCH_SetConfig_r11__ext2__numberPRB_Pairs_v1310_PR_setup, 
-		            "epdcch_setconfig_r11->ext2->numberPRB_Pairs_v1310->present is not setup\n");
-           
+		"epdcch_setconfig_r11->ext2->numberPRB_Pairs_v1310->present is not setup\n");
+
     /* Simple scheduler for 1 repetition, 1 HARQ */
     if (subframeP == 5) { // MPDCCH
       if (round_DL < 8) LOG_D(MAC, "MPDCCH round_DL = %d in frame %d subframe %d\n", round_DL, frameP, subframeP);
@@ -2040,13 +2040,13 @@ schedule_ue_spec_br(module_id_t module_idP,
           LOG_D(MAC, "Calling mac_rlc_status_ind for DCCH\n");
           
           rlc_status = mac_rlc_status_ind(module_idP,
-                                          rnti,
-                                          module_idP,
-                                          frameP,
-                                          subframeP,
-                                          ENB_FLAG_YES,
-                                          MBMS_FLAG_NO,
-                                          DCCH,
+					  rnti,
+					  module_idP,
+					  frameP,
+					  subframeP,
+					  ENB_FLAG_YES,
+					  MBMS_FLAG_NO,
+					  DCCH,
                                           (TBS-ta_len-header_len_dcch),
                                           0,
                                           0); // transport block set size
@@ -2055,19 +2055,19 @@ schedule_ue_spec_br(module_id_t module_idP,
 
           if (rlc_status.bytes_in_buffer > 0) {  // There is DCCH to transmit
             LOG_D(MAC, "[eNB %d] Frame %d, DL-DCCH->DLSCH CC_id %d, Requesting %d bytes from RLC (RRC message)\n",
-                  module_idP,
+					      module_idP,
                   frameP,
                   CC_id,
                   TBS-header_len_dcch);
 
             sdu_lengths[0] = mac_rlc_data_req(module_idP,
-                                              rnti,
-                                              module_idP,
-                                              frameP,
-                                              ENB_FLAG_YES,
-                                              MBMS_FLAG_NO,
-                                              DCCH,
-                                              TBS, //not used
+					      rnti,
+					      module_idP,
+					      frameP,
+					      ENB_FLAG_YES,
+					      MBMS_FLAG_NO,
+					      DCCH,
+					      TBS, //not used
                                               (char *)&dlsch_buffer[0],
                                               0,
                                               0);
@@ -2097,42 +2097,42 @@ schedule_ue_spec_br(module_id_t module_idP,
             sdu_length_total = 0;
           }
         }
-	
+
         /* Check for DCCH1 and update header information (assume 2 byte sub-header) */
         if (TBS - ta_len-header_len_dcch - sdu_length_total > 0) {
           rlc_status = mac_rlc_status_ind(module_idP,
-                                          rnti,
-                                          module_idP,
-                                          frameP,
-                                          subframeP,
-                                          ENB_FLAG_YES,
-                                          MBMS_FLAG_NO,
+					  rnti,
+					  module_idP,
+					  frameP,
+					  subframeP,
+					  ENB_FLAG_YES,
+					  MBMS_FLAG_NO,
                                           DCCH + 1,
                                           (TBS-ta_len-header_len_dcch-sdu_length_total),
                                           0, 
                                           0); // transport block set size less allocations for timing advance and DCCH SDU
 	        
-          sdu_lengths[num_sdus] = 0;
-	  
+	  sdu_lengths[num_sdus] = 0;
+
           if (rlc_status.bytes_in_buffer > 0) {
             LOG_D(MAC,"[eNB %d], Frame %d, DCCH1->DLSCH, CC_id %d, Requesting %d bytes from RLC (RRC message)\n",
-                  module_idP,
+						      module_idP,
                   frameP,
                   CC_id,
                   TBS-header_len_dcch - sdu_length_total);
 
             sdu_lengths[num_sdus] += mac_rlc_data_req(module_idP,
-                                                      rnti,
-                                                      module_idP,
-                                                      frameP,
-                                                      ENB_FLAG_YES,
-                                                      MBMS_FLAG_NO,
-                                                      DCCH+1,
-                                                      TBS, //not used
+						      rnti,
+						      module_idP,
+						      frameP,
+						      ENB_FLAG_YES,
+						      MBMS_FLAG_NO,
+						      DCCH+1,
+						      TBS, //not used
                                                       (char *)&dlsch_buffer[sdu_length_total],
                                                       0, 
                                                       0);
-	    
+
             T(T_ENB_MAC_UE_DL_SDU, 
               T_INT(module_idP), 
               T_INT(CC_id), 
@@ -2148,8 +2148,8 @@ schedule_ue_spec_br(module_id_t module_idP,
             header_len_dcch += 2;
             UE_list->eNB_UE_stats[CC_id][UE_id].num_pdu_tx[DCCH1] += 1;
             UE_list->eNB_UE_stats[CC_id][UE_id].num_bytes_tx[DCCH1] += sdu_lengths[num_sdus];
-	          num_sdus++;
-	        }
+	    num_sdus++;
+	  }
         }
 
       /* Assume the max dtch header size, and adjust it later */
@@ -2162,27 +2162,27 @@ schedule_ue_spec_br(module_id_t module_idP,
         header_len_dtch += 3; 
         header_len_dtch_last = 3;
 
-        LOG_D(MAC,"[eNB %d], Frame %d, DTCH%d->DLSCH, Checking RLC status (tbs %d, len %d)\n",
+	  LOG_D(MAC,"[eNB %d], Frame %d, DTCH%d->DLSCH, Checking RLC status (tbs %d, len %d)\n",
               module_idP,
               frameP,
               lcid,
               TBS,
               TBS - ta_len-header_len_dcch - sdu_length_total - header_len_dtch);
-        
+
         if (TBS - ta_len - header_len_dcch - sdu_length_total - header_len_dtch > 0) { // NN: > 2 ?
-          rlc_status = mac_rlc_status_ind(module_idP,
-                                          rnti,
-                                          module_idP,
-                                          frameP,
-                                          subframeP,
-                                          ENB_FLAG_YES,
-                                          MBMS_FLAG_NO,
-                                          lcid,
+	    rlc_status = mac_rlc_status_ind(module_idP,
+					    rnti,
+					    module_idP,
+					    frameP,
+					    subframeP,
+					    ENB_FLAG_YES,
+					    MBMS_FLAG_NO,
+					    lcid,
                                           TBS - ta_len - header_len_dcch - sdu_length_total - header_len_dtch,
                                           0,
                                           0);
-          
-          if (rlc_status.bytes_in_buffer > 0) {
+
+	    if (rlc_status.bytes_in_buffer > 0) {
             /* RRC inactivity LTE-M */
             /* Reset RRC inactivity timer after uplane activity */
             ue_contextP = rrc_eNB_get_ue_context(RC.rrc[module_idP], rnti);
@@ -2202,15 +2202,15 @@ schedule_ue_spec_br(module_id_t module_idP,
                       TBS - header_len_dcch - sdu_length_total - header_len_dtch,
                       lcid, 
                       header_len_dtch);
-            
-            sdu_lengths[num_sdus] = mac_rlc_data_req(module_idP,
-                                                    rnti,
-                                                    module_idP,
-                                                    frameP,
-                                                    ENB_FLAG_YES,
-                                                    MBMS_FLAG_NO,
-                                                    lcid,
-                                                    TBS,	//not used
+
+	      sdu_lengths[num_sdus] = mac_rlc_data_req(module_idP,
+						       rnti,
+						       module_idP,
+						       frameP,
+						       ENB_FLAG_YES,
+						       MBMS_FLAG_NO,
+						       lcid,
+						       TBS,	//not used
                                                     (char*) &dlsch_buffer[sdu_length_total],
                                                     0,
                                                     0);
@@ -2230,56 +2230,56 @@ schedule_ue_spec_br(module_id_t module_idP,
                   sdu_lengths[num_sdus],
                   lcid);
 
-            sdu_lcids[num_sdus] = lcid;
-            sdu_length_total += sdu_lengths[num_sdus];
+	      sdu_lcids[num_sdus] = lcid;
+	      sdu_length_total += sdu_lengths[num_sdus];
 
-            if (sdu_lengths[num_sdus] < 128) {
-              header_len_dtch--;
-              header_len_dtch_last--;
-            }
+	      if (sdu_lengths[num_sdus] < 128) {
+		header_len_dtch--;
+		header_len_dtch_last--;
+	      }
 
-            num_sdus++;
+	      num_sdus++;
           } else { // no data for this LCID
             header_len_dtch -= 3;
-          }
+	    }
         } else { // no TBS left
           header_len_dtch -= 3;
-          break;
-        }
+	    break;
+	  }
       } // for loop LCID
 
     if (header_len_dtch == 0) {
       header_len_dtch_last = 0;
-    }
+	}
 
     /* There is at least one SDU  */
     if ((sdu_length_total + header_len_dcch + header_len_dtch) > 0) {
       /* Now compute number of required RBs for total sdu length */
       /* Assume RAH format 2 */
       /* Adjust  header lengths */
-      header_len_dcch_tmp = header_len_dcch;
-      header_len_dtch_tmp = header_len_dtch;
+	  header_len_dcch_tmp = header_len_dcch;
+	  header_len_dtch_tmp = header_len_dtch;
       
       if (header_len_dtch == 0) {
         header_len_dcch = (header_len_dcch > 0) ? 1 : 0; // remove length field
-      } else {
+	  } else {
         header_len_dtch_last -= 1; // now use it to find how many bytes has to be removed for the last MAC SDU 
         header_len_dtch = (header_len_dtch > 0) ? header_len_dtch - header_len_dtch_last : header_len_dtch; // remove length field for the last SDU
-      }
+	  }
 
-      mcs = 9;
+          mcs = 9;
 
       /* Decrease mcs until TBS falls below required length */
-      while ((TBS > (sdu_length_total + header_len_dcch + header_len_dtch + ta_len)) && (mcs>0)) {
-        mcs--;
-        TBS = get_TBS_DL(mcs,6);
-      }
+          while ((TBS > (sdu_length_total + header_len_dcch + header_len_dtch + ta_len)) && (mcs>0)) {
+            mcs--;
+            TBS = get_TBS_DL(mcs,6);
+          }
 
       /* If we have decreased too much or we don't have enough RBs, increase MCS */
-      while (TBS < (sdu_length_total + header_len_dcch + header_len_dtch + ta_len)) {
-        mcs++;
-        TBS = get_TBS_DL(mcs,6);
-      }
+          while (TBS < (sdu_length_total + header_len_dcch + header_len_dtch + ta_len)) {
+            mcs++;
+            TBS = get_TBS_DL(mcs,6);
+          }
 
       LOG_D(MAC, "[eNB %d] CC_id %d Generated DLSCH header (mcs %d, TBS %d, nb_rb %d)\n",
             module_idP,
@@ -2287,35 +2287,35 @@ schedule_ue_spec_br(module_id_t module_idP,
             mcs,
             TBS,
             6);
-            
-      if ((TBS - header_len_dcch - header_len_dtch - sdu_length_total - ta_len) <= 2) {
-        padding = (TBS - header_len_dcch - header_len_dtch - sdu_length_total - ta_len);
-        post_padding = 0;
-      } else {
-        padding = 0;
+
+          if ((TBS - header_len_dcch - header_len_dtch - sdu_length_total - ta_len) <= 2) {
+            padding = (TBS - header_len_dcch - header_len_dtch - sdu_length_total - ta_len);
+            post_padding = 0;
+          } else {
+            padding = 0;
 
         /* Adjust the header len */
         if (header_len_dtch == 0) {
-          header_len_dcch = header_len_dcch_tmp;
+              header_len_dcch = header_len_dcch_tmp;
         } else { // if ((header_len_dcch==0)&&((header_len_dtch==1)||(header_len_dtch==2)))
-          header_len_dtch = header_len_dtch_tmp;
-        }
+              header_len_dtch = header_len_dtch_tmp;
+            }
 
         post_padding = TBS - sdu_length_total - header_len_dcch - header_len_dtch - ta_len; // 1 is for the postpadding header
-      }
+          }
 
-      offset = generate_dlsch_header((unsigned char*)UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0],
-                                      num_sdus,     //num_sdus
-                                      sdu_lengths,  //
-                                      sdu_lcids,
-                                      255,          // no drx
-                                      ta_update,    // timing advance
-                                      NULL,         // contention res id
-                                      padding,
-                                      post_padding);
+          offset = generate_dlsch_header((unsigned char*)UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0],
+                                         num_sdus,              //num_sdus
+                                         sdu_lengths,  //
+                                         sdu_lcids,
+                                         255,                                   // no drx
+                                         ta_update, // timing advance
+                                         NULL,                                  // contention res id
+                                         padding,
+                                         post_padding);
 
 
-      if (ta_update != 31) {
+          if (ta_update != 31) {
         LOG_D(MAC,"[eNB %d][DLSCH] Frame %d Generate header for UE_id %d on CC_id %d: sdu_length_total %d, num_sdus %d, sdu_lengths[0] %d, sdu_lcids[0] %d => payload offset %d,timing advance value : %d, padding %d,post_padding %d,(mcs %d, TBS %d, nb_rb %d),header_dcch %d, header_dtch %d\n",
               module_idP,
               frameP, 
@@ -2334,17 +2334,17 @@ schedule_ue_spec_br(module_id_t module_idP,
               6,
               header_len_dcch,
               header_len_dtch);
-	    }
+	  }
 
       /* Cycle through SDUs and place in dlsch_buffer */
       memcpy(&UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0][offset], dlsch_buffer, sdu_length_total);
-      
+
       /* Fill remainder of DLSCH with random data */
       for (j = 0; j < (TBS - sdu_length_total - offset); j++) {
         UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0][offset + sdu_length_total + j] = (char)(taus()&0xff);
-      }
+          }
 
-      if (opt_enabled == 1) {
+          if (opt_enabled == 1) {
         trace_pdu(1, 
                   (uint8_t *)UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0],
                   TBS, 
@@ -2356,13 +2356,13 @@ schedule_ue_spec_br(module_id_t module_idP,
                   0,
                   0);
 
-        LOG_D(OPT,"[eNB %d][DLSCH] CC_id %d Frame %d  rnti %x  with size %d\n",
+            LOG_D(OPT,"[eNB %d][DLSCH] CC_id %d Frame %d  rnti %x  with size %d\n",
               module_idP, 
               CC_id, 
               frameP, 
               UE_RNTI(module_idP, UE_id), 
               TBS);
-      }
+          }
 
       T(T_ENB_MAC_UE_DL_PDU_WITH_DATA, 
         T_INT(module_idP), 
@@ -2375,10 +2375,10 @@ schedule_ue_spec_br(module_id_t module_idP,
 
 	    /* Do PUCCH power control */
       /* This is the normalized RX power */
-      /* TODO: fix how we deal with power, unit is not dBm, it's special from nfapi */
+          /* TODO: fix how we deal with power, unit is not dBm, it's special from nfapi */
 	    normalized_rx_power = (5 * ue_sched_ctl->pucch1_snr[CC_id]-640) / 10 + 30;
 	    target_rx_power = mac->puCch10xSnr / 10 + 30;
-	    
+
       /* This assumes accumulated tpc */
 	    /* Make sure that we are only sending a tpc update once a frame, otherwise the control loop will freak out */
 	    int32_t framex10psubframe = UE_list->UE_template[CC_id][UE_id].pucch_tpc_tx_frame * 10 + UE_list->UE_template[CC_id][UE_id].pucch_tpc_tx_subframe;
@@ -2386,21 +2386,21 @@ schedule_ue_spec_br(module_id_t module_idP,
       if (((framex10psubframe + 10) <= (frameP * 10 + subframeP)) || // normal case
 	        ((framex10psubframe > (frameP * 10 + subframeP)) && 
             (((10240 - framex10psubframe +frameP * 10 + subframeP) >= 10)))) { // frame wrap-around
-	      if (ue_sched_ctl->pucch1_cqi_update[CC_id] == 1) { 
-	        ue_sched_ctl->pucch1_cqi_update[CC_id] = 0;
-      
+	    if (ue_sched_ctl->pucch1_cqi_update[CC_id] == 1) {
+	      ue_sched_ctl->pucch1_cqi_update[CC_id] = 0;
+
           UE_list->UE_template[CC_id][UE_id].pucch_tpc_tx_frame = frameP;
           UE_list->UE_template[CC_id][UE_id].pucch_tpc_tx_subframe = subframeP;
-          
+
           if (normalized_rx_power > (target_rx_power + 4)) {
-            tpc = 0; //-1
+		tpc = 0; //-1
           } else if (normalized_rx_power<(target_rx_power - 4)) {
-            tpc = 2; //+1
-          } else {
-            tpc = 1; //0
-          }
-                  
-          LOG_D(MAC,"[eNB %d] DLSCH scheduler: frame %d, subframe %d, harq_pid %d, tpc %d, normalized/target rx power %d/%d\n",
+		tpc = 2; //+1
+	      } else {
+		tpc = 1; //0
+	      }
+
+	      LOG_D(MAC,"[eNB %d] DLSCH scheduler: frame %d, subframe %d, harq_pid %d, tpc %d, normalized/target rx power %d/%d\n",
                 module_idP,
                 frameP, 
                 subframeP,
@@ -2412,75 +2412,75 @@ schedule_ue_spec_br(module_id_t module_idP,
 	        tpc = 1; // 0
         }
 	    } else { // time to do TPC update 
-	      tpc = 1; //0
-	    }
+	    tpc = 1; //0
+	  }
 
-      // Toggle NDI in first round
+	  // Toggle NDI in first round
       UE_template->oldNDI[harq_pid] = 1 - UE_template->oldNDI[harq_pid];
-      ue_sched_ctl->round[CC_id][harq_pid] = 0;
+	  ue_sched_ctl->round[CC_id][harq_pid] = 0;
       round_DL = 0;
 	  } // if ((sdu_length_total + header_len_dcch + header_len_dtch) > 0)
-  } 
-  
+	}
+
     if (round_DL < 8) {
       /* Fill in MDPDCCH */
-      memset ((void *) dl_config_pdu, 0, sizeof (nfapi_dl_config_request_pdu_t));
+	memset ((void *) dl_config_pdu, 0, sizeof (nfapi_dl_config_request_pdu_t));
 
-      dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_MPDCCH_PDU_TYPE;
-      dl_config_pdu->pdu_size = (uint8_t) (2 + sizeof (nfapi_dl_config_mpdcch_pdu));
-      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.dci_format = (UE_template->rach_resource_type > 1) ? 11 : 10;
-      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.mpdcch_narrow_band = epdcch_setconfig_r11->ext2->mpdcch_config_r13->choice.setup.mpdcch_Narrowband_r13-1;
-      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.number_of_prb_pairs = 6;
-      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.resource_block_assignment = 0; // Note: this can be dynamic
-      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.mpdcch_tansmission_type = epdcch_setconfig_r11->transmissionType_r11;  
+	dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_MPDCCH_PDU_TYPE;
+	dl_config_pdu->pdu_size = (uint8_t) (2 + sizeof (nfapi_dl_config_mpdcch_pdu));
+	dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.dci_format = (UE_template->rach_resource_type > 1) ? 11 : 10;
+	dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.mpdcch_narrow_band = epdcch_setconfig_r11->ext2->mpdcch_config_r13->choice.setup.mpdcch_Narrowband_r13-1;
+	dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.number_of_prb_pairs = 6;
+	dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.resource_block_assignment = 0; // Note: this can be dynamic
+	dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.mpdcch_tansmission_type = epdcch_setconfig_r11->transmissionType_r11;
 
       AssertFatal(UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.startSymbol_r11 != NULL,
-                  "UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.startSymbol_r11 is null\n");
-      
-      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.start_symbol = *UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.startSymbol_r11;
-      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.ecce_index = 0;         // Note: this should be dynamic
-      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.aggregation_level = 24; // OK for CEModeA r1-3 (9.1.5-1b) or CEModeB r1-4
-      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.rnti_type = 4; // t-CRNTI
-      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.rnti = rnti;
-      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.ce_mode = (UE_template->rach_resource_type < 3) ? 1 : 2;
-      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.drms_scrambling_init = epdcch_setconfig_r11->dmrs_ScramblingSequenceInt_r11;
-      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.initial_transmission_sf_io = (frameP * 10) + subframeP;
-      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.transmission_power = 6000;     // 0dB
-      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.resource_block_coding = getRIV (6, 0, 6) | ((epdcch_setconfig_r11->ext2->mpdcch_config_r13->choice.setup.mpdcch_Narrowband_r13-1)<<5);
+		    "UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.startSymbol_r11 is null\n");
+
+	dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.start_symbol = *UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.startSymbol_r11;
+	dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.ecce_index = 0;        // Note: this should be dynamic
+	dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.aggregation_level = 24;        // OK for CEModeA r1-3 (9.1.5-1b) or CEModeB r1-4
+	dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.rnti_type = 4; // t-CRNTI
+	dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.rnti = rnti;
+	dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.ce_mode = (UE_template->rach_resource_type < 3) ? 1 : 2;
+	dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.drms_scrambling_init = epdcch_setconfig_r11->dmrs_ScramblingSequenceInt_r11;
+	dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.initial_transmission_sf_io = (frameP * 10) + subframeP;
+	dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.transmission_power = 6000;     // 0dB
+	dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.resource_block_coding = getRIV (6, 0, 6) | ((epdcch_setconfig_r11->ext2->mpdcch_config_r13->choice.setup.mpdcch_Narrowband_r13-1)<<5);
       dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.mcs = mcs;       // adjust according to size of RAR, 208 bits with N1A_PRB=3
-      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.pdsch_reptition_levels = 0;    // fix to 4 for now
+	dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.pdsch_reptition_levels = 0;    // fix to 4 for now
       dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.redundancy_version = rvseq[round_DL&3];
-      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.new_data_indicator = UE_template->oldNDI[harq_pid];
-      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.harq_process = 0;
-      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.tpmi_length = 0;
-      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.tpmi = 0;
-      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.pmi_flag = 0;
-      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.pmi = 0;
-      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.harq_resource_offset = 0;
-      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.dci_subframe_repetition_number = 0;
-      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.tpc = 3; 
-      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.downlink_assignment_index_length = 0;
-      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.downlink_assignment_index = 0;
-      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.allocate_prach_flag = 0;
-      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.preamble_index = 0;
-      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.prach_mask_index = 0;
-      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.starting_ce_level = 0;
-      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.srs_request = 0;
-      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.antenna_ports_and_scrambling_identity_flag = 0;
-      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.antenna_ports_and_scrambling_identity = 0;
-      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.frequency_hopping_enabled_flag = 0;
-      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.paging_direct_indication_differentiation_flag = 0;
-      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.direct_indication = 0;
-      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.total_dci_length_including_padding = 0; // this is not needed by OAI L1, but should be filled in
-      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.number_of_tx_antenna_ports = 1;
-      dl_req->number_pdu++;
-      UE_template->mcs[harq_pid] = dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.mcs;
-    }
+	dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.new_data_indicator = UE_template->oldNDI[harq_pid];
+	dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.harq_process = 0;
+	dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.tpmi_length = 0;
+	dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.tpmi = 0;
+	dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.pmi_flag = 0;
+	dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.pmi = 0;
+	dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.harq_resource_offset = 0;
+	dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.dci_subframe_repetition_number = 0;
+	dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.tpc = 3;
+	dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.downlink_assignment_index_length = 0;
+	dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.downlink_assignment_index = 0;
+	dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.allocate_prach_flag = 0;
+	dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.preamble_index = 0;
+	dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.prach_mask_index = 0;
+	dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.starting_ce_level = 0;
+	dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.srs_request = 0;
+	dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.antenna_ports_and_scrambling_identity_flag = 0;
+	dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.antenna_ports_and_scrambling_identity = 0;
+	dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.frequency_hopping_enabled_flag = 0;
+	dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.paging_direct_indication_differentiation_flag = 0;
+	dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.direct_indication = 0;
+	dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.total_dci_length_including_padding = 0;        // this is not needed by OAI L1, but should be filled in
+	dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.number_of_tx_antenna_ports = 1;
+	dl_req->number_pdu++;
+	UE_template->mcs[harq_pid] = dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.mcs;
+      }
   } else if ((subframeP == 7) && (round_DL < 8)) { // DLSCH
     LOG_D(MAC, "DLSCH round_DL = %d in frame %d subframe %d\n", round_DL, frameP, subframeP);
-	  
-	  int absSF = (frameP * 10) + subframeP;
-	  
+
+	  int             absSF = (frameP * 10) + subframeP;
+
 	  /* Have to check that MPDCCH was generated */
 	  LOG_D(MAC, "[eNB %d][RAPROC] CC_id %d Frame %d, subframeP %d: Generating DLSCH (ce_level %d RNTI %x)\n",
 	        module_idP, 
@@ -2494,72 +2494,72 @@ schedule_ue_spec_br(module_id_t module_idP,
 
 	  dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu];
 	  
-    memset ((void *) dl_config_pdu, 0, sizeof (nfapi_dl_config_request_pdu_t));
+	  memset ((void *) dl_config_pdu, 0, sizeof (nfapi_dl_config_request_pdu_t));
     
-    dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DLSCH_PDU_TYPE;
-    dl_config_pdu->pdu_size = (uint8_t) (2 + sizeof (nfapi_dl_config_dlsch_pdu));
-    dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index = mac->pdu_index[CC_id];
-    dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.rnti = rnti;
-    dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type = 2;   // format 1A/1B/1D
-    dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.virtual_resource_block_assignment_flag = 0;     // localized
-    dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_block_coding = getRIV (to_prb (cc[CC_id].mib->message.dl_Bandwidth), first_rb, 6);  // check that this isn't getRIV(6,0,6)
-    dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.modulation = 2; //QPSK
-    dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.redundancy_version = 0;
-    dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_blocks = 1;   // first block
-    dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_block_to_codeword_swap_flag = 0;
-    dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_scheme = (cc[CC_id].p_eNB == 1) ? 0 : 1;
-    dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_layers = 1;
-    dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_subbands = 1;
-    //      dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.codebook_index                         = ;
-    dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ue_category_capacity = 1;
-    dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pa = 4; // 0 dB
-    dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.delta_power_offset_index = 0;
-    dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ngap = 0;
-    dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.nprb = get_subbandsize (cc[CC_id].mib->message.dl_Bandwidth); // ignored
-    dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_mode = (cc[CC_id].p_eNB == 1) ? 1 : 2;
-    dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_prb_per_subband = 1;
-    dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_vector = 1;
-    //      dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.bf_vector                    = ; 
-    dl_config_pdu->dlsch_pdu.dlsch_pdu_rel10.pdsch_start = *UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.startSymbol_r11;
-    dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.ue_type = (UE_template->rach_resource_type < 3) ? 1 : 2;
-    dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.pdsch_payload_type = 2;        // not SI message
-    dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.initial_transmission_sf_io = (10 * frameP) + subframeP;
-    dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.drms_table_flag = 0;
-    dl_req->number_pdu++;
-
-    // DL request
-    mac->TX_req[CC_id].sfn_sf = (frameP << 4) + subframeP;
-    TX_req = &mac->TX_req[CC_id].tx_request_body.tx_pdu_list[mac->TX_req[CC_id].tx_request_body.number_of_pdus];
+      dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DLSCH_PDU_TYPE;
+      dl_config_pdu->pdu_size = (uint8_t) (2 + sizeof (nfapi_dl_config_dlsch_pdu));
+      dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index = mac->pdu_index[CC_id];
+      dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.rnti = rnti;
+      dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type = 2;   // format 1A/1B/1D
+      dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.virtual_resource_block_assignment_flag = 0;     // localized
+      dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_block_coding = getRIV (to_prb (cc[CC_id].mib->message.dl_Bandwidth), first_rb, 6);  // check that this isn't getRIV(6,0,6)
+      dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.modulation = 2; //QPSK
+      dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.redundancy_version = 0;
+      dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_blocks = 1;   // first block
+      dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_block_to_codeword_swap_flag = 0;
+      dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_scheme = (cc[CC_id].p_eNB == 1) ? 0 : 1;
+      dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_layers = 1;
+      dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_subbands = 1;
+      //      dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.codebook_index                         = ;
+      dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ue_category_capacity = 1;
+      dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pa = 4; // 0 dB
+      dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.delta_power_offset_index = 0;
+      dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ngap = 0;
+      dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.nprb = get_subbandsize (cc[CC_id].mib->message.dl_Bandwidth); // ignored
+      dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_mode = (cc[CC_id].p_eNB == 1) ? 1 : 2;
+      dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_prb_per_subband = 1;
+      dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_vector = 1;
+      //      dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.bf_vector                    = ;
+      dl_config_pdu->dlsch_pdu.dlsch_pdu_rel10.pdsch_start = *UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.startSymbol_r11;
+      dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.ue_type = (UE_template->rach_resource_type < 3) ? 1 : 2;
+      dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.pdsch_payload_type = 2;        // not SI message
+      dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.initial_transmission_sf_io = (10 * frameP) + subframeP;
+      dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.drms_table_flag = 0;
+      dl_req->number_pdu++;
+
+      // DL request
+      mac->TX_req[CC_id].sfn_sf = (frameP << 4) + subframeP;
+      TX_req = &mac->TX_req[CC_id].tx_request_body.tx_pdu_list[mac->TX_req[CC_id].tx_request_body.number_of_pdus];
     TX_req->pdu_length = get_TBS_DL(UE_template->mcs[harq_pid], 6);
-    TX_req->pdu_index = mac->pdu_index[CC_id]++;
-    TX_req->num_segments = 1;
-    TX_req->segments[0].segment_length = TX_req->pdu_length;
-    TX_req->segments[0].segment_data = mac->UE_list.DLSCH_pdu[CC_id][0][(unsigned char) UE_id].payload[0];
-    mac->TX_req[CC_id].tx_request_body.number_of_pdus++;
-
-    ackNAK_absSF = absSF + 4;
-    ul_req = &mac->UL_req_tmp[CC_id][ackNAK_absSF % 10].ul_config_request_body;
-    ul_config_pdu = &ul_req->ul_config_pdu_list[ul_req->number_of_pdus];
-    
-    ul_config_pdu->pdu_type = NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE;
-    ul_config_pdu->pdu_size = (uint8_t) (2 + sizeof (nfapi_ul_config_uci_harq_pdu));
-    ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel8.handle = 0;      // don't know how to use this
-    ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel8.rnti = rnti;
-    ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel13.ue_type = (UE_template->rach_resource_type < 3) ? 1 : 2;
-    ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel13.empty_symbols = 0;
-    ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel13.total_number_of_repetitions = pucchreps[UE_template->rach_resource_type - 1];
-    ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel13.repetition_number = 0;
-
-    if (cc[CC_id].tdd_Config == NULL) {  // FDD case
-      ul_config_pdu->uci_harq_pdu.harq_information.harq_information_rel9_fdd.n_pucch_1_0 = n1pucchan[UE_template->rach_resource_type - 1];
-      // NOTE: How to fill in the rest of the n_pucch_1_0 information 213 Section 10.1.2.1 in the general case
-      // = N_ECCE_q + Delta_ARO + n1pucchan[ce_level]
-      // higher in the MPDCCH configuration, N_ECCE_q is hard-coded to 0, and harq resource offset to 0 =>
-      // Delta_ARO = 0 from Table 10.1.2.1-1
-      ul_config_pdu->uci_harq_pdu.harq_information.harq_information_rel9_fdd.harq_size = 1; // 1-bit ACK/NAK
-      ul_config_pdu->uci_harq_pdu.harq_information.harq_information_rel9_fdd.number_of_pucch_resources = 1;
+      TX_req->pdu_index = mac->pdu_index[CC_id]++;
+      TX_req->num_segments = 1;
+      TX_req->segments[0].segment_length = TX_req->pdu_length;
+      TX_req->segments[0].segment_data = mac->UE_list.DLSCH_pdu[CC_id][0][(unsigned char) UE_id].payload[0];
+      mac->TX_req[CC_id].tx_request_body.number_of_pdus++;
+
+      ackNAK_absSF = absSF + 4;
+      ul_req = &mac->UL_req_tmp[CC_id][ackNAK_absSF % 10].ul_config_request_body;
+      ul_config_pdu = &ul_req->ul_config_pdu_list[ul_req->number_of_pdus];
+
+      ul_config_pdu->pdu_type = NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE;
+      ul_config_pdu->pdu_size = (uint8_t) (2 + sizeof (nfapi_ul_config_uci_harq_pdu));
+      ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel8.handle = 0;      // don't know how to use this
+      ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel8.rnti = rnti;
+      ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel13.ue_type = (UE_template->rach_resource_type < 3) ? 1 : 2;
+      ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel13.empty_symbols = 0;
+      ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel13.total_number_of_repetitions = pucchreps[UE_template->rach_resource_type - 1];
+      ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel13.repetition_number = 0;
+
+      if (cc[CC_id].tdd_Config == NULL) {    // FDD case
+	ul_config_pdu->uci_harq_pdu.harq_information.harq_information_rel9_fdd.n_pucch_1_0 = n1pucchan[UE_template->rach_resource_type - 1];
+	// NOTE: How to fill in the rest of the n_pucch_1_0 information 213 Section 10.1.2.1 in the general case
+	// = N_ECCE_q + Delta_ARO + n1pucchan[ce_level]
+	// higher in the MPDCCH configuration, N_ECCE_q is hard-coded to 0, and harq resource offset to 0 =>
+	// Delta_ARO = 0 from Table 10.1.2.1-1
+	ul_config_pdu->uci_harq_pdu.harq_information.harq_information_rel9_fdd.harq_size = 1; // 1-bit ACK/NAK
+	ul_config_pdu->uci_harq_pdu.harq_information.harq_information_rel9_fdd.number_of_pucch_resources = 1;
       } else {
-      	AssertFatal (1 == 0, "PUCCH configuration for ACK/NAK not handled yet for TDD BL/CE case\n");
+	AssertFatal (1 == 0, "PUCCH configuration for ACK/NAK not handled yet for TDD BL/CE case\n");
       }
 
       ul_req->number_of_pdus++;
@@ -2572,7 +2572,7 @@ schedule_ue_spec_br(module_id_t module_idP,
         T_INT (subframeP),
 	      T_INT (0 /* harq_pid always 0? */ ), 
         T_BUFFER (&mac->UE_list.DLSCH_pdu[CC_id][0][UE_id].payload[0], TX_req->pdu_length));
-      
+
       if (opt_enabled == 1) {
         trace_pdu(1, 
                   (uint8_t *) mac->UE_list.DLSCH_pdu[CC_id][0][(unsigned char) UE_id].payload[0], 
@@ -2591,7 +2591,7 @@ schedule_ue_spec_br(module_id_t module_idP,
               frameP, 
               rnti, 
               TX_req->pdu_length);
-      }
+    }
     } // end else if ((subframeP == 7) && (round_DL < 8))
   } // end loop on UE_id
 }
@@ -2600,8 +2600,8 @@ schedule_ue_spec_br(module_id_t module_idP,
 //------------------------------------------------------------------------------
 void
 fill_DLSCH_dci(module_id_t module_idP,
-               frame_t frameP, 
-               sub_frame_t subframeP, 
+               frame_t frameP,
+               sub_frame_t subframeP,
                int *mbsfn_flagP)
 //------------------------------------------------------------------------------
 {
@@ -2625,11 +2625,11 @@ fill_DLSCH_dci(module_id_t module_idP,
   UE_TEMPLATE *ue_template;
 
   start_meas(&eNB->fill_DLSCH_dci);
-  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_FILL_DLSCH_DCI, 
+  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_FILL_DLSCH_DCI,
                                           VCD_FUNCTION_IN);
 
   for (CC_id = 0; CC_id < RC.nb_mac_CC[module_idP]; CC_id++) {
-    LOG_D(MAC, "Doing fill DCI for CC_id %d\n", 
+    LOG_D(MAC, "Doing fill DCI for CC_id %d\n",
           CC_id);
 
     if (mbsfn_flagP[CC_id] > 0)
@@ -2642,8 +2642,8 @@ fill_DLSCH_dci(module_id_t module_idP,
     // UE specific DCIs
     for (UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) {
       dlsch_info = &eNB_dlsch_info[module_idP][CC_id][UE_id];
-      LOG_T(MAC, "CC_id %d, UE_id: %d => status %d\n", 
-            CC_id, 
+      LOG_T(MAC, "CC_id %d, UE_id: %d => status %d\n",
+            CC_id,
             UE_id,
             dlsch_info->status);
 
@@ -2670,16 +2670,16 @@ fill_DLSCH_dci(module_id_t module_idP,
           if (dl_config_pdu->pdu_type == NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE &&
               dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti == rnti &&
               dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format != 1) {
-            dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding = allocate_prbs_sub(nb_rb, 
-                                                                                                N_RB_DL, 
+            dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding = allocate_prbs_sub(nb_rb,
+                                                                                                N_RB_DL,
                                                                                                 N_RBG,
                                                                                                 rballoc_sub);
             dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_allocation_type = 0;
           } else if (dl_config_pdu->pdu_type == NFAPI_DL_CONFIG_DLSCH_PDU_TYPE &&
                      dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.rnti == rnti &&
                      dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type == 0) {
-            dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_block_coding = allocate_prbs_sub(nb_rb, 
-                                                                                              N_RB_DL, 
+            dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_block_coding = allocate_prbs_sub(nb_rb,
+                                                                                              N_RB_DL,
                                                                                               N_RBG,
                                                                                               rballoc_sub);
           }
@@ -2689,14 +2689,14 @@ fill_DLSCH_dci(module_id_t module_idP,
   }
 
   stop_meas(&eNB->fill_DLSCH_dci);
-  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_FILL_DLSCH_DCI, 
+  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_FILL_DLSCH_DCI,
                                           VCD_FUNCTION_OUT);
 }
 
 //------------------------------------------------------------------------------
 unsigned char *get_dlsch_sdu(module_id_t module_idP,
-                             int CC_id, 
-                             frame_t frameP, 
+                             int CC_id,
+                             frame_t frameP,
                              rnti_t rntiP,
                              uint8_t TBindex)
 //------------------------------------------------------------------------------
@@ -2706,16 +2706,16 @@ unsigned char *get_dlsch_sdu(module_id_t module_idP,
 
   if (rntiP == SI_RNTI) {
     LOG_D(MAC, "[eNB %d] CC_id %d Frame %d Get DLSCH sdu for BCCH \n",
-          module_idP, 
-          CC_id, 
+          module_idP,
+          CC_id,
           frameP);
     return ((unsigned char *) &eNB->common_channels[CC_id].BCCH_pdu.payload[0]);
   }
 
   if (rntiP == P_RNTI) {
-    LOG_D(MAC, "[eNB %d] CC_id %d Frame %d Get PCH sdu for PCCH \n", 
-          module_idP, 
-          CC_id, 
+    LOG_D(MAC, "[eNB %d] CC_id %d Frame %d Get PCH sdu for PCCH \n",
+          module_idP,
+          CC_id,
           frameP);
     return ((unsigned char *) &eNB->common_channels[CC_id].PCCH_pdu.payload[0]);
   }
@@ -2724,18 +2724,18 @@ unsigned char *get_dlsch_sdu(module_id_t module_idP,
 
   if (UE_id != -1) {
     LOG_D(MAC, "[eNB %d] Frame %d:  CC_id %d Get DLSCH sdu for rnti %x => UE_id %d\n",
-          module_idP, 
-          frameP, 
-          CC_id, 
-          rntiP, 
+          module_idP,
+          frameP,
+          CC_id,
+          rntiP,
           UE_id);
     return ((unsigned char *) &eNB->UE_list.DLSCH_pdu[CC_id][TBindex][UE_id].payload[0]);
-  } 
+  }
 
   LOG_E(MAC, "[eNB %d] Frame %d: CC_id %d UE with RNTI %x does not exist\n",
-        module_idP, 
-        frameP, 
-        CC_id, 
+        module_idP,
+        frameP,
+        CC_id,
         rntiP);
   return NULL;
 }
@@ -2744,15 +2744,15 @@ unsigned char *get_dlsch_sdu(module_id_t module_idP,
 //------------------------------------------------------------------------------
 void
 update_ul_dci(module_id_t module_idP,
-              uint8_t CC_idP, 
-              rnti_t rntiP, 
-              uint8_t daiP, 
+              uint8_t CC_idP,
+              rnti_t rntiP,
+              uint8_t daiP,
               sub_frame_t subframe)
 //------------------------------------------------------------------------------
 {
   eNB_MAC_INST *eNB = RC.mac[module_idP];
   COMMON_channels_t *cc = &eNB->common_channels[CC_idP];
-  
+
   if (cc->tdd_Config != NULL) { // TDD
     nfapi_hi_dci0_request_t *HI_DCI0_req = &eNB->HI_DCI0_req[CC_idP][subframe];
     nfapi_hi_dci0_request_pdu_t *hi_dci0_pdu = &HI_DCI0_req->hi_dci0_request_body.hi_dci0_pdu_list[0];
@@ -2835,10 +2835,10 @@ set_ue_dai(sub_frame_t subframeP,
   return;
 }
 
-void 
-schedule_PCH(module_id_t module_idP, 
-             frame_t frameP, 
-             sub_frame_t subframeP) 
+void
+schedule_PCH(module_id_t module_idP,
+             frame_t frameP,
+             sub_frame_t subframeP)
 {
   /* DCI:format 1A/1C P-RNTI:0xFFFE */
   /* PDU:eNB_rrc_inst[Mod_idP].common_channels[CC_id].PCCH_pdu.payload */
@@ -2892,25 +2892,26 @@ schedule_PCH(module_id_t module_idP,
         pcch_sdu_length = mac_rrc_data_req(module_idP,
                                            CC_id,
                                            frameP,
-                                           PCCH, 
+                                           PCCH,
+                                           0xFFFE,
                                            1,
                                            &cc->PCCH_pdu.payload[0],
                                            i); // used for ue index
 
         if (pcch_sdu_length == 0) {
-          LOG_D(MAC, "[eNB %d] Frame %d subframe %d: PCCH not active(size = 0 byte)\n", 
-                module_idP, 
-                frameP, 
+          LOG_D(MAC, "[eNB %d] Frame %d subframe %d: PCCH not active(size = 0 byte)\n",
+                module_idP,
+                frameP,
                 subframeP);
           continue;
         }
 
-        LOG_D(MAC, "[eNB %d] Frame %d subframe %d: PCCH->PCH CC_id %d UE_id %d, Received %d bytes \n", 
+        LOG_D(MAC, "[eNB %d] Frame %d subframe %d: PCCH->PCH CC_id %d UE_id %d, Received %d bytes \n",
               module_idP,
-              frameP, 
-              subframeP, 
-              CC_id, 
-              i, 
+              frameP,
+              subframeP,
+              CC_id,
+              i,
               pcch_sdu_length);
 
 #ifdef FORMAT1C
@@ -3006,9 +3007,9 @@ schedule_PCH(module_id_t module_idP,
         } else {
           /* unexpected: pcch sdb size is over max value*/
           LOG_E(MAC,"[eNB %d] Frame %d : PCCH->PCH CC_id %d, Received %d bytes is over max length(256) \n",
-                module_idP, 
+                module_idP,
                 frameP,
-                CC_id, 
+                CC_id,
                 pcch_sdu_length);
           return;
         }
@@ -3092,8 +3093,8 @@ schedule_PCH(module_id_t module_idP,
 
 #endif
         dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu];
-        memset((void *) dl_config_pdu, 
-               0, 
+        memset((void *) dl_config_pdu,
+               0,
                sizeof(nfapi_dl_config_request_pdu_t));
         dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE;
         dl_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_dl_config_dci_dl_pdu));
@@ -3107,8 +3108,8 @@ schedule_PCH(module_id_t module_idP,
         dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tpc                         = 1; // no TPC
         dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.new_data_indicator_1        = 1;
         dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.redundancy_version_1        = 1;
-        dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding       = getRIV(n_rb_dl, 
-                                                                                       first_rb, 
+        dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding       = getRIV(n_rb_dl,
+                                                                                       first_rb,
                                                                                        4);
         dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.virtual_resource_block_assignment_flag = 0;
 #endif
@@ -3118,13 +3119,13 @@ schedule_PCH(module_id_t module_idP,
         dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.transmission_power          = 6000; // equal to RS power
         dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1                       = mcs;
 
-        if (!CCE_allocation_infeasible(module_idP, 
-                                       CC_id, 
-                                       0, 
-                                       subframeP, 
-                                       dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level, 
+        if (!CCE_allocation_infeasible(module_idP,
+                                       CC_id,
+                                       0,
+                                       subframeP,
+                                       dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level,
                                        P_RNTI)) {
-          LOG_D(MAC,"Frame %d: Subframe %d : Adding common DCI for P_RNTI\n", 
+          LOG_D(MAC,"Frame %d: Subframe %d : Adding common DCI for P_RNTI\n",
                 frameP,
                 subframeP);
           dl_req->number_dci++;
@@ -3143,13 +3144,13 @@ schedule_PCH(module_id_t module_idP,
           dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.rnti                                   = 0xFFFE;
 #ifdef FORMAT1C
           dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type               = 3;   // format 1C
-          dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_block_coding                  = getRIV(n_vrb_dl / n_rb_step, 
-                                                                                                  first_rb / n_rb_step, 
+          dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_block_coding                  = getRIV(n_vrb_dl / n_rb_step,
+                                                                                                  first_rb / n_rb_step,
                                                                                                   Lcrbs / n_rb_step);
 #else
           dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type               = 2;   // format 1A/1B/1D
-          dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_block_coding                  = getRIV(n_rb_dl, 
-                                                                                                  first_rb, 
+          dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_block_coding                  = getRIV(n_rb_dl,
+                                                                                                  first_rb,
                                                                                                   4);
           dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.virtual_resource_block_assignment_flag = 0;   // localized
 #endif
@@ -3192,9 +3193,9 @@ schedule_PCH(module_id_t module_idP,
           eNB->TX_req[CC_id].tx_request_body.number_of_pdus++;
         } else {
           LOG_E(MAC,"[eNB %d] CCid %d Frame %d, subframe %d : Cannot add DCI 1A/1C for Paging\n",
-                module_idP, 
-                CC_id, 
-                frameP, 
+                module_idP,
+                CC_id,
+                frameP,
                 subframeP);
           continue;
         }
@@ -3211,10 +3212,10 @@ schedule_PCH(module_id_t module_idP,
                     0,
                     0);
           LOG_D(OPT,"[eNB %d][PCH] Frame %d trace pdu for CC_id %d rnti %x with size %d\n",
-                module_idP, 
-                frameP, 
-                CC_id, 
-                0xffff, 
+                module_idP,
+                frameP,
+                CC_id,
+                0xffff,
                 pcch_sdu_length);
         }
 
@@ -3224,16 +3225,16 @@ schedule_PCH(module_id_t module_idP,
         eNB->eNB_stats[CC_id].pcch_mcs = mcs;
         //paging first_rb log
         LOG_D(MAC,"[eNB %d] Frame %d subframe %d PCH: paging_ue_index %d pcch_sdu_length %d mcs %d first_rb %d\n",
-              module_idP, 
-              frameP, 
-              subframeP, 
-              ue_pf_po->ue_index_value, 
-              pcch_sdu_length, 
-              mcs, 
+              module_idP,
+              frameP,
+              subframeP,
+              ue_pf_po->ue_index_value,
+              pcch_sdu_length,
+              mcs,
               first_rb);
         pthread_mutex_lock(&ue_pf_po_mutex);
-        memset(ue_pf_po, 
-               0, 
+        memset(ue_pf_po,
+               0,
                sizeof(UE_PF_PO_t));
         pthread_mutex_unlock(&ue_pf_po_mutex);
       }
@@ -3245,10 +3246,10 @@ schedule_PCH(module_id_t module_idP,
   return;
 }
 
-static int 
-slice_priority_compare(const void *_a, 
-                       const void *_b, 
-                       void *_c) 
+static int
+slice_priority_compare(const void *_a,
+                       const void *_b,
+                       void *_c)
 {
   const int slice_id1 = *(const int *) _a;
   const int slice_id2 = *(const int *) _b;
@@ -3262,9 +3263,9 @@ slice_priority_compare(const void *_a,
   return 1;
 }
 
-void 
-slice_priority_sort(module_id_t Mod_id, 
-                    int slice_list[MAX_NUM_SLICES]) 
+void
+slice_priority_sort(module_id_t Mod_id,
+                    int slice_list[MAX_NUM_SLICES])
 {
   int i;
   int n_dl = RC.mac[Mod_id]->slice_info.n_dl;
@@ -3272,10 +3273,10 @@ slice_priority_sort(module_id_t Mod_id,
     slice_list[i] = i;
   }
 
-  qsort_r(slice_list, 
-          n_dl, 
+  qsort_r(slice_list,
+          n_dl,
           sizeof(int),
-          slice_priority_compare, 
+          slice_priority_compare,
           &Mod_id);
   return;
 }
diff --git a/openair2/LAYER2/MAC/eNB_scheduler_fairRR.c b/openair2/LAYER2/MAC/eNB_scheduler_fairRR.c
index db98335527cf4a8af652cbe44222e84d6b318f07..4657493e5912b1b2eacf1846815059d9535e3460 100644
--- a/openair2/LAYER2/MAC/eNB_scheduler_fairRR.c
+++ b/openair2/LAYER2/MAC/eNB_scheduler_fairRR.c
@@ -841,6 +841,7 @@ schedule_ue_spec_fairRR(module_id_t module_idP,
 #ifdef DEBUG_eNB_SCHEDULER
   int k;
 #endif
+
   start_meas(&eNB->schedule_dlsch);
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME
   (VCD_SIGNAL_DUMPER_FUNCTIONS_SCHEDULE_DLSCH, VCD_FUNCTION_IN);
@@ -1219,8 +1220,8 @@ schedule_ue_spec_fairRR(module_id_t module_idP,
           }
 
           add_ue_dlsch_info(module_idP,
-                            CC_id, 
-                            UE_id, 
+                            CC_id,
+                            UE_id,
                             subframeP,
                             S_DL_SCHEDULED,
                             rnti);
diff --git a/openair2/LAYER2/MAC/eNB_scheduler_mch.c b/openair2/LAYER2/MAC/eNB_scheduler_mch.c
index 649f763f422dfc6777f7ae807b776c282761b552..faf36026d62e8346a0adac000a01125bb4f2b5e3 100644
--- a/openair2/LAYER2/MAC/eNB_scheduler_mch.c
+++ b/openair2/LAYER2/MAC/eNB_scheduler_mch.c
@@ -542,7 +542,7 @@ schedule_MBMS(module_id_t module_idP, uint8_t CC_id, frame_t frameP,
 	      "[eNB %d] CC_id %d Frame %d Subframe %d: Schedule MCCH MESSAGE (area %d, sfAlloc %d)\n",
 	      module_idP, CC_id, frameP, subframeP, i, j);
 
-	mcch_sdu_length = mac_rrc_data_req(module_idP, CC_id, frameP, MCCH, 1, &cc->MCCH_pdu.payload[0], 
+	mcch_sdu_length = mac_rrc_data_req(module_idP, CC_id, frameP, MCCH, 0xFFFC, 1, &cc->MCCH_pdu.payload[0], 
 					   i);	// this is the mbsfn sync area index
 
 	if (mcch_sdu_length > 0) {
diff --git a/openair2/LAYER2/MAC/eNB_scheduler_phytest.c b/openair2/LAYER2/MAC/eNB_scheduler_phytest.c
index 881359f274dff57a844170abddc892761dce2a5d..2f566c0d7a0d48d1397c23b4fe4892cba59879dc 100644
--- a/openair2/LAYER2/MAC/eNB_scheduler_phytest.c
+++ b/openair2/LAYER2/MAC/eNB_scheduler_phytest.c
@@ -169,7 +169,7 @@ schedule_ue_spec_phy_test(
 			      1, // number of subbands
 			      //			     uint8_t codebook_index,
 			      4, // UE category capacity
-			      LTE_PDSCH_ConfigDedicated__p_a_dB0, 
+			      LTE_PDSCH_ConfigDedicated__p_a_dB0,
 			      0, // delta_power_offset for TM5
 			      0, // ngap
 			      0, // nprb
diff --git a/openair2/LAYER2/MAC/eNB_scheduler_primitives.c b/openair2/LAYER2/MAC/eNB_scheduler_primitives.c
index 579449ac15dcc624692f9ed22439f528019fc21d..1488209dd772176a778e11f216bab16faccf9e6e 100644
--- a/openair2/LAYER2/MAC/eNB_scheduler_primitives.c
+++ b/openair2/LAYER2/MAC/eNB_scheduler_primitives.c
@@ -64,9 +64,9 @@ extern RAN_CONTEXT_t RC;
 extern uint8_t nfapi_mode;
 
 //------------------------------------------------------------------------------
-int 
-choose(int n, 
-       int k) 
+int
+choose(int n,
+       int k)
 //------------------------------------------------------------------------------
 {
   int res = 1;
@@ -90,10 +90,10 @@ choose(int n,
 
 //------------------------------------------------------------------------------
 // Patented algorithm from Yang et al, US Patent 2009, "Channel Quality Indexing and Reverse Indexing"
-void reverse_index(int N, 
-                   int M, 
-                   int r, 
-                   int *v) 
+void reverse_index(int N,
+                   int M,
+                   int r,
+                   int *v)
 //------------------------------------------------------------------------------
 {
   int BaseValue = 0;
@@ -106,7 +106,7 @@ void reverse_index(int N,
   i = M;
 
   while (i > 0 && r > 0) {
-    IncreaseValue = choose(N - M + 1 - sumV - v[i - 1] + i - 2, 
+    IncreaseValue = choose(N - M + 1 - sumV - v[i - 1] + i - 2,
                            i - 1);
     ThresholdValue = BaseValue + IncreaseValue;
 
@@ -123,7 +123,7 @@ void reverse_index(int N,
 
 //------------------------------------------------------------------------------
 int
-to_prb(int dl_Bandwidth) 
+to_prb(int dl_Bandwidth)
 //------------------------------------------------------------------------------
 {
   int prbmap[6] = { 6, 15, 25, 50, 75, 100 };
@@ -132,8 +132,8 @@ to_prb(int dl_Bandwidth)
 }
 
 //------------------------------------------------------------------------------
-int 
-to_rbg(int dl_Bandwidth) 
+int
+to_rbg(int dl_Bandwidth)
 //------------------------------------------------------------------------------
 {
   int rbgmap[6] = { 6, 8, 13, 17, 19, 25 };
@@ -142,8 +142,8 @@ to_rbg(int dl_Bandwidth)
 }
 
 //------------------------------------------------------------------------------
-int 
-get_phich_resource_times6(COMMON_channels_t *cc) 
+int
+get_phich_resource_times6(COMMON_channels_t *cc)
 //------------------------------------------------------------------------------
 {
   int phichmap[4] = { 1, 3, 6, 12 };
@@ -156,10 +156,10 @@ get_phich_resource_times6(COMMON_channels_t *cc)
 }
 
 //------------------------------------------------------------------------------
-uint16_t 
-mac_computeRIV(uint16_t N_RB_DL, 
-               uint16_t RBstart, 
-               uint16_t Lcrbs) 
+uint16_t
+mac_computeRIV(uint16_t N_RB_DL,
+               uint16_t RBstart,
+               uint16_t Lcrbs)
 //------------------------------------------------------------------------------
 {
   if (Lcrbs <= (1 + (N_RB_DL >> 1))) {
@@ -169,8 +169,8 @@ mac_computeRIV(uint16_t N_RB_DL,
 }
 
 //------------------------------------------------------------------------------
-uint8_t 
-getQm(uint8_t mcs) 
+uint8_t
+getQm(uint8_t mcs)
 //------------------------------------------------------------------------------
 {
   if (mcs < 10)      return (2);
@@ -184,7 +184,7 @@ get_Msg3alloc(COMMON_channels_t *cc,
               sub_frame_t       current_subframe,
               frame_t           current_frame,
               frame_t           *frame,
-              sub_frame_t       *subframe) 
+              sub_frame_t       *subframe)
 //------------------------------------------------------------------------------
 {
   // Fill in other TDD Configuration!!!!
@@ -295,8 +295,8 @@ void
 get_Msg3allocret(COMMON_channels_t *cc,
                  sub_frame_t current_subframe,
                  frame_t current_frame,
-                 frame_t *frame, 
-                 sub_frame_t *subframe) 
+                 frame_t *frame,
+                 sub_frame_t *subframe)
 //------------------------------------------------------------------------------
 {
   int subframeAssignment;
@@ -338,9 +338,9 @@ get_Msg3allocret(COMMON_channels_t *cc,
 
 //------------------------------------------------------------------------------
 uint8_t
-subframe2harqpid(COMMON_channels_t *cc, 
+subframe2harqpid(COMMON_channels_t *cc,
                  frame_t frame,
-                 sub_frame_t subframe) 
+                 sub_frame_t subframe)
 //------------------------------------------------------------------------------
 {
   uint8_t ret = 255;
@@ -413,8 +413,8 @@ subframe2harqpid(COMMON_channels_t *cc,
 //------------------------------------------------------------------------------
 uint8_t
 get_Msg3harqpid(COMMON_channels_t *cc,
-                frame_t frame, 
-                sub_frame_t current_subframe) 
+                frame_t frame,
+                sub_frame_t current_subframe)
 //------------------------------------------------------------------------------
 {
   uint8_t ul_subframe = 0;
@@ -492,16 +492,16 @@ get_Msg3harqpid(COMMON_channels_t *cc,
     }
   }
 
-  return (subframe2harqpid(cc, 
-                           ul_frame, 
+  return (subframe2harqpid(cc,
+                           ul_frame,
                            ul_subframe));
 }
 
 //------------------------------------------------------------------------------
 uint32_t
-pdcchalloc2ulframe(COMMON_channels_t *ccP, 
-                   uint32_t frame, 
-                   uint8_t n) 
+pdcchalloc2ulframe(COMMON_channels_t *ccP,
+                   uint32_t frame,
+                   uint8_t n)
 //------------------------------------------------------------------------------
 {
   uint32_t ul_frame = (frame + (n >= 6 ? 1 : 0));
@@ -519,8 +519,8 @@ pdcchalloc2ulframe(COMMON_channels_t *ccP,
       }
     }
   }
-  LOG_D(PHY, "frame %d subframe %d: PUSCH frame = %d\n", 
-        frame, 
+  LOG_D(PHY, "frame %d subframe %d: PUSCH frame = %d\n",
+        frame,
         n,
         ul_frame);
 
@@ -528,9 +528,9 @@ pdcchalloc2ulframe(COMMON_channels_t *ccP,
 }
 
 //------------------------------------------------------------------------------
-uint8_t 
-pdcchalloc2ulsubframe(COMMON_channels_t *ccP, 
-                      uint8_t n) 
+uint8_t
+pdcchalloc2ulsubframe(COMMON_channels_t *ccP,
+                      uint8_t n)
 //------------------------------------------------------------------------------
 {
   uint8_t ul_subframe;
@@ -544,16 +544,16 @@ pdcchalloc2ulsubframe(COMMON_channels_t *ccP,
   else
     ul_subframe = ((n + 4) % 10);
 
-  LOG_D(PHY, "subframe %d: PUSCH subframe = %d\n", 
-        n, 
+  LOG_D(PHY, "subframe %d: PUSCH subframe = %d\n",
+        n,
         ul_subframe);
   return ul_subframe;
 }
 
 //------------------------------------------------------------------------------
-int 
-is_UL_sf(COMMON_channels_t *ccP, 
-         sub_frame_t subframeP) 
+int
+is_UL_sf(COMMON_channels_t *ccP,
+         sub_frame_t subframeP)
 //------------------------------------------------------------------------------
 {
   // if FDD return dummy value
@@ -621,9 +621,9 @@ is_UL_sf(COMMON_channels_t *ccP,
 }
 
 //------------------------------------------------------------------------------
-int 
-is_S_sf(COMMON_channels_t *ccP, 
-        sub_frame_t subframeP) 
+int
+is_S_sf(COMMON_channels_t *ccP,
+        sub_frame_t subframeP)
 //------------------------------------------------------------------------------
 {
   // if FDD return dummy value
@@ -649,9 +649,9 @@ is_S_sf(COMMON_channels_t *ccP,
 }
 
 //------------------------------------------------------------------------------
-uint8_t 
-ul_subframe2_k_phich(COMMON_channels_t *cc, 
-                     sub_frame_t ul_subframe) 
+uint8_t
+ul_subframe2_k_phich(COMMON_channels_t *cc,
+                     sub_frame_t ul_subframe)
 //------------------------------------------------------------------------------
 {
   if(cc->tdd_Config) { //TODO fill other tdd config
@@ -678,9 +678,9 @@ ul_subframe2_k_phich(COMMON_channels_t *cc,
 }
 
 //------------------------------------------------------------------------------
-uint16_t 
-get_pucch1_absSF(COMMON_channels_t *cc, 
-                 uint16_t dlsch_absSF) 
+uint16_t
+get_pucch1_absSF(COMMON_channels_t *cc,
+                 uint16_t dlsch_absSF)
 //------------------------------------------------------------------------------
 {
   uint16_t sf, f, nextf;
@@ -688,7 +688,7 @@ get_pucch1_absSF(COMMON_channels_t *cc,
 
   if (tdd_Config == NULL) { //FDD n+4
     return (dlsch_absSF + 4) % 10240;
-  } 
+  }
 
   sf = dlsch_absSF % 10;
   f = dlsch_absSF / 10;
@@ -768,16 +768,16 @@ get_pucch1_absSF(COMMON_channels_t *cc,
                   tdd_Config->subframeAssignment);
       return 0;
   }
-  
+
   AssertFatal(1 == 0, "Shouldn't get here\n");
 }
 
 //------------------------------------------------------------------------------
 void
-get_srs_pos(COMMON_channels_t *cc, 
+get_srs_pos(COMMON_channels_t *cc,
             uint16_t isrs,
-            uint16_t *psrsPeriodicity, 
-            uint16_t *psrsOffset) 
+            uint16_t *psrsPeriodicity,
+            uint16_t *psrsOffset)
 //------------------------------------------------------------------------------
 {
   if (cc->tdd_Config) { // TDD
@@ -844,9 +844,9 @@ get_srs_pos(COMMON_channels_t *cc,
 void
 get_csi_params(COMMON_channels_t *cc,
                struct LTE_CQI_ReportPeriodic *cqi_ReportPeriodic,
-               uint16_t *Npd, 
-               uint16_t *N_OFFSET_CQI, 
-               int *H) 
+               uint16_t *Npd,
+               uint16_t *N_OFFSET_CQI,
+               int *H)
 //------------------------------------------------------------------------------
 {
   AssertFatal(cqi_ReportPeriodic != NULL, "cqi_ReportPeriodic is null!\n");
@@ -924,10 +924,10 @@ get_csi_params(COMMON_channels_t *cc,
 
 //------------------------------------------------------------------------------
 uint8_t
-get_dl_cqi_pmi_size_pusch(COMMON_channels_t *cc, 
+get_dl_cqi_pmi_size_pusch(COMMON_channels_t *cc,
                           uint8_t tmode,
                           uint8_t ri,
-                          LTE_CQI_ReportModeAperiodic_t *cqi_ReportModeAperiodic) 
+                          LTE_CQI_ReportModeAperiodic_t *cqi_ReportModeAperiodic)
 //------------------------------------------------------------------------------
 {
   int Ntab[6] = { 0, 4, 7, 9, 10, 13 };
@@ -1046,11 +1046,11 @@ get_dl_cqi_pmi_size_pusch(COMMON_channels_t *cc,
 
 //------------------------------------------------------------------------------
 uint8_t
-get_rel8_dl_cqi_pmi_size(UE_sched_ctrl *sched_ctl, 
+get_rel8_dl_cqi_pmi_size(UE_sched_ctrl *sched_ctl,
                          int CC_idP,
-                         COMMON_channels_t *cc, 
+                         COMMON_channels_t *cc,
                          uint8_t tmode,
-                         struct LTE_CQI_ReportPeriodic *cqi_ReportPeriodic) 
+                         struct LTE_CQI_ReportPeriodic *cqi_ReportPeriodic)
 //------------------------------------------------------------------------------
 {
   int no_pmi = 0;
@@ -1077,7 +1077,7 @@ get_rel8_dl_cqi_pmi_size(UE_sched_ctrl *sched_ctl,
       break;
   }
 
-  if (cqi_ReportPeriodic->choice.setup.cqi_FormatIndicatorPeriodic.present == LTE_CQI_ReportPeriodic__setup__cqi_FormatIndicatorPeriodic_PR_widebandCQI || 
+  if (cqi_ReportPeriodic->choice.setup.cqi_FormatIndicatorPeriodic.present == LTE_CQI_ReportPeriodic__setup__cqi_FormatIndicatorPeriodic_PR_widebandCQI ||
       sched_ctl->feedback_cnt[CC_idP] == 0) {
     // send wideband report every opportunity if wideband reporting mode is selected, else every H opportunities
     if (no_pmi == 1) return 4;
@@ -1086,8 +1086,8 @@ get_rel8_dl_cqi_pmi_size(UE_sched_ctrl *sched_ctl,
     if (cc->p_eNB == 4 && ri == 1) return 8;
     if (cc->p_eNB == 4 && ri == 2) return 11;
     AssertFatal(1 == 0, "illegal combination p %d, ri %d, no_pmi %d\n",
-                cc->p_eNB, 
-                ri, 
+                cc->p_eNB,
+                ri,
                 no_pmi);
   } else if (cqi_ReportPeriodic->choice.setup.cqi_FormatIndicatorPeriodic.present == LTE_CQI_ReportPeriodic__setup__cqi_FormatIndicatorPeriodic_PR_subbandCQI) {
     if (no_pmi == 1 || ri == 1) return (4 + Ltab[cc->mib->message.dl_Bandwidth]);
@@ -1111,11 +1111,11 @@ fill_nfapi_dl_dci_1A(nfapi_dl_config_request_pdu_t *dl_config_pdu,
                      uint8_t                       mcs,
                      uint8_t                       ndi,
                      uint8_t                       rv,
-                     uint8_t                       vrb_flag) 
+                     uint8_t                       vrb_flag)
 //------------------------------------------------------------------------------
 {
   memset((void *) dl_config_pdu, 0,sizeof(nfapi_dl_config_request_pdu_t));
-  
+
   dl_config_pdu->pdu_type                                                          = NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE;
   dl_config_pdu->pdu_size                                                          = (uint8_t) (2 + sizeof(nfapi_dl_config_dci_dl_pdu));
   dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tl.tag                                 = NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL8_TAG;
@@ -1136,12 +1136,12 @@ fill_nfapi_dl_dci_1A(nfapi_dl_config_request_pdu_t *dl_config_pdu,
 
 //------------------------------------------------------------------------------
 void
-program_dlsch_acknak(module_id_t module_idP, 
-                     int CC_idP, 
+program_dlsch_acknak(module_id_t module_idP,
+                     int CC_idP,
                      int UE_idP,
-                     frame_t frameP, 
+                     frame_t frameP,
                      sub_frame_t subframeP,
-                     uint8_t cce_idx) 
+                     uint8_t cce_idx)
 //------------------------------------------------------------------------------
 {
   eNB_MAC_INST                           *eNB                         = RC.mac[module_idP];
@@ -1155,8 +1155,8 @@ program_dlsch_acknak(module_id_t module_idP,
   nfapi_ul_config_harq_information       *harq_information            = NULL;
 #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 2, 0))
   struct LTE_PhysicalConfigDedicated__ext2 *ext2 = UE_list->UE_template[CC_idP][UE_idP].physicalConfigDedicated->ext2;
-  if (ext2 && 
-      ext2->pucch_ConfigDedicated_v1020 && 
+  if (ext2 &&
+      ext2->pucch_ConfigDedicated_v1020 &&
       ext2->pucch_ConfigDedicated_v1020->simultaneousPUCCH_PUSCH_r10 &&
       *ext2->pucch_ConfigDedicated_v1020->simultaneousPUCCH_PUSCH_r10 == LTE_PUCCH_ConfigDedicated_v1020__simultaneousPUCCH_PUSCH_r10_true)
     use_simultaneous_pucch_pusch = 1;
@@ -1164,22 +1164,22 @@ program_dlsch_acknak(module_id_t module_idP,
 #endif
   // pucch1 and pusch feedback is similar, namely in n+k subframes from now
   // This is used in the following "if/else" condition to check if there isn't or is already an UL grant in n+k
-  int16_t ul_absSF = get_pucch1_absSF(&cc[CC_idP], 
+  int16_t ul_absSF = get_pucch1_absSF(&cc[CC_idP],
                                       subframeP + (10 * frameP));
 
-  if ((ul_config_pdu = has_ul_grant(module_idP, 
-                                    CC_idP, 
-                                    ul_absSF, 
+  if ((ul_config_pdu = has_ul_grant(module_idP,
+                                    CC_idP,
+                                    ul_absSF,
                                     rnti)) == NULL) {
     // no UL grant so
     // Program ACK/NAK alone Format 1a/b or 3
     ul_req = &eNB->UL_req_tmp[CC_idP][ul_absSF % 10].ul_config_request_body;
     ul_config_pdu = &ul_req->ul_config_pdu_list[ul_req->number_of_pdus];
     // Do PUCCH
-    fill_nfapi_uci_acknak(module_idP, 
-                          CC_idP, 
-                          rnti, 
-                          subframeP + (10 * frameP), 
+    fill_nfapi_uci_acknak(module_idP,
+                          CC_idP,
+                          rnti,
+                          subframeP + (10 * frameP),
                           cce_idx);
   } else {
     /* there is already an existing UL grant so update it if needed
@@ -1193,7 +1193,7 @@ program_dlsch_acknak(module_id_t module_idP,
           harq_information = &ul_config_pdu->ulsch_uci_harq_pdu.harq_information;
           ul_config_pdu->pdu_type = NFAPI_UL_CONFIG_ULSCH_UCI_HARQ_PDU_TYPE;
           LOG_D(MAC, "Frame %d, Subframe %d: Switched UCI HARQ to ULSCH UCI HARQ\n",
-                frameP, 
+                frameP,
                 subframeP);
         } else {
           // Convert it to an NFAPI_UL_CONFIG_ULSCH_HARQ_PDU_TYPE
@@ -1205,7 +1205,7 @@ program_dlsch_acknak(module_id_t module_idP,
           ul_config_pdu->ulsch_harq_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.initial_number_of_resource_blocks
             = ul_config_pdu->ulsch_harq_pdu.ulsch_pdu.ulsch_pdu_rel8.number_of_resource_blocks;  // we don't change the number of resource blocks across retransmissions yet
           LOG_D(MAC,"Frame %d, Subframe %d: Switched UCI HARQ to ULSCH HARQ\n",
-                frameP, 
+                frameP,
                 subframeP);
         }
 
@@ -1291,28 +1291,28 @@ program_dlsch_acknak(module_id_t module_idP,
   }
 
   if (ulsch_harq_information) {
-    fill_nfapi_ulsch_harq_information(module_idP, 
-                                      CC_idP, 
-                                      rnti, 
-                                      ulsch_harq_information, 
+    fill_nfapi_ulsch_harq_information(module_idP,
+                                      CC_idP,
+                                      rnti,
+                                      ulsch_harq_information,
                                       subframeP);
   }
   if (harq_information) {
-    fill_nfapi_harq_information(module_idP, 
-                                CC_idP, 
-                                rnti, 
-                                harq_information, 
+    fill_nfapi_harq_information(module_idP,
+                                CC_idP,
+                                rnti,
+                                harq_information,
                                 cce_idx);
   }
   return;
 }
 
 //------------------------------------------------------------------------------
-uint8_t 
-get_V_UL_DAI(module_id_t module_idP, 
-             int CC_idP, 
+uint8_t
+get_V_UL_DAI(module_id_t module_idP,
+             int CC_idP,
              uint16_t rntiP,
-             sub_frame_t subframeP) 
+             sub_frame_t subframeP)
 //------------------------------------------------------------------------------
 {
   nfapi_hi_dci0_request_body_t *HI_DCI0_req = &RC.mac[module_idP]->HI_DCI0_req[CC_idP][subframeP].hi_dci0_request_body;
@@ -1334,7 +1334,7 @@ fill_nfapi_ulsch_harq_information(module_id_t                            module_
                                   int                                    CC_idP,
                                   uint16_t                               rntiP,
                                   nfapi_ul_config_ulsch_harq_information *harq_information,
-                                  sub_frame_t                            subframeP) 
+                                  sub_frame_t                            subframeP)
 //------------------------------------------------------------------------------
 {
   eNB_MAC_INST *eNB     = RC.mac[module_idP];
@@ -1347,10 +1347,10 @@ fill_nfapi_ulsch_harq_information(module_id_t                            module_
   AssertFatal(UE_list != NULL, "UE_list is null\n");
 
   LTE_PhysicalConfigDedicated_t *physicalConfigDedicated = UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated;
-  AssertFatal(physicalConfigDedicated != NULL, "physicalConfigDedicated for rnti %x is null\n", 
+  AssertFatal(physicalConfigDedicated != NULL, "physicalConfigDedicated for rnti %x is null\n",
               rntiP);
 
-  struct LTE_PUSCH_ConfigDedicated *puschConfigDedicated = physicalConfigDedicated->pusch_ConfigDedicated;           
+  struct LTE_PUSCH_ConfigDedicated *puschConfigDedicated = physicalConfigDedicated->pusch_ConfigDedicated;
   AssertFatal(puschConfigDedicated != NULL, "physicalConfigDedicated->puschConfigDedicated for rnti %x is null\n",
               rntiP);
 
@@ -1388,9 +1388,9 @@ fill_nfapi_ulsch_harq_information(module_id_t                            module_
         harq_information_rel10->harq_size = 1;
       else {
         if (harq_information_rel10->ack_nack_mode == 1)
-          harq_information_rel10->harq_size = get_V_UL_DAI(module_idP, 
-                                                           CC_idP, 
-                                                           rntiP, 
+          harq_information_rel10->harq_size = get_V_UL_DAI(module_idP,
+                                                           CC_idP,
+                                                           rntiP,
                                                            subframeP);
         else
           harq_information_rel10->harq_size = 1;
@@ -1403,9 +1403,9 @@ fill_nfapi_ulsch_harq_information(module_id_t                            module_
         harq_information_rel10->harq_size = 2;
       } else {
         if (harq_information_rel10->ack_nack_mode == 1)
-          harq_information_rel10->harq_size = get_V_UL_DAI(module_idP, 
-                                                           CC_idP, 
-                                                           rntiP, 
+          harq_information_rel10->harq_size = get_V_UL_DAI(module_idP,
+                                                           CC_idP,
+                                                           rntiP,
                                                            subframeP);
         else
           harq_information_rel10->harq_size = 2;
@@ -1417,7 +1417,7 @@ fill_nfapi_ulsch_harq_information(module_id_t                            module_
 }
 
 //------------------------------------------------------------------------------
-uint8_t 
+uint8_t
 Np[6][4] = {
   {0, 1, 3, 5},
   {0, 3, 8, 13},
@@ -1430,10 +1430,10 @@ Np[6][4] = {
 
 // This is part of the PUCCH allocation procedure (see Section 10.1 36.213)
 //------------------------------------------------------------------------------
-uint16_t 
+uint16_t
 getNp(int dl_Bandwidth,
       uint8_t nCCE,
-      uint8_t plus1) 
+      uint8_t plus1)
 //------------------------------------------------------------------------------
 {
   AssertFatal(dl_Bandwidth < 6, "dl_Bandwidth %d>5\n", dl_Bandwidth);
@@ -1453,27 +1453,27 @@ fill_nfapi_harq_information(module_id_t                      module_idP,
                             int                              CC_idP,
                             uint16_t                         rntiP,
                             nfapi_ul_config_harq_information *harq_information,
-                            uint8_t                          cce_idxP) 
+                            uint8_t                          cce_idxP)
 //------------------------------------------------------------------------------
 {
   eNB_MAC_INST *eNB     = RC.mac[module_idP];
   COMMON_channels_t *cc = &eNB->common_channels[CC_idP];
   UE_list_t *UE_list    = &eNB->UE_list;
 
-  int UE_id = find_UE_id(module_idP, 
+  int UE_id = find_UE_id(module_idP,
                          rntiP);
 
   AssertFatal(UE_id >= 0, "UE_id cannot be found, impossible\n");
   AssertFatal(UE_list != NULL, "UE_list is null\n");
   harq_information->harq_information_rel11.tl.tag        = NFAPI_UL_CONFIG_REQUEST_HARQ_INFORMATION_REL11_TAG;
   harq_information->harq_information_rel11.num_ant_ports = 1;
-  
+
   LTE_PhysicalConfigDedicated_t *physicalConfigDedicated = UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated;
   struct LTE_PUCCH_ConfigDedicated *pucch_ConfigDedicated = NULL;
   if (physicalConfigDedicated != NULL) pucch_ConfigDedicated = physicalConfigDedicated->pucch_ConfigDedicated;
 
-  switch (get_tmode(module_idP, 
-                    CC_idP, 
+  switch (get_tmode(module_idP,
+                    CC_idP,
                     UE_id)) {
     case 1:
     case 2:
@@ -1494,7 +1494,7 @@ fill_nfapi_harq_information(module_id_t                      module_idP,
         }
 
         harq_information->harq_information_rel10_tdd.tl.tag                    = NFAPI_UL_CONFIG_REQUEST_HARQ_INFORMATION_REL10_TDD_TAG;
-        harq_information->harq_information_rel10_tdd.n_pucch_1_0               
+        harq_information->harq_information_rel10_tdd.n_pucch_1_0
           = getNp(cc->mib->message.dl_Bandwidth, cce_idxP, 0) + cc->radioResourceConfigCommon->pucch_ConfigCommon.n1PUCCH_AN + cce_idxP;
         harq_information->harq_information_rel10_tdd.number_of_pucch_resources = 1;
       } else {
@@ -1540,7 +1540,7 @@ fill_nfapi_uci_acknak(module_id_t module_idP,
                       int         CC_idP,
                       uint16_t    rntiP,
                       uint16_t    absSFP,
-                      uint8_t     cce_idxP) 
+                      uint8_t     cce_idxP)
 //------------------------------------------------------------------------------
 {
   eNB_MAC_INST                   *eNB           = RC.mac[module_idP];
@@ -1550,24 +1550,24 @@ fill_nfapi_uci_acknak(module_id_t module_idP,
   nfapi_ul_config_request_body_t *ul_req_body   = &ul_req->ul_config_request_body;
   nfapi_ul_config_request_pdu_t  *ul_config_pdu = &ul_req_body->ul_config_pdu_list[ul_req_body->number_of_pdus];
   memset((void *) ul_config_pdu, 0, sizeof(nfapi_ul_config_request_pdu_t));
-  
+
   ul_config_pdu->pdu_type                                               = NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE;
   ul_config_pdu->pdu_size                                               = (uint8_t) (2 + sizeof(nfapi_ul_config_uci_harq_pdu));
   ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_UE_INFORMATION_REL8_TAG;
   ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel8.handle = 0;  // don't know how to use this
   ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel8.rnti   = rntiP;
 
-  fill_nfapi_harq_information(module_idP, 
+  fill_nfapi_harq_information(module_idP,
                               CC_idP,
                               rntiP,
-                              &ul_config_pdu->uci_harq_pdu.harq_information, 
+                              &ul_config_pdu->uci_harq_pdu.harq_information,
                               cce_idxP);
   LOG_D(MAC, "Filled in UCI HARQ request for rnti %x SF %d.%d acknakSF %d.%d, cce_idxP %d-> n1_pucch %d\n",
-        rntiP, 
-        absSFP / 10, 
-        absSFP % 10, 
+        rntiP,
+        absSFP / 10,
+        absSFP % 10,
         ackNAK_absSF / 10,
-        ackNAK_absSF % 10, 
+        ackNAK_absSF % 10,
         cce_idxP,
         ul_config_pdu->uci_harq_pdu.harq_information.harq_information_rel9_fdd.n_pucch_1_0);
 
@@ -1595,7 +1595,7 @@ fill_nfapi_dlsch_config(eNB_MAC_INST *eNB,
                         uint8_t transport_block_to_codeword_swap_flag,
                         uint8_t transmission_scheme,
                         uint8_t number_of_layers,
-                        uint8_t number_of_subbands,   
+                        uint8_t number_of_subbands,
                         // uint8_t codebook_index,
                         uint8_t ue_category_capacity,
                         uint8_t pa,
@@ -1604,7 +1604,7 @@ fill_nfapi_dlsch_config(eNB_MAC_INST *eNB,
                         uint8_t nprb,
                         uint8_t transmission_mode,
                         uint8_t num_bf_prb_per_subband,
-                        uint8_t num_bf_vector) 
+                        uint8_t num_bf_vector)
 //------------------------------------------------------------------------------
 {
   nfapi_dl_config_request_pdu_t *dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu];
@@ -1646,13 +1646,13 @@ fill_nfapi_tx_req(nfapi_tx_request_body_t *tx_req_body,
                   uint16_t                absSF,
                   uint16_t                pdu_length,
                   int16_t                 pdu_index,
-                  uint8_t                 *pdu) 
+                  uint8_t                 *pdu)
 //------------------------------------------------------------------------------
 {
   nfapi_tx_request_pdu_t *TX_req = &tx_req_body->tx_pdu_list[tx_req_body->number_of_pdus];
-   
+
   LOG_D(MAC, "Filling TX_req %d for pdu length %d\n",
-        tx_req_body->number_of_pdus, 
+        tx_req_body->number_of_pdus,
         pdu_length);
 
   TX_req->pdu_length                 = pdu_length;
@@ -1686,7 +1686,7 @@ fill_nfapi_ulsch_config_request_rel8(nfapi_ul_config_request_pdu_t *ul_config_pd
                                      uint8_t                        ul_tx_mode,
                                      uint8_t                        current_tx_nb,
                                      uint8_t                        n_srs,
-                                     uint16_t                       size) 
+                                     uint16_t                       size)
 {
   uint8_t ri_size = 0;
 
@@ -1737,7 +1737,7 @@ fill_nfapi_ulsch_config_request_rel8(nfapi_ul_config_request_pdu_t *ul_config_pd
     nfapi_ul_config_cqi_ri_information_rel9_t *ri_information = &ul_config_pdu->ulsch_cqi_ri_pdu.cqi_ri_information.cqi_ri_information_rel9;
     int max_ri = (1 << ri_information->aperiodic_cqi_pmi_ri_report.cc[0].ri_size);
     for (int ri = 0; ri < max_ri; ri++) {
-      ri_information->aperiodic_cqi_pmi_ri_report.cc[0].dl_cqi_pmi_size[ri] 
+      ri_information->aperiodic_cqi_pmi_ri_report.cc[0].dl_cqi_pmi_size[ri]
         = get_dl_cqi_pmi_size_pusch(cc,
                                     tmode,
                                     1 + ri,
@@ -1752,11 +1752,11 @@ fill_nfapi_ulsch_config_request_rel8(nfapi_ul_config_request_pdu_t *ul_config_pd
 #if (LTE_RRC_VERSION >= MAKE_VERSION(13, 0, 0))
 //------------------------------------------------------------------------------
 void
-fill_nfapi_ulsch_config_request_emtc(nfapi_ul_config_request_pdu_t *ul_config_pdu, 
+fill_nfapi_ulsch_config_request_emtc(nfapi_ul_config_request_pdu_t *ul_config_pdu,
                                      uint8_t ue_type,
                                      uint16_t total_number_of_repetitions,
                                      uint16_t repetition_number,
-                                     uint16_t initial_transmission_sf_io) 
+                                     uint16_t initial_transmission_sf_io)
 //------------------------------------------------------------------------------
 {
   // Re13 fields
@@ -1769,8 +1769,8 @@ fill_nfapi_ulsch_config_request_emtc(nfapi_ul_config_request_pdu_t *ul_config_pd
 }
 
 //------------------------------------------------------------------------------
-int 
-get_numnarrowbands(long dl_Bandwidth) 
+int
+get_numnarrowbands(long dl_Bandwidth)
 //------------------------------------------------------------------------------
 {
   int nb_tab[6] = { 1, 2, 4, 8, 12, 16 };
@@ -1779,8 +1779,8 @@ get_numnarrowbands(long dl_Bandwidth)
 }
 
 //------------------------------------------------------------------------------
-int 
-get_numnarrowbandbits(long dl_Bandwidth) 
+int
+get_numnarrowbandbits(long dl_Bandwidth)
 //------------------------------------------------------------------------------
 {
   int nbbits_tab[6] = { 0, 1, 2, 3, 4, 4 };
@@ -1790,24 +1790,24 @@ get_numnarrowbandbits(long dl_Bandwidth)
 
 //This implements the frame/subframe condition for first subframe of MPDCCH transmission (Section 9.1.5 36.213, Rel 13/14)
 //------------------------------------------------------------------------------
-int 
+int
 startSF_fdd_RA_times2[8] = { 2, 3, 4, 5, 8, 10, 16, 20 };
 //------------------------------------------------------------------------------
 
 //------------------------------------------------------------------------------
-int 
+int
 startSF_tdd_RA[7] = { 1, 2, 4, 5, 8, 10, 20 };
 //------------------------------------------------------------------------------
 
 //------------------------------------------------------------------------------
 int
-mpdcch_sf_condition(eNB_MAC_INST *eNB, 
-                    int CC_id, 
+mpdcch_sf_condition(eNB_MAC_INST *eNB,
+                    int CC_id,
                     frame_t frameP,
-                    sub_frame_t subframeP, 
+                    sub_frame_t subframeP,
                     int rmax,
-                    MPDCCH_TYPES_t mpdcch_type, 
-                    int UE_id) 
+                    MPDCCH_TYPES_t mpdcch_type,
+                    int UE_id)
 //------------------------------------------------------------------------------
 {
   struct LTE_PRACH_ConfigSIB_v1310 *ext4_prach = eNB->common_channels[CC_id].radioResourceConfigCommon_BR-> ext4->prach_ConfigCommon_v1310;
@@ -1866,9 +1866,9 @@ mpdcch_sf_condition(eNB_MAC_INST *eNB,
 }
 
 //------------------------------------------------------------------------------
-int 
-narrowband_to_first_rb(COMMON_channels_t *cc, 
-                       int nb_index) 
+int
+narrowband_to_first_rb(COMMON_channels_t *cc,
+                       int nb_index)
 //------------------------------------------------------------------------------
 {
   switch (cc->mib->message.dl_Bandwidth) {
@@ -1906,7 +1906,7 @@ narrowband_to_first_rb(COMMON_channels_t *cc,
 #endif
 
 //------------------------------------------------------------------------------
-void 
+void
 init_ue_sched_info(void)
 //------------------------------------------------------------------------------
 {
@@ -1931,9 +1931,9 @@ init_ue_sched_info(void)
 }
 
 //------------------------------------------------------------------------------
-unsigned char 
-get_ue_weight(module_id_t module_idP, 
-              int CC_idP, 
+unsigned char
+get_ue_weight(module_id_t module_idP,
+              int CC_idP,
               int ue_idP)
 //------------------------------------------------------------------------------
 {
@@ -1941,8 +1941,8 @@ get_ue_weight(module_id_t module_idP,
 }
 
 //------------------------------------------------------------------------------
-int 
-find_UE_id(module_id_t mod_idP, 
+int
+find_UE_id(module_id_t mod_idP,
            rnti_t rntiP)
 //------------------------------------------------------------------------------
 {
@@ -1961,9 +1961,9 @@ find_UE_id(module_id_t mod_idP,
 }
 
 //------------------------------------------------------------------------------
-int 
-find_RA_id(module_id_t mod_idP, 
-           int CC_idP, 
+int
+find_RA_id(module_id_t mod_idP,
+           int CC_idP,
            rnti_t rntiP)
 //------------------------------------------------------------------------------
 {
@@ -1973,8 +1973,8 @@ find_RA_id(module_id_t mod_idP,
 
   for (RA_id = 0; RA_id < NB_RA_PROC_MAX; RA_id++) {
     LOG_D(MAC, "Checking RA_id %d for %x : state %d\n",
-          RA_id, 
-          rntiP, 
+          RA_id,
+          rntiP,
           ra[RA_id].state);
 
     if (ra[RA_id].state != IDLE && ra[RA_id].rnti == rntiP)
@@ -1985,8 +1985,8 @@ find_RA_id(module_id_t mod_idP,
 }
 
 //------------------------------------------------------------------------------
-int 
-UE_num_active_CC(UE_list_t *listP, 
+int
+UE_num_active_CC(UE_list_t *listP,
                  int ue_idP)
 //------------------------------------------------------------------------------
 {
@@ -1994,25 +1994,23 @@ UE_num_active_CC(UE_list_t *listP,
 }
 
 //------------------------------------------------------------------------------
-int 
-UE_PCCID(module_id_t mod_idP, 
+int
+UE_PCCID(module_id_t mod_idP,
          int ue_idP)
 //------------------------------------------------------------------------------
 {
-  if (!RC.mac || !RC.mac[mod_idP]) return 0;
-
   return (RC.mac[mod_idP]->UE_list.pCC_id[ue_idP]);
 }
 
 //------------------------------------------------------------------------------
-rnti_t 
-UE_RNTI(module_id_t mod_idP, 
+rnti_t
+UE_RNTI(module_id_t mod_idP,
         int ue_idP)
 //------------------------------------------------------------------------------
 {
   if (!RC.mac || !RC.mac[mod_idP]) return 0;
 
-  rnti_t rnti = RC.mac[mod_idP]->UE_list.UE_template[UE_PCCID(mod_idP, 
+  rnti_t rnti = RC.mac[mod_idP]->UE_list.UE_template[UE_PCCID(mod_idP,
                                                               ue_idP)][ue_idP].rnti;
 
   if (rnti > 0) {
@@ -2025,13 +2023,11 @@ UE_RNTI(module_id_t mod_idP,
 }
 
 //------------------------------------------------------------------------------
-boolean_t 
-is_UE_active(module_id_t mod_idP, 
+boolean_t
+is_UE_active(module_id_t mod_idP,
              int ue_idP)
 //------------------------------------------------------------------------------
 {
-  if (!RC.mac || !RC.mac[mod_idP]) return 0;
-
   return (RC.mac[mod_idP]->UE_list.active[ue_idP]);
 }
 
@@ -2039,7 +2035,7 @@ is_UE_active(module_id_t mod_idP,
 unsigned char
 get_aggregation(uint8_t bw_index,
                 uint8_t cqi,
-                uint8_t dci_fmt) 
+                uint8_t dci_fmt)
 //------------------------------------------------------------------------------
 {
   unsigned char aggregation = 3;
@@ -2080,28 +2076,28 @@ get_aggregation(uint8_t bw_index,
         cqi,
         bw_index,
         dci_fmt);
-        
+
   return 1 << aggregation;
 }
 
 //------------------------------------------------------------------------------
-void 
-dump_ue_list(UE_list_t *listP, 
-             int ul_flag) 
+void
+dump_ue_list(UE_list_t *listP,
+             int ul_flag)
 //------------------------------------------------------------------------------
 {
   int j;
 
   if (ul_flag == 0) {
     for (j = listP->head; j >= 0; j = listP->next[j]) {
-      LOG_T(MAC, "node %d => %d\n", 
-            j, 
+      LOG_T(MAC, "node %d => %d\n",
+            j,
             listP->next[j]);
     }
   } else {
     for (j = listP->head_ul; j >= 0; j = listP->next_ul[j]) {
-      LOG_T(MAC, "node %d => %d\n", 
-            j, 
+      LOG_T(MAC, "node %d => %d\n",
+            j,
             listP->next_ul[j]);
     }
   }
@@ -2109,15 +2105,15 @@ dump_ue_list(UE_list_t *listP,
 }
 
 //------------------------------------------------------------------------------
-int 
-add_new_ue(module_id_t mod_idP, 
-           int cc_idP, 
-           rnti_t rntiP, 
+int
+add_new_ue(module_id_t mod_idP,
+           int cc_idP,
+           rnti_t rntiP,
            int harq_pidP
 #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
            , uint8_t rach_resource_type
 #endif
-           ) 
+           )
 //------------------------------------------------------------------------------
 {
   int UE_id;
@@ -2125,10 +2121,10 @@ add_new_ue(module_id_t mod_idP,
   UE_list_t *UE_list = &RC.mac[mod_idP]->UE_list;
 
   LOG_D(MAC, "[eNB %d, CC_id %d] Adding UE with rnti %x (next avail %d, num_UEs %d)\n",
-        mod_idP, 
-        cc_idP, 
-        rntiP, 
-        UE_list->avail, 
+        mod_idP,
+        cc_idP,
+        rntiP,
+        UE_list->avail,
         UE_list->num_UEs);
 
   dump_ue_list(UE_list, 0);
@@ -2139,7 +2135,7 @@ add_new_ue(module_id_t mod_idP,
 
     UE_id = i;
     memset(&UE_list->UE_template[cc_idP][UE_id], 0, sizeof(UE_TEMPLATE));
-    
+
     UE_list->UE_template[cc_idP][UE_id].rnti = rntiP;
     UE_list->UE_template[cc_idP][UE_id].configured = FALSE;
     UE_list->numactiveCCs[UE_id] = 1;
@@ -2157,10 +2153,10 @@ add_new_ue(module_id_t mod_idP,
     UE_list->UE_template[cc_idP][UE_id].rach_resource_type = rach_resource_type;
 #endif
 
-    memset((void *) &UE_list->UE_sched_ctrl[UE_id], 
+    memset((void *) &UE_list->UE_sched_ctrl[UE_id],
            0,
            sizeof(UE_sched_ctrl));
-    memset((void *) &UE_list->eNB_UE_stats[cc_idP][UE_id], 
+    memset((void *) &UE_list->eNB_UE_stats[cc_idP][UE_id],
            0,
            sizeof(eNB_UE_STATS));
     UE_list->UE_sched_ctrl[UE_id].ue_reestablishment_reject_timer = 0;
@@ -2179,25 +2175,25 @@ add_new_ue(module_id_t mod_idP,
     eNB_ulsch_info[mod_idP][cc_idP][UE_id].status = S_UL_WAITING;
     eNB_dlsch_info[mod_idP][cc_idP][UE_id].status = S_DL_WAITING;
     LOG_D(MAC, "[eNB %d] Add UE_id %d on Primary CC_id %d: rnti %x\n",
-          mod_idP, 
-          UE_id, 
-          cc_idP, 
+          mod_idP,
+          UE_id,
+          cc_idP,
           rntiP);
-    dump_ue_list(UE_list, 
+    dump_ue_list(UE_list,
                  0);
     return (UE_id);
   }
 
   // printf("MAC: cannot add new UE for rnti %x\n", rntiP);
   LOG_E(MAC, "error in add_new_ue(), could not find space in UE_list, Dumping UE list\n");
-  dump_ue_list(UE_list, 
+  dump_ue_list(UE_list,
                0);
   return -1;
 }
 
 //------------------------------------------------------------------------------
-int 
-rrc_mac_remove_ue(module_id_t mod_idP, 
+int
+rrc_mac_remove_ue(module_id_t mod_idP,
                   rnti_t rntiP)
 //------------------------------------------------------------------------------
 {
@@ -2209,7 +2205,7 @@ rrc_mac_remove_ue(module_id_t mod_idP,
   eNB_UE_STATS *ue_stats;
 
   if (UE_id == -1) {
-    LOG_W(MAC,"rrc_mac_remove_ue: UE %x not found\n", 
+    LOG_W(MAC,"rrc_mac_remove_ue: UE %x not found\n",
           rntiP);
     return 0;
   }
@@ -2218,7 +2214,7 @@ rrc_mac_remove_ue(module_id_t mod_idP,
                     UE_id);
   LOG_I(MAC,"Removing UE %d from Primary CC_id %d (rnti %x)\n",
         UE_id,
-        pCC_id, 
+        pCC_id,
         rntiP);
   dump_ue_list(UE_list,
                0);
@@ -2281,12 +2277,12 @@ rrc_mac_remove_ue(module_id_t mod_idP,
   eNB_dlsch_info[mod_idP][pCC_id][UE_id].serving_num = 0;
 
   // check if this has an RA process active
-  if (find_RA_id(mod_idP, 
-                 pCC_id, 
+  if (find_RA_id(mod_idP,
+                 pCC_id,
                  rntiP) != -1) {
-    cancel_ra_proc(mod_idP, 
-                   pCC_id, 
-                   0, 
+    cancel_ra_proc(mod_idP,
+                   pCC_id,
+                   0,
                    rntiP);
   }
 
@@ -2319,10 +2315,10 @@ rrc_mac_remove_ue(module_id_t mod_idP,
 }
 
 //------------------------------------------------------------------------------
-int 
-prev(UE_list_t *listP, 
-     int nodeP, 
-     int ul_flag) 
+int
+prev(UE_list_t *listP,
+     int nodeP,
+     int ul_flag)
 //------------------------------------------------------------------------------
 {
   int j;
@@ -2350,32 +2346,32 @@ prev(UE_list_t *listP,
   }
 
   LOG_E(MAC, "error in prev(), could not find previous to %d in UE_list %s, should never happen, Dumping UE list\n",
-        nodeP, 
+        nodeP,
         (ul_flag == 0) ? "DL" : "UL");
-  dump_ue_list(listP, 
+  dump_ue_list(listP,
                ul_flag);
   return -1;
 }
 
 //------------------------------------------------------------------------------
-void 
-swap_UEs(UE_list_t *listP, 
-         int nodeiP, 
-         int nodejP, 
-         int ul_flag) 
+void
+swap_UEs(UE_list_t *listP,
+         int nodeiP,
+         int nodejP,
+         int ul_flag)
 //------------------------------------------------------------------------------
 {
   int prev_i, prev_j, next_i, next_j;
-  LOG_T(MAC, "Swapping UE %d,%d\n", 
-        nodeiP, 
+  LOG_T(MAC, "Swapping UE %d,%d\n",
+        nodeiP,
         nodejP);
-  dump_ue_list(listP, 
+  dump_ue_list(listP,
                ul_flag);
-  prev_i = prev(listP, 
-                nodeiP, 
+  prev_i = prev(listP,
+                nodeiP,
                 ul_flag);
-  prev_j = prev(listP, 
-                nodejP, 
+  prev_j = prev(listP,
+                nodejP,
                 ul_flag);
   AssertFatal((prev_i >= 0) && (prev_j >= 0), "swap_UEs: problem");
 
@@ -2388,9 +2384,9 @@ swap_UEs(UE_list_t *listP,
   }
 
   LOG_T(MAC, "[%s] next_i %d, next_i, next_j %d, head %d \n",
-        (ul_flag == 0) ? "DL" : "UL", 
-        next_i, 
-        next_j, 
+        (ul_flag == 0) ? "DL" : "UL",
+        next_i,
+        next_j,
         listP->head);
 
   if (ul_flag == 0) {
@@ -2419,12 +2415,12 @@ swap_UEs(UE_list_t *listP,
       listP->next[nodeiP] = next_j;
 
       if (nodeiP == listP->head) {
-        LOG_T(MAC, "changing head to %d\n", 
+        LOG_T(MAC, "changing head to %d\n",
               nodejP);
         listP->head = nodejP;
         listP->next[prev_j] = nodeiP;
       } else if (nodejP == listP->head) {
-        LOG_D(MAC, "changing head to %d\n", 
+        LOG_D(MAC, "changing head to %d\n",
               nodeiP);
         listP->head = nodeiP;
         listP->next[prev_i] = nodejP;
@@ -2459,12 +2455,12 @@ swap_UEs(UE_list_t *listP,
       listP->next_ul[nodeiP] = next_j;
 
       if (nodeiP == listP->head_ul) {
-        LOG_T(MAC, "[UL]changing head to %d\n", 
+        LOG_T(MAC, "[UL]changing head to %d\n",
               nodejP);
         listP->head_ul = nodejP;
         listP->next_ul[prev_j] = nodeiP;
       } else if (nodejP == listP->head_ul) {
-        LOG_T(MAC, "[UL]changing head to %d\n", 
+        LOG_T(MAC, "[UL]changing head to %d\n",
               nodeiP);
         listP->head_ul = nodeiP;
         listP->next_ul[prev_i] = nodejP;
@@ -2476,7 +2472,7 @@ swap_UEs(UE_list_t *listP,
   }
 
   LOG_T(MAC, "After swap\n");
-  dump_ue_list(listP, 
+  dump_ue_list(listP,
                ul_flag);
   return;
 }
@@ -2484,9 +2480,9 @@ swap_UEs(UE_list_t *listP,
 // This has to be updated to include BSR information
 //------------------------------------------------------------------------------
 uint8_t
-UE_is_to_be_scheduled(module_id_t module_idP, 
-                      int CC_id, 
-                      uint8_t UE_id) 
+UE_is_to_be_scheduled(module_id_t module_idP,
+                      int CC_id,
+                      uint8_t UE_id)
 //------------------------------------------------------------------------------
 {
   UE_TEMPLATE *UE_template = &RC.mac[module_idP]->UE_list.UE_template[CC_id][UE_id];
@@ -2499,24 +2495,24 @@ UE_is_to_be_scheduled(module_id_t module_idP,
   rnti_t ue_rnti = UE_RNTI(module_idP,
                            UE_id);
   LOG_D(MAC, "[eNB %d][PUSCH] Checking UL requirements UE %d/%x\n",
-        module_idP, 
-        UE_id, 
+        module_idP,
+        UE_id,
         ue_rnti);
 
   if (UE_template->scheduled_ul_bytes < UE_template->estimated_ul_buffer ||
       UE_template->ul_SR > 0 || // uplink scheduling request
       (UE_sched_ctl->ul_inactivity_timer > 20 && UE_sched_ctl->ul_scheduled == 0) ||  // every 2 frames when RRC_CONNECTED
-      (UE_sched_ctl->ul_inactivity_timer > 10 && 
-       UE_sched_ctl->ul_scheduled == 0 && 
-       mac_eNB_get_rrc_status(module_idP, 
+      (UE_sched_ctl->ul_inactivity_timer > 10 &&
+       UE_sched_ctl->ul_scheduled == 0 &&
+       mac_eNB_get_rrc_status(module_idP,
                               ue_rnti) < RRC_CONNECTED)) { // every Frame when not RRC_CONNECTED
     LOG_D(MAC, "[eNB %d][PUSCH] UE %d/%x should be scheduled (BSR0 estimated size %d, SR %d)\n",
-          module_idP, 
-          UE_id, 
+          module_idP,
+          UE_id,
           ue_rnti,
           UE_template->ul_buffer_info[LCGID0], UE_template->ul_SR);
     return 1;
-  } 
+  }
   return 0;
 }
 
@@ -2524,7 +2520,7 @@ UE_is_to_be_scheduled(module_id_t module_idP,
 uint8_t
 get_tmode(module_id_t module_idP,
           int CC_idP,
-          int UE_idP) 
+          int UE_idP)
 //------------------------------------------------------------------------------
 {
   eNB_MAC_INST *eNB = RC.mac[module_idP];
@@ -2537,8 +2533,8 @@ get_tmode(module_id_t module_idP,
     return (cc->p_eNB);
   }
 
-  AssertFatal(physicalConfigDedicated->antennaInfo != NULL, 
-              "antennaInfo (mod_id %d) is null for CCId %d, UEid %d, physicalConfigDedicated %p\n", 
+  AssertFatal(physicalConfigDedicated->antennaInfo != NULL,
+              "antennaInfo (mod_id %d) is null for CCId %d, UEid %d, physicalConfigDedicated %p\n",
               module_idP,
               CC_idP,
 		          UE_idP,
@@ -2565,10 +2561,10 @@ get_tmode(module_id_t module_idP,
 
 //------------------------------------------------------------------------------
 int8_t
-get_ULharq(module_id_t module_idP, 
-           int CC_idP, 
+get_ULharq(module_id_t module_idP,
+           int CC_idP,
            uint16_t frameP,
-           uint8_t subframeP) 
+           uint8_t subframeP)
 //------------------------------------------------------------------------------
 {
   int8_t ret = -1;
@@ -2636,16 +2632,16 @@ get_ULharq(module_id_t module_idP,
   }
 
   AssertFatal(ret != -1, "invalid harq_pid(%d) at SFN/SF = %d/%d\n", (int8_t) ret,
-              frameP, 
+              frameP,
               subframeP);
   return ret;
 }
 
 //------------------------------------------------------------------------------
-uint16_t 
-getRIV(uint16_t N_RB_DL, 
-       uint16_t RBstart, 
-       uint16_t Lcrbs) 
+uint16_t
+getRIV(uint16_t N_RB_DL,
+       uint16_t RBstart,
+       uint16_t Lcrbs)
 //------------------------------------------------------------------------------
 {
   uint16_t RIV;
@@ -2660,10 +2656,10 @@ getRIV(uint16_t N_RB_DL,
 
 //------------------------------------------------------------------------------
 uint32_t
-allocate_prbs(int UE_id, 
-              unsigned char nb_rb, 
+allocate_prbs(int UE_id,
+              unsigned char nb_rb,
               int N_RB_DL,
-              uint32_t *rballoc) 
+              uint32_t *rballoc)
 //------------------------------------------------------------------------------
 {
   int i;
@@ -2695,7 +2691,7 @@ allocate_prbs(int UE_id,
 //------------------------------------------------------------------------------
 int
 get_bw_index(module_id_t module_id,
-             uint8_t CC_id) 
+             uint8_t CC_id)
 //------------------------------------------------------------------------------
 {
   int bw_index = 0;
@@ -2733,7 +2729,7 @@ get_bw_index(module_id_t module_id,
 //------------------------------------------------------------------------------
 int
 get_min_rb_unit(module_id_t module_id,
-                uint8_t CC_id) 
+                uint8_t CC_id)
 //------------------------------------------------------------------------------
 {
   int min_rb_unit = 0;
@@ -2770,21 +2766,21 @@ get_min_rb_unit(module_id_t module_id,
 
 //------------------------------------------------------------------------------
 uint32_t
-allocate_prbs_sub(int nb_rb, 
-                  int N_RB_DL, 
-                  int N_RBG, 
-                  uint8_t *rballoc) 
+allocate_prbs_sub(int nb_rb,
+                  int N_RB_DL,
+                  int N_RBG,
+                  uint8_t *rballoc)
 //------------------------------------------------------------------------------
 {
   int check = 0;    //check1=0,check2=0;
   uint32_t rballoc_dci = 0;
   //uint8_t number_of_subbands=13;
   LOG_T(MAC, "*****Check1RBALLOC****: %d%d%d%d (nb_rb %d,N_RBG %d)\n",
-        rballoc[3], 
-        rballoc[2], 
-        rballoc[1], 
-        rballoc[0], 
-        nb_rb, 
+        rballoc[3],
+        rballoc[2],
+        rballoc[1],
+        rballoc[0],
+        nb_rb,
         N_RBG);
 
   while (nb_rb > 0 && check < N_RBG) {
@@ -2825,15 +2821,15 @@ allocate_prbs_sub(int nb_rb,
   }
 
   // rballoc_dci = (rballoc_dci)&(0x1fff);
-  LOG_T(MAC, "*********RBALLOC : %x\n", 
+  LOG_T(MAC, "*********RBALLOC : %x\n",
         rballoc_dci);
   // exit(-1);
   return rballoc_dci;
 }
 
 //------------------------------------------------------------------------------
-int 
-get_subbandsize(uint8_t dl_Bandwidth) 
+int
+get_subbandsize(uint8_t dl_Bandwidth)
 //------------------------------------------------------------------------------
 {
   uint8_t ss[6] = { 6, 4, 4, 6, 8, 8 };
@@ -2843,8 +2839,8 @@ get_subbandsize(uint8_t dl_Bandwidth)
 }
 
 //------------------------------------------------------------------------------
-int 
-get_nb_subband(int N_RB_DL) 
+int
+get_nb_subband(int N_RB_DL)
 //------------------------------------------------------------------------------
 {
   int nb_sb = 0;
@@ -2882,17 +2878,17 @@ get_nb_subband(int N_RB_DL)
   return nb_sb;
 }
 /*
-void 
-init_CCE_table(int module_idP, 
-               int CC_idP) 
+void
+init_CCE_table(int module_idP,
+               int CC_idP)
 {
-  memset(RC.mac[module_idP]->CCE_table[CC_idP], 
-         0, 
+  memset(RC.mac[module_idP]->CCE_table[CC_idP],
+         0,
          800 * sizeof(int));
 }
 */
-void 
-init_CCE_table(int *CCE_table) 
+void
+init_CCE_table(int *CCE_table)
 {
   memset(CCE_table, 0, 800 * sizeof(int));
 }
@@ -2903,8 +2899,8 @@ get_nCCE_offset(int *CCE_table,
                 const unsigned char L,
                 const int nCCE,
                 const int common_dci,
-                const unsigned short rnti, 
-                const unsigned char subframe) 
+                const unsigned short rnti,
+                const unsigned char subframe)
 //------------------------------------------------------------------------------
 {
   int search_space_free, m, nb_candidates = 0, l, i;
@@ -2944,7 +2940,7 @@ get_nCCE_offset(int *CCE_table,
     }
 
     return -1;
-  } 
+  }
   // Find first available in ue specific search space
   // according to procedure in Section 9.1.1 of 36.213 (v. 8.6)
   // compute Yk
@@ -2967,17 +2963,17 @@ get_nCCE_offset(int *CCE_table,
       break;
 
     default:
-      DevParam(L, 
-               nCCE, 
+      DevParam(L,
+               nCCE,
                rnti);
       break;
   }
 
   LOG_D(MAC, "rnti %x, Yk = %d, nCCE %d (nCCE/L %d),nb_cand %d\n",
-        rnti, 
-        Yk, 
-        nCCE, 
-        nCCE / L, 
+        rnti,
+        Yk,
+        nCCE,
+        nCCE / L,
         nb_candidates);
 
   for (m = 0; m < nb_candidates; m++) {
@@ -3005,11 +3001,11 @@ get_nCCE_offset(int *CCE_table,
 
 //------------------------------------------------------------------------------
 void
-dump_CCE_table(int *CCE_table, 
+dump_CCE_table(int *CCE_table,
                const int nCCE,
-               const unsigned short rnti, 
-               const int subframe, 
-               int L) 
+               const unsigned short rnti,
+               const int subframe,
+               int L)
 //------------------------------------------------------------------------------
 {
   int nb_candidates = 0, i;
@@ -3020,7 +3016,7 @@ dump_CCE_table(int *CCE_table,
     printf("%1d.", CCE_table[i]);
 
     if ((i & 7) == 7)
-      printf("\n CCE %d: ", 
+      printf("\n CCE %d: ",
              i);
   }
 
@@ -3047,19 +3043,19 @@ dump_CCE_table(int *CCE_table,
       break;
   }
 
-  LOG_I(PHY, "rnti %x, Yk*L = %u, nCCE %d (nCCE/L %d),nb_cand*L %d\n", 
+  LOG_I(PHY, "rnti %x, Yk*L = %u, nCCE %d (nCCE/L %d),nb_cand*L %d\n",
          rnti,
-         Yk * L, 
-         nCCE, 
-         nCCE / L, 
+         Yk * L,
+         nCCE,
+         nCCE / L,
          nb_candidates * L);
 }
 
 //------------------------------------------------------------------------------
 uint16_t
-getnquad(COMMON_channels_t *cc, 
-         uint8_t num_pdcch_symbols, 
-         uint8_t mi) 
+getnquad(COMMON_channels_t *cc,
+         uint8_t num_pdcch_symbols,
+         uint8_t mi)
 //------------------------------------------------------------------------------
 {
   uint16_t Nreg = 0;
@@ -3106,21 +3102,21 @@ getnquad(COMMON_channels_t *cc,
 
 //------------------------------------------------------------------------------
 uint16_t
-getnCCE(COMMON_channels_t *cc, 
-        uint8_t num_pdcch_symbols, 
-        uint8_t mi) 
+getnCCE(COMMON_channels_t *cc,
+        uint8_t num_pdcch_symbols,
+        uint8_t mi)
 //------------------------------------------------------------------------------
 {
   AssertFatal(cc != NULL, "cc is null\n");
-  return (getnquad(cc, 
-                   num_pdcch_symbols, 
+  return (getnquad(cc,
+                   num_pdcch_symbols,
                    mi) / 9);
 }
 
 //------------------------------------------------------------------------------
-uint8_t 
-getmi(COMMON_channels_t *cc, 
-      int subframe) 
+uint8_t
+getmi(COMMON_channels_t *cc,
+      int subframe)
 //------------------------------------------------------------------------------
 {
   AssertFatal(cc != NULL, "cc is null\n");
@@ -3178,26 +3174,26 @@ getmi(COMMON_channels_t *cc,
 
 //------------------------------------------------------------------------------
 uint16_t
-get_nCCE_max(COMMON_channels_t *cc, 
-             int num_pdcch_symbols, 
-             int subframe) 
+get_nCCE_max(COMMON_channels_t *cc,
+             int num_pdcch_symbols,
+             int subframe)
 //------------------------------------------------------------------------------
 {
   AssertFatal(cc != NULL, "cc is null\n");
-  return (getnCCE(cc, 
-                  num_pdcch_symbols, 
-                  getmi(cc, 
+  return (getnCCE(cc,
+                  num_pdcch_symbols,
+                  getmi(cc,
                         subframe)));
 }
 
 // Allocate the CCEs
 //------------------------------------------------------------------------------
 int
-allocate_CCEs(int module_idP, 
-              int CC_idP, 
-              frame_t frameP, 
-              sub_frame_t subframeP, 
-              int test_onlyP) 
+allocate_CCEs(int module_idP,
+              int CC_idP,
+              frame_t frameP,
+              sub_frame_t subframeP,
+              int test_onlyP)
 //------------------------------------------------------------------------------
 {
   eNB_MAC_INST *eNB = RC.mac[module_idP];
@@ -3223,9 +3219,9 @@ allocate_CCEs(int module_idP,
 
   nfapi_ul_config_request_body_t *ul_req = &eNB->UL_req_tmp[CC_idP][ackNAK_absSF % 10].ul_config_request_body;
   LOG_D(MAC, "Allocate CCEs subframe %d, test %d : (DL PDU %d, DL DCI %d, UL %d)\n",
-        subframeP, 
-        test_onlyP, 
-        DL_req->number_pdu, 
+        subframeP,
+        test_onlyP,
+        DL_req->number_pdu,
         DL_req->number_dci,
         HI_DCI0_req->number_of_dci);
   DL_req->number_pdcch_ofdm_symbols = 1;
@@ -3238,17 +3234,17 @@ try_again:
   for (i = 0, idci = 0; i < DL_req->number_pdu; i++) {
     dl_config_pduLoop = &dl_config_pdu[i];
     // allocate DL common DCIs first
-    if (dl_config_pduLoop->pdu_type == NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE && 
+    if (dl_config_pduLoop->pdu_type == NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE &&
         dl_config_pduLoop->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type == 2) {
       LOG_D(MAC, "Trying to allocate COMMON DCI %d/%d (%d,%d) : rnti %x, aggreg %d nCCE %d / %d (num_pdcch_symbols %d)\n",
-            idci, 
+            idci,
             DL_req->number_dci + HI_DCI0_req->number_of_dci,
-            DL_req->number_dci, 
+            DL_req->number_dci,
             HI_DCI0_req->number_of_dci,
             dl_config_pduLoop->dci_dl_pdu.dci_dl_pdu_rel8.rnti,
-            dl_config_pduLoop->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level, 
-            nCCE, 
-            nCCE_max, 
+            dl_config_pduLoop->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level,
+            nCCE,
+            nCCE_max,
             DL_req->number_pdcch_ofdm_symbols);
 
       if (nCCE + (dl_config_pduLoop->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level) > nCCE_max) {
@@ -3264,8 +3260,8 @@ try_again:
 
       // number of CCEs left can potentially hold this allocation
       fCCE = get_nCCE_offset(CCE_table,
-                             dl_config_pduLoop->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level, 
-                             nCCE_max, 
+                             dl_config_pduLoop->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level,
+                             nCCE_max,
                              1,
                              dl_config_pduLoop->dci_dl_pdu.dci_dl_pdu_rel8.rnti,
                              subframeP);
@@ -3273,7 +3269,7 @@ try_again:
       if (fCCE == -1) {
         if (DL_req->number_pdcch_ofdm_symbols == max_symbol) {
           LOG_D(MAC, "subframe %d: Dropping Allocation for RNTI %x\n",
-                subframeP, 
+                subframeP,
                 dl_config_pduLoop->dci_dl_pdu.dci_dl_pdu_rel8.rnti);
 
           for (j = 0; j <= i; j++) {
@@ -3286,7 +3282,7 @@ try_again:
                     HI_DCI0_req->number_of_dci,
                     dl_config_pduLoop->dci_dl_pdu.dci_dl_pdu_rel8.rnti,
                     dl_config_pduLoop->dci_dl_pdu.dci_dl_pdu_rel8.dci_format,
-                    dl_config_pduLoop->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level, 
+                    dl_config_pduLoop->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level,
                     nCCE, nCCE_max, DL_req->number_pdcch_ofdm_symbols);
           }
           //dump_CCE_table(CCE_table,nCCE_max,subframeP,dci_alloc->rnti,1<<dci_alloc->L);
@@ -3307,9 +3303,9 @@ try_again:
       if ((test_onlyP%2) == 0) {
         dl_config_pduLoop->dci_dl_pdu.dci_dl_pdu_rel8.cce_idx = fCCE;
         LOG_D(MAC, "Allocate COMMON DCI CCEs subframe %d, test %d => L %d fCCE %d\n",
-              subframeP, 
-              test_onlyP, 
-              dl_config_pduLoop->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level, 
+              subframeP,
+              test_onlyP,
+              dl_config_pduLoop->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level,
               fCCE);
       }
 
@@ -3323,13 +3319,13 @@ try_again:
     // allocate UL DCIs
     if (hi_dci0_pdu[i].pdu_type == NFAPI_HI_DCI0_DCI_PDU_TYPE) {
       LOG_D(MAC, "Trying to allocate format 0 DCI %d/%d (%d,%d) : rnti %x, aggreg %d nCCE %d / %d (num_pdcch_symbols %d)\n",
-            idci, 
+            idci,
             DL_req->number_dci + HI_DCI0_req->number_of_dci,
-            DL_req->number_dci, 
+            DL_req->number_dci,
             HI_DCI0_req->number_of_dci,
             hi_dci0_pduLoop->dci_pdu.dci_pdu_rel8.rnti,
             hi_dci0_pduLoop->dci_pdu.dci_pdu_rel8.aggregation_level,
-            nCCE, nCCE_max, 
+            nCCE, nCCE_max,
             DL_req->number_pdcch_ofdm_symbols);
 
       if (nCCE + hi_dci0_pduLoop->dci_pdu.dci_pdu_rel8.aggregation_level > nCCE_max) {
@@ -3346,15 +3342,15 @@ try_again:
       // number of CCEs left can potentially hold this allocation
       fCCE = get_nCCE_offset(CCE_table,
                              hi_dci0_pduLoop->dci_pdu.dci_pdu_rel8.aggregation_level,
-                             nCCE_max, 
+                             nCCE_max,
                              0,
-                             hi_dci0_pduLoop->dci_pdu.dci_pdu_rel8.rnti, 
+                             hi_dci0_pduLoop->dci_pdu.dci_pdu_rel8.rnti,
                              subframeP);
 
       if (fCCE == -1) {
         if (DL_req->number_pdcch_ofdm_symbols == max_symbol) {
           LOG_D(MAC, "subframe %d: Dropping Allocation for RNTI %x\n",
-                subframeP, 
+                subframeP,
                 hi_dci0_pduLoop->dci_pdu.dci_pdu_rel8.rnti);
 
           for (j = 0; j <= i; j++) {
@@ -3367,7 +3363,7 @@ try_again:
                     HI_DCI0_req->number_of_dci,
                     hi_dci0_pduLoop->dci_pdu.dci_pdu_rel8.rnti,
                     hi_dci0_pduLoop->dci_pdu.dci_pdu_rel8.dci_format,
-                    hi_dci0_pduLoop->dci_pdu.dci_pdu_rel8.aggregation_level, 
+                    hi_dci0_pduLoop->dci_pdu.dci_pdu_rel8.aggregation_level,
                     nCCE, nCCE_max, DL_req->number_pdcch_ofdm_symbols);
           }
           //dump_CCE_table(CCE_table,nCCE_max,subframeP,dci_alloc->rnti,1<<dci_alloc->L);
@@ -3383,13 +3379,13 @@ try_again:
 
       // the allocation is feasible, rnti rule passes
       nCCE += hi_dci0_pduLoop->dci_pdu.dci_pdu_rel8.aggregation_level;
-      LOG_D(MAC, "Allocating at nCCE %d\n", 
+      LOG_D(MAC, "Allocating at nCCE %d\n",
             fCCE);
 
       if ((test_onlyP%2) == 0) {
         hi_dci0_pduLoop->dci_pdu.dci_pdu_rel8.cce_index = fCCE;
-        LOG_D(MAC, "Allocate CCEs subframe %d, test %d\n", 
-              subframeP, 
+        LOG_D(MAC, "Allocate CCEs subframe %d, test %d\n",
+              subframeP,
               test_onlyP);
       }
 
@@ -3403,12 +3399,12 @@ try_again:
     if ((dl_config_pdu[i].pdu_type == NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE)
         && (dl_config_pduLoop->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type == 1)) {
       LOG_D(MAC, "Trying to allocate DL UE-SPECIFIC DCI %d/%d (%d,%d) : rnti %x, aggreg %d nCCE %d / %d (num_pdcch_symbols %d)\n",
-            idci, 
+            idci,
             DL_req->number_dci + HI_DCI0_req->number_of_dci,
             DL_req->number_dci, HI_DCI0_req->number_of_dci,
             dl_config_pduLoop->dci_dl_pdu.dci_dl_pdu_rel8.rnti,
-            dl_config_pduLoop->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level, 
-            nCCE, 
+            dl_config_pduLoop->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level,
+            nCCE,
             nCCE_max,
             DL_req->number_pdcch_ofdm_symbols);
 
@@ -3416,7 +3412,7 @@ try_again:
         if (DL_req->number_pdcch_ofdm_symbols == max_symbol)
           return -1;
 
-        LOG_D(MAC, "Can't fit DCI allocations with %d PDCCH symbols, increasing by 1\n", 
+        LOG_D(MAC, "Can't fit DCI allocations with %d PDCCH symbols, increasing by 1\n",
               DL_req->number_pdcch_ofdm_symbols);
         DL_req->number_pdcch_ofdm_symbols++;
         nCCE_max = get_nCCE_max(cc, DL_req->number_pdcch_ofdm_symbols, subframeP);
@@ -3425,8 +3421,8 @@ try_again:
 
       // number of CCEs left can potentially hold this allocation
       fCCE = get_nCCE_offset(CCE_table,
-                             dl_config_pduLoop->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level, 
-                             nCCE_max, 
+                             dl_config_pduLoop->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level,
+                             nCCE_max,
                              0,
                              dl_config_pduLoop->dci_dl_pdu.dci_dl_pdu_rel8.rnti,
                              subframeP);
@@ -3434,7 +3430,7 @@ try_again:
       if (fCCE == -1) {
         if (DL_req->number_pdcch_ofdm_symbols == max_symbol) {
           LOG_I(MAC, "subframe %d: Dropping Allocation for RNTI %x\n",
-                subframeP, 
+                subframeP,
                 dl_config_pduLoop->dci_dl_pdu.dci_dl_pdu_rel8.rnti);
 
           for (j = 0; j <= i; j++) {
@@ -3465,13 +3461,13 @@ try_again:
 
       // the allocation is feasible, rnti rule passes
       nCCE += dl_config_pduLoop->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level;
-      LOG_D(MAC, "Allocating at nCCE %d\n", 
+      LOG_D(MAC, "Allocating at nCCE %d\n",
             fCCE);
 
       if ((test_onlyP%2) == 0) {
         dl_config_pduLoop->dci_dl_pdu.dci_dl_pdu_rel8.cce_idx = fCCE;
-        LOG_D(MAC, "Allocate CCEs subframe %d, test %d\n", 
-              subframeP, 
+        LOG_D(MAC, "Allocate CCEs subframe %d, test %d\n",
+              subframeP,
               test_onlyP);
       }
 
@@ -3499,9 +3495,9 @@ try_again:
 //------------------------------------------------------------------------------
 nfapi_ul_config_request_pdu_t *
 has_ul_grant(module_id_t module_idP,
-             int CC_idP, 
-             uint16_t absSFP, 
-             uint16_t rnti) 
+             int CC_idP,
+             uint16_t absSFP,
+             uint16_t rnti)
 //------------------------------------------------------------------------------
 {
   nfapi_ul_config_request_body_t *ul_req = &RC.mac[module_idP]->UL_req_tmp[CC_idP][absSFP % 10].ul_config_request_body;
@@ -3509,15 +3505,15 @@ has_ul_grant(module_id_t module_idP,
   uint8_t pdu_type;
 
   LOG_D(MAC, "Checking for rnti %x UL grant in subframeP %d (num pdu %d)\n",
-        rnti, 
-        absSFP % 10, 
+        rnti,
+        absSFP % 10,
         ul_req->number_of_pdus);
 
   for (int i = 0; i < ul_req->number_of_pdus; i++, ul_config_pdu++) {
     pdu_type = ul_config_pdu->pdu_type;
-    LOG_D(MAC, "PDU %d : type %d,rnti %x\n", 
+    LOG_D(MAC, "PDU %d : type %d,rnti %x\n",
           i,
-          pdu_type, 
+          pdu_type,
           rnti);
 
     if (pdu_type == NFAPI_UL_CONFIG_ULSCH_PDU_TYPE && ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.rnti == rnti)
@@ -3571,9 +3567,9 @@ boolean_t
 CCE_allocation_infeasible(int module_idP,
                           int CC_idP,
                           int format_flag,
-                          int subframe, 
-                          int aggregation, 
-                          int rnti) 
+                          int subframe,
+                          int aggregation,
+                          int rnti)
 //------------------------------------------------------------------------------
 {
   nfapi_dl_config_request_body_t *DL_req       = &RC.mac[module_idP]->DL_req[CC_idP].dl_config_request_body;
@@ -3619,10 +3615,10 @@ CCE_allocation_infeasible(int module_idP,
 }
 
 //------------------------------------------------------------------------------
-void 
-get_retransmission_timing(LTE_TDD_Config_t *tdd_Config, 
+void
+get_retransmission_timing(LTE_TDD_Config_t *tdd_Config,
                           frame_t *frameP,
-                          sub_frame_t *subframeP) 
+                          sub_frame_t *subframeP)
 //------------------------------------------------------------------------------
 {
   if (tdd_Config == NULL) {
@@ -3633,8 +3629,8 @@ get_retransmission_timing(LTE_TDD_Config_t *tdd_Config,
   } else {
     switch (tdd_Config->subframeAssignment) { //TODO fill in other TDD configs
       default:
-        printf("%s:%d: TODO\n", 
-               __FILE__, 
+        printf("%s:%d: TODO\n",
+               __FILE__,
                __LINE__);
         abort();
         break;
@@ -3649,7 +3645,7 @@ get_retransmission_timing(LTE_TDD_Config_t *tdd_Config,
           *frameP = (*frameP + (*subframeP / 10)) % 1024;
           *subframeP %= 10;
         } else {
-          AssertFatal(2 == 1, "Illegal dl subframe %d for tdd config %ld\n", 
+          AssertFatal(2 == 1, "Illegal dl subframe %d for tdd config %ld\n",
                       *subframeP,
                       tdd_Config->subframeAssignment);
         }
@@ -3662,7 +3658,7 @@ get_retransmission_timing(LTE_TDD_Config_t *tdd_Config,
 //------------------------------------------------------------------------------
 uint8_t
 get_dl_subframe_count(int tdd_config_sfa,
-                      sub_frame_t subframeP) 
+                      sub_frame_t subframeP)
 //------------------------------------------------------------------------------
 {
   uint8_t tdd1[10] = {1, -1, -1, -1, 2, 3, -1, -1, -1, 4}; // special subframes 1,6 are excluded
@@ -3679,7 +3675,7 @@ get_dl_subframe_count(int tdd_config_sfa,
 uint8_t
 frame_subframe2_dl_harq_pid(LTE_TDD_Config_t *tdd_Config,
                             int abs_frameP,
-                            sub_frame_t subframeP) 
+                            sub_frame_t subframeP)
 //------------------------------------------------------------------------------
 {
   int harq_pid;
@@ -3688,7 +3684,7 @@ frame_subframe2_dl_harq_pid(LTE_TDD_Config_t *tdd_Config,
   if (tdd_Config) {
     switch(tdd_Config->subframeAssignment) { //TODO fill in other tdd config
       case 1:
-        count = get_dl_subframe_count(tdd_Config->subframeAssignment, 
+        count = get_dl_subframe_count(tdd_Config->subframeAssignment,
                                       subframeP);
         harq_pid = (((frame_cnt * 1024 + abs_frameP) * 4) - 1 + count) % 7;//4 dl subframe in a frame
 
@@ -3713,14 +3709,14 @@ frame_subframe2_dl_harq_pid(LTE_TDD_Config_t *tdd_Config,
 }
 
 //------------------------------------------------------------------------------
-unsigned char 
+unsigned char
 ul_ACK_subframe2M(LTE_TDD_Config_t *tdd_Config,
-                  unsigned char subframe) 
+                  unsigned char subframe)
 //------------------------------------------------------------------------------
 {
   if (tdd_Config == NULL) {
     return 1;
-  } 
+  }
   switch (tdd_Config->subframeAssignment) {
     case 1:
       return 1; // don't ACK special subframe for now
@@ -3742,13 +3738,13 @@ ul_ACK_subframe2M(LTE_TDD_Config_t *tdd_Config,
     case 3:
       if (subframe == 2) {  // ACK subframes 5 and 6
         return 2; // should be 3
-      } 
+      }
       if (subframe == 3) { // ACK subframes 7 and 8
         return 2;  // To be updated
-      } 
+      }
       if (subframe == 4) { // ACK subframes 9 and 0
         return 2;
-      } 
+      }
       AssertFatal(1==0,"illegal subframe %d for tdd_config %ld\n",
                   subframe,
                   tdd_Config->subframeAssignment);
@@ -3757,10 +3753,10 @@ ul_ACK_subframe2M(LTE_TDD_Config_t *tdd_Config,
     case 4:
       if (subframe == 2) {  // ACK subframes 0,4 and 5
         return 3; // should be 4
-      } 
+      }
       if (subframe == 3) { // ACK subframes 6,7,8 and 9
         return 4;
-      } 
+      }
       AssertFatal(1==0,"illegal subframe %d for tdd_config %ld\n",
                   subframe,
                   tdd_Config->subframeAssignment);
@@ -3769,7 +3765,7 @@ ul_ACK_subframe2M(LTE_TDD_Config_t *tdd_Config,
     case 5:
       if (subframe == 2) {  // ACK subframes 0,3,4,5,6,7,8 and 9
         return 8; // should be 3
-      } 
+      }
       AssertFatal(1==0,"illegal subframe %d for tdd_config %ld\n",
                   subframe,
                   tdd_Config->subframeAssignment);
@@ -3780,15 +3776,15 @@ ul_ACK_subframe2M(LTE_TDD_Config_t *tdd_Config,
 }
 
 //------------------------------------------------------------------------------
-unsigned char 
+unsigned char
 ul_ACK_subframe2dl_subframe(LTE_TDD_Config_t *tdd_Config,
                             unsigned char subframe,
-                            unsigned char ACK_index) 
+                            unsigned char ACK_index)
 //------------------------------------------------------------------------------
 {
   if (tdd_Config == NULL) {
     return ((subframe < 4) ? subframe + 6 : subframe - 4);
-  } 
+  }
 
   switch (tdd_Config->subframeAssignment) {
     case 3:
@@ -3798,10 +3794,10 @@ ul_ACK_subframe2dl_subframe(LTE_TDD_Config_t *tdd_Config,
       }
       if (subframe == 3) { // ACK subframes 7 and 8
         return (7 + ACK_index);  // To be updated
-      } 
+      }
       if (subframe == 4) { // ACK subframes 9 and 0
         return ((9 + ACK_index) % 10);
-      } 
+      }
       AssertFatal(1==0, "illegal subframe %d for tdd_config->subframeAssignment %ld\n",
                   subframe,
                   tdd_Config->subframeAssignment);
@@ -3813,10 +3809,10 @@ ul_ACK_subframe2dl_subframe(LTE_TDD_Config_t *tdd_Config,
         //  return(1); TBC
         if (ACK_index == 2) return 0;
         return (4 + ACK_index);
-      } 
+      }
       if (subframe == 3) { // ACK subframes 6, 7 8 and 9
         return (6 + ACK_index);  // To be updated
-      } 
+      }
       AssertFatal(1 == 0, "illegal subframe %d for tdd_config %ld\n",
                   subframe,
                   tdd_Config->subframeAssignment);
@@ -3825,7 +3821,7 @@ ul_ACK_subframe2dl_subframe(LTE_TDD_Config_t *tdd_Config,
     case 1:
       if (subframe == 2) {  // ACK subframes 5 and 6
         return (5 + ACK_index);
-      } 
+      }
       if (subframe == 3) { // ACK subframe 9
         return 9;  // To be updated
       }
@@ -3834,7 +3830,7 @@ ul_ACK_subframe2dl_subframe(LTE_TDD_Config_t *tdd_Config,
       }
       if (subframe == 8) { // ACK subframe 4
         return 4;  // To be updated
-      } 
+      }
       AssertFatal(1 == 0, "illegal subframe %d for tdd_config %ld\n",
                   subframe,
                   tdd_Config->subframeAssignment);
@@ -3845,13 +3841,13 @@ ul_ACK_subframe2dl_subframe(LTE_TDD_Config_t *tdd_Config,
 
 //------------------------------------------------------------------------------
 void
-extract_harq(module_id_t mod_idP, 
-             int CC_idP, 
+extract_harq(module_id_t mod_idP,
+             int CC_idP,
              int UE_id,
-             frame_t frameP, 
+             frame_t frameP,
              sub_frame_t subframeP,
-             void *harq_indication, 
-             int format) 
+             void *harq_indication,
+             int format)
 //------------------------------------------------------------------------------
 {
   eNB_MAC_INST *eNB = RC.mac[mod_idP];
@@ -3874,17 +3870,17 @@ extract_harq(module_id_t mod_idP,
 
 #if (LTE_RRC_VERSION >= MAKE_VERSION(13, 0, 0))
   LTE_PhysicalConfigDedicated_t *physicalConfigDedicated = UE_list->UE_template[pCCid][UE_id].physicalConfigDedicated;
-  if (physicalConfigDedicated != NULL && physicalConfigDedicated->pucch_ConfigDedicated != NULL && 
-      physicalConfigDedicated->ext7 != NULL && physicalConfigDedicated->ext7->pucch_ConfigDedicated_r13 != NULL && 
+  if (physicalConfigDedicated != NULL && physicalConfigDedicated->pucch_ConfigDedicated != NULL &&
+      physicalConfigDedicated->ext7 != NULL && physicalConfigDedicated->ext7->pucch_ConfigDedicated_r13 != NULL &&
       ((physicalConfigDedicated->ext7->pucch_ConfigDedicated_r13->spatialBundlingPUCCH_r13 && format == 0) ||
        (physicalConfigDedicated->ext7->pucch_ConfigDedicated_r13->spatialBundlingPUSCH_r13 && format == 1))) {
     spatial_bundling = 1;
   }
-#endif 
-    
+#endif
+
   for (i = 0; i < numCC; i++) {
-    tmode[i] = get_tmode(mod_idP, 
-                         i, 
+    tmode[i] = get_tmode(mod_idP,
+                         i,
                          UE_id);
   }
   if (cc->tdd_Config) {
@@ -3894,7 +3890,7 @@ extract_harq(module_id_t mod_idP,
 
     switch (harq_indication_tdd->mode) {
       case 0:   // Format 1a/b bundling
-        AssertFatal(numCC == 1, "numCC %d > 1, should not be using Format1a/b\n", 
+        AssertFatal(numCC == 1, "numCC %d > 1, should not be using Format1a/b\n",
                     numCC);
         int M = ul_ACK_subframe2M(cc->tdd_Config,
                                   subframeP);
@@ -3944,10 +3940,10 @@ extract_harq(module_id_t mod_idP,
                   if (ra[ra_i].rnti == rnti && ra[ra_i].state == WAITMSG4ACK) {
                     //Msg NACK num to MAC ,remove UE
                     // add UE info to freeList
-                    LOG_I(RRC, "put UE %x into freeList\n", 
+                    LOG_I(RRC, "put UE %x into freeList\n",
                           rnti);
-                    put_UE_in_freelist(mod_idP, 
-                                      rnti, 
+                    put_UE_in_freelist(mod_idP,
+                                      rnti,
                                       1);
                   }
                 }
@@ -3965,15 +3961,15 @@ extract_harq(module_id_t mod_idP,
                     subframeP);
 
               if (num_ack_nak == 1 && harq_indication_tdd->harq_data[0].bundling.value_0 == 1) {
-                cancel_ra_proc(mod_idP, 
-                               CC_idP, 
-                               frameP, 
+                cancel_ra_proc(mod_idP,
+                               CC_idP,
+                               frameP,
                                ra[ra_i].rnti);
               } else {
                 if(sched_ctl->round[CC_idP][harq_pid] == 7) {
-                  cancel_ra_proc(mod_idP, 
-                                 CC_idP, 
-                                 frameP, 
+                  cancel_ra_proc(mod_idP,
+                                 CC_idP,
+                                 frameP,
                                  ra[ra_i].rnti);
                 }
               }
@@ -4009,7 +4005,7 @@ extract_harq(module_id_t mod_idP,
 
     switch (harq_indication_fdd->mode) {
       case 0:   // Format 1a/b (10.1.2.1)
-        AssertFatal(numCC == 1, "numCC %d > 1, should not be using Format1a/b\n", 
+        AssertFatal(numCC == 1, "numCC %d > 1, should not be using Format1a/b\n",
                     numCC);
 
         if (tmode[0] == 1 || tmode[0] == 2 || tmode[0] == 5 || tmode[0] == 6 || tmode[0] == 7) {  // NOTE: have to handle the case of TM9-10 with 1 antenna port
@@ -4023,27 +4019,27 @@ extract_harq(module_id_t mod_idP,
           // So if nfapi_mode == 2(VNF), this function don't check assertion to avoid process exit.
           if (nfapi_mode != 2) {
             AssertFatal(sched_ctl->round[CC_idP][harq_pid] < 8, "Got ACK/NAK for inactive harq_pid %d for UE %d/%x\n",
-                        harq_pid, 
-                        UE_id, 
+                        harq_pid,
+                        UE_id,
                         rnti);
           } else {
             if (sched_ctl->round[CC_idP][harq_pid] == 8) {
               LOG_E(MAC,"Got ACK/NAK for inactive harq_pid %d for UE %d/%x\n",
-                    harq_pid, 
-                    UE_id, 
+                    harq_pid,
+                    UE_id,
                     rnti);
               return;
             }
           }
 
           AssertFatal(pdu[0] == 1 || pdu[0] == 2 || pdu[0] == 4, "Received ACK/NAK %d which is not 1 or 2 for harq_pid %d from UE %d/%x\n",
-                      pdu[0], 
-                      harq_pid, 
-                      UE_id, 
+                      pdu[0],
+                      harq_pid,
+                      UE_id,
                       rnti);
 
-          LOG_D(MAC, "Received %d for harq_pid %d\n", 
-                pdu[0], 
+          LOG_D(MAC, "Received %d for harq_pid %d\n",
+                pdu[0],
                 harq_pid);
 
           RA_t *ra = &eNB->common_channels[CC_idP].ra[0];
@@ -4058,15 +4054,15 @@ extract_harq(module_id_t mod_idP,
                     subframeP);
 
               if (pdu[0] == 1) {
-                cancel_ra_proc(mod_idP, 
-                               CC_idP, 
-                               frameP, 
+                cancel_ra_proc(mod_idP,
+                               CC_idP,
+                               frameP,
                                ra[ra_i].rnti);
               } else {
                 if (sched_ctl->round[CC_idP][harq_pid] == 7) {
-                  cancel_ra_proc(mod_idP, 
-                                 CC_idP, 
-                                 frameP, 
+                  cancel_ra_proc(mod_idP,
+                                 CC_idP,
+                                 frameP,
                                  ra[ra_i].rnti);
                 }
               }
@@ -4092,10 +4088,10 @@ extract_harq(module_id_t mod_idP,
                 if((ra[ra_i].rnti == rnti) && (ra[ra_i].state == WAITMSG4ACK)) {
                   //Msg NACK num to MAC ,remove UE
                   // add UE info to freeList
-                  LOG_I(RRC, "put UE %x into freeList\n", 
+                  LOG_I(RRC, "put UE %x into freeList\n",
                         rnti);
-                  put_UE_in_freelist(mod_idP, 
-                                     rnti, 
+                  put_UE_in_freelist(mod_idP,
+                                     rnti,
                                      1);
                 }
               }
@@ -4150,11 +4146,11 @@ extract_harq(module_id_t mod_idP,
             AssertFatal(1 == 0, "Illegal ACK/NAK/round combination (%d,%d,%d,%d,%d) for harq_pid %d, UE %d/%x\n",
                         num_ack_nak,
                         sched_ctl->round[CC_idP][harq_pid],
-                        sched_ctl->round[CC_idP][harq_pid], 
+                        sched_ctl->round[CC_idP][harq_pid],
                         pdu[0],
-                        pdu[1], 
-                        harq_pid, 
-                        UE_id, 
+                        pdu[1],
+                        harq_pid,
+                        UE_id,
                         rnti);
         }
 
@@ -4204,14 +4200,14 @@ extract_harq(module_id_t mod_idP,
           AssertFatal(pdu[2] <= 3, "pdu[2] %d is not ACK/NAK/DTX\n",
                       pdu[2]);
           AssertFatal(sched_ctl->tbcnt[pCCid][harq_pid] == 2, "sched_ctl->tbcnt[%d][%d] != 2 for UE %d/%x\n",
-                      pCCid, 
-                      harq_pid, 
-                      UE_id, 
+                      pCCid,
+                      harq_pid,
+                      UE_id,
                       rnti);
           AssertFatal(sched_ctl->tbcnt[1 - pCCid][harq_pid] == 1, "sched_ctl->tbcnt[%d][%d] != 1 for UE %d/%x\n",
-                      1 - pCCid, 
-                      harq_pid, 
-                      UE_id, 
+                      1 - pCCid,
+                      harq_pid,
+                      UE_id,
                       rnti);
 
           if (pdu[0] == 1 && pdu[1] == 1) { // both ACK
@@ -4255,14 +4251,14 @@ extract_harq(module_id_t mod_idP,
           AssertFatal(pdu[2] <= 3, "pdu[2] %d is not ACK/NAK/DTX\n",
                       pdu[2]);
           AssertFatal(sched_ctl->tbcnt[1 - pCCid][harq_pid] == 2, "sched_ctl->tbcnt[%d][%d] != 2 for UE %d/%x\n",
-                      1 - pCCid, 
-                      harq_pid, 
-                      UE_id, 
+                      1 - pCCid,
+                      harq_pid,
+                      UE_id,
                       rnti);
           AssertFatal(sched_ctl->tbcnt[pCCid][harq_pid] == 1, "sched_ctl->tbcnt[%d][%d] != 1 for UE %d/%x\n",
-                      pCCid, 
-                      harq_pid, 
-                      UE_id, 
+                      pCCid,
+                      harq_pid,
+                      UE_id,
                       rnti);
 
           if (pdu[0] == 1 && pdu[1] == 1) { // both ACK
@@ -4310,12 +4306,12 @@ extract_harq(module_id_t mod_idP,
           AssertFatal(pdu[3] <= 3, "pdu[3] %d is not ACK/NAK/DTX\n",
                       pdu[3]);
           AssertFatal(sched_ctl->tbcnt[0][harq_pid] == 2, "sched_ctl->tbcnt[0][%d] != 2 for UE %d/%x\n",
-                      harq_pid, 
-                      UE_id, 
+                      harq_pid,
+                      UE_id,
                       rnti);
           AssertFatal(sched_ctl->tbcnt[1][harq_pid] == 2, "sched_ctl->tbcnt[1][%d] != 2 for UE %d/%x\n",
-                      harq_pid, 
-                      UE_id, 
+                      harq_pid,
+                      UE_id,
                       rnti);
 
           if (pdu[0] == 1 && pdu[1] == 1) { // both ACK
@@ -4381,10 +4377,10 @@ extract_harq(module_id_t mod_idP,
                 }
               } else
                 AssertFatal(1 == 0, "Illegal harq_ack value for CC %d harq_pid %d (%d) UE %d/%x\n",
-                            i, 
-                            harq_pid, 
-                            pdu[j], 
-                            UE_id, 
+                            i,
+                            harq_pid,
+                            pdu[j],
+                            UE_id,
                             rnti);
 
               j++;
@@ -4417,12 +4413,12 @@ extract_harq(module_id_t mod_idP,
                 }
               } else
                 AssertFatal(1 == 0, "Illegal combination for CC %d harq_pid %d (%d,%d,%d) UE %d/%x\n",
-                            i, 
+                            i,
                             harq_pid,
                             sched_ctl->tbcnt[i][harq_pid],
-                            pdu[j], 
-                            pdu[j + 1], 
-                            UE_id, 
+                            pdu[j],
+                            pdu[j + 1],
+                            UE_id,
                             rnti);
 
               j += 2;
@@ -4439,17 +4435,17 @@ extract_harq(module_id_t mod_idP,
                 }
               } else {
                 AssertFatal(1 == 0, "Illegal hack_nak value %d for CC %d harq_pid %d UE %d/%x\n",
-                            pdu[j], 
-                            i, 
-                            harq_pid, 
-                            UE_id, 
+                            pdu[j],
+                            i,
+                            harq_pid,
+                            UE_id,
                             rnti);
               }
               j++;
             } else {
               AssertFatal(1 == 0, "Illegal value for spatial_bundling %d\n",
                           spatial_bundling);
-            } 
+            }
           }
         }
 
@@ -4469,13 +4465,13 @@ extract_harq(module_id_t mod_idP,
 
 //------------------------------------------------------------------------------
 void
-extract_pucch_csi(module_id_t mod_idP, 
-                  int CC_idP, 
+extract_pucch_csi(module_id_t mod_idP,
+                  int CC_idP,
                   int UE_id,
-                  frame_t frameP, 
+                  frame_t frameP,
                   sub_frame_t subframeP,
-                  uint8_t *pdu, 
-                  uint8_t length) 
+                  uint8_t *pdu,
+                  uint8_t length)
 //------------------------------------------------------------------------------
 {
   UE_list_t *UE_list = &RC.mac[mod_idP]->UE_list;
@@ -4486,12 +4482,12 @@ extract_pucch_csi(module_id_t mod_idP,
   uint8_t Jtab[6] = { 0, 2, 2, 3, 4, 4 };
   int feedback_cnt;
 
-  AssertFatal(UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated != NULL, "physicalConfigDedicated is null for UE %d\n", 
+  AssertFatal(UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated != NULL, "physicalConfigDedicated is null for UE %d\n",
               UE_id);
-  AssertFatal(UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->cqi_ReportConfig != NULL, "cqi_ReportConfig is null for UE %d\n", 
+  AssertFatal(UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->cqi_ReportConfig != NULL, "cqi_ReportConfig is null for UE %d\n",
               UE_id);
-  struct LTE_CQI_ReportPeriodic *cqi_ReportPeriodic = UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->cqi_ReportConfig->cqi_ReportPeriodic;            
-  AssertFatal(cqi_ReportPeriodic != NULL, "cqi_ReportPeriodic is null for UE %d\n", 
+  struct LTE_CQI_ReportPeriodic *cqi_ReportPeriodic = UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->cqi_ReportConfig->cqi_ReportPeriodic;
+  AssertFatal(cqi_ReportPeriodic != NULL, "cqi_ReportPeriodic is null for UE %d\n",
               UE_id);
   // determine feedback mode
   AssertFatal(cqi_ReportPeriodic->present != LTE_CQI_ReportPeriodic_PR_NOTHING, "cqi_ReportPeriodic->present == LTE_CQI_ReportPeriodic_PR_NOTHING!\n");
@@ -4501,10 +4497,10 @@ extract_pucch_csi(module_id_t mod_idP,
   int H, K, bandwidth_part, L, Lmask;
   int ri = sched_ctl->periodic_ri_received[CC_idP];
 
-  get_csi_params(cc, 
-                 cqi_ReportPeriodic, 
-                 &Npd, 
-                 &N_OFFSET_CQI, 
+  get_csi_params(cc,
+                 cqi_ReportPeriodic,
+                 &Npd,
+                 &N_OFFSET_CQI,
                  &H);
   K = (H - 1) / Jtab[cc->mib->message.dl_Bandwidth];
   L = Ltab[cc->mib->message.dl_Bandwidth];
@@ -4514,8 +4510,8 @@ extract_pucch_csi(module_id_t mod_idP,
   if (feedback_cnt > 0) bandwidth_part = (feedback_cnt - 1) % K;
   else bandwidth_part = 0;
 
-  switch (get_tmode(mod_idP, 
-                    CC_idP, 
+  switch (get_tmode(mod_idP,
+                    CC_idP,
                     UE_id)) {
     case 1:
     case 2:
@@ -4536,7 +4532,7 @@ extract_pucch_csi(module_id_t mod_idP,
       break;
 }
 
-  if (cqi_ReportPeriodic->choice.setup.cqi_FormatIndicatorPeriodic.present == LTE_CQI_ReportPeriodic__setup__cqi_FormatIndicatorPeriodic_PR_widebandCQI || 
+  if (cqi_ReportPeriodic->choice.setup.cqi_FormatIndicatorPeriodic.present == LTE_CQI_ReportPeriodic__setup__cqi_FormatIndicatorPeriodic_PR_widebandCQI ||
       feedback_cnt == 0) {
     // Note: This implements only Tables: 5.3.3.1-1,5.3.3.1-1A and 5.3.3.1-2 from 36.213 (1,2,4 antenna ports Wideband CQI/PMI)
     if (no_pmi == 1) {  // get spatial_diffcqi if needed
@@ -4562,8 +4558,8 @@ extract_pucch_csi(module_id_t mod_idP,
       sched_ctl->periodic_wideband_pmi[CC_idP] = (pdu[0] >> 7) & 0xF;
     } else
       AssertFatal(1 == 0, "illegal combination p %d, ri %d, no_pmi %d\n",
-                  cc->p_eNB, 
-                  ri, 
+                  cc->p_eNB,
+                  ri,
                   no_pmi);
   } else if (cqi_ReportPeriodic->choice.setup.cqi_FormatIndicatorPeriodic.present == LTE_CQI_ReportPeriodic__setup__cqi_FormatIndicatorPeriodic_PR_subbandCQI) {
     // This is Table 5.2.3.3.2-2 for 36.213
@@ -4581,13 +4577,13 @@ extract_pucch_csi(module_id_t mod_idP,
 
 //------------------------------------------------------------------------------
 void
-extract_pusch_csi(module_id_t mod_idP, 
-                  int CC_idP, 
+extract_pusch_csi(module_id_t mod_idP,
+                  int CC_idP,
                   int UE_id,
-                  frame_t frameP, 
+                  frame_t frameP,
                   sub_frame_t subframeP,
-                  uint8_t *pdu, 
-                  uint8_t length) 
+                  uint8_t *pdu,
+                  uint8_t length)
 //------------------------------------------------------------------------------
 {
   UE_list_t *UE_list = &RC.mac[mod_idP]->UE_list;
@@ -4601,13 +4597,13 @@ extract_pusch_csi(module_id_t mod_idP,
   int i;
   uint64_t p = *(uint64_t *) pdu;
   int curbyte, curbit;
-  AssertFatal(UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated != NULL, "physicalConfigDedicated is null for UE %d\n", 
+  AssertFatal(UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated != NULL, "physicalConfigDedicated is null for UE %d\n",
               UE_id);
-  AssertFatal(UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->cqi_ReportConfig != NULL, "cqi_ReportConfig is null for UE %d\n", 
+  AssertFatal(UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->cqi_ReportConfig != NULL, "cqi_ReportConfig is null for UE %d\n",
               UE_id);
-  LTE_CQI_ReportModeAperiodic_t *cqi_ReportModeAperiodic 
+  LTE_CQI_ReportModeAperiodic_t *cqi_ReportModeAperiodic
     = UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->cqi_ReportConfig->cqi_ReportModeAperiodic;
-  AssertFatal(cqi_ReportModeAperiodic  != NULL, "cqi_ReportModeAperiodic is null for UE %d\n", 
+  AssertFatal(cqi_ReportModeAperiodic  != NULL, "cqi_ReportModeAperiodic is null for UE %d\n",
               UE_id);
   int N = Ntab[cc->mib->message.dl_Bandwidth];
   int tmode = get_tmode(mod_idP, CC_idP, UE_id);
@@ -4684,9 +4680,9 @@ extract_pusch_csi(module_id_t mod_idP,
       diffcqi0 = (uint8_t) (p & 0x03);
       p >>= 2;
       r = (uint8_t) (p & ((1 >> Ltab_uesel[bw]) - 1));
-      reverse_index(Ntab_uesel[bw], 
-                    Mtab_uesel[bw], 
-                    r, 
+      reverse_index(Ntab_uesel[bw],
+                    Mtab_uesel[bw],
+                    r,
                     v);
 
       for (m = 0; m < Mtab_uesel[bw]; m++) {
@@ -4715,9 +4711,9 @@ extract_pusch_csi(module_id_t mod_idP,
 
       r = (uint8_t) (p & ((1 >> Ltab_uesel[bw]) - 1));
       p >>= Ltab_uesel[bw];
-      reverse_index(Ntab_uesel[bw], 
-                    Mtab_uesel[bw], 
-                    r, 
+      reverse_index(Ntab_uesel[bw],
+                    Mtab_uesel[bw],
+                    r,
                     v);
 
       if (ri == 1 && cc->p_eNB == 2) {
@@ -4870,14 +4866,14 @@ extract_pusch_csi(module_id_t mod_idP,
 
 //------------------------------------------------------------------------------
 void
-cqi_indication(module_id_t mod_idP, 
-               int CC_idP, 
+cqi_indication(module_id_t mod_idP,
+               int CC_idP,
                frame_t frameP,
-               sub_frame_t subframeP, 
+               sub_frame_t subframeP,
                rnti_t rntiP,
-               nfapi_cqi_indication_rel9_t *rel9, 
+               nfapi_cqi_indication_rel9_t *rel9,
                uint8_t *pdu,
-               nfapi_ul_cqi_information_t *ul_cqi_information) 
+               nfapi_ul_cqi_information_t *ul_cqi_information)
 //------------------------------------------------------------------------------
 {
   int UE_id = find_UE_id(mod_idP, rntiP);
@@ -4891,35 +4887,35 @@ cqi_indication(module_id_t mod_idP,
   UE_sched_ctrl *sched_ctl = &UE_list->UE_sched_ctrl[UE_id];
 
   if (UE_id >= 0) {
-    LOG_D(MAC,"%s() UE_id:%d channel:%d cqi:%d\n", 
-          __FUNCTION__, 
-          UE_id, 
-          ul_cqi_information->channel, 
+    LOG_D(MAC,"%s() UE_id:%d channel:%d cqi:%d\n",
+          __FUNCTION__,
+          UE_id,
+          ul_cqi_information->channel,
           ul_cqi_information->ul_cqi);
 
     if (ul_cqi_information->channel == 0) { // PUCCH
       // extract pucch csi information before changing RI information
-      extract_pucch_csi(mod_idP, 
-                        CC_idP, 
-                        UE_id, 
-                        frameP, 
+      extract_pucch_csi(mod_idP,
+                        CC_idP,
+                        UE_id,
+                        frameP,
                         subframeP,
                         pdu, rel9->length);
       memcpy((void *) sched_ctl->periodic_ri_received,
-             (void *) rel9->ri, 
+             (void *) rel9->ri,
              rel9->number_of_cc_reported);
       // SNR for PUCCH2
       sched_ctl->pucch2_snr[CC_idP] = ul_cqi_information->ul_cqi;
     } else {    //PUSCH
       memcpy((void *) sched_ctl->aperiodic_ri_received,
-             (void *) rel9->ri, 
+             (void *) rel9->ri,
              rel9->number_of_cc_reported);
-      extract_pusch_csi(mod_idP, 
-                        CC_idP, 
-                        UE_id, 
-                        frameP, 
+      extract_pusch_csi(mod_idP,
+                        CC_idP,
+                        UE_id,
+                        frameP,
                         subframeP,
-                        pdu, 
+                        pdu,
                         rel9->length);
       LOG_D(MAC,"Frame %d Subframe %d update CQI:%d\n",
             frameP,
@@ -4938,19 +4934,19 @@ cqi_indication(module_id_t mod_idP,
 
 //------------------------------------------------------------------------------
 void
-SR_indication(module_id_t mod_idP, 
-              int cc_idP, 
+SR_indication(module_id_t mod_idP,
+              int cc_idP,
               frame_t frameP,
-              sub_frame_t subframeP, 
-              rnti_t rntiP, 
-              uint8_t ul_cqi) 
+              sub_frame_t subframeP,
+              rnti_t rntiP,
+              uint8_t ul_cqi)
 //------------------------------------------------------------------------------
 {
-  T(T_ENB_MAC_SCHEDULING_REQUEST, 
-    T_INT(mod_idP), 
+  T(T_ENB_MAC_SCHEDULING_REQUEST,
+    T_INT(mod_idP),
     T_INT(cc_idP),
-    T_INT(frameP), 
-    T_INT(subframeP), 
+    T_INT(frameP),
+    T_INT(subframeP),
     T_INT(rntiP));
   int UE_id = find_UE_id(mod_idP, rntiP);
   UE_list_t *UE_list = &RC.mac[mod_idP]->UE_list;
@@ -4958,11 +4954,11 @@ SR_indication(module_id_t mod_idP,
   if (UE_id != -1) {
     if (mac_eNB_get_rrc_status(mod_idP, UE_RNTI(mod_idP, UE_id)) <  RRC_CONNECTED) {
       LOG_D(MAC, "[eNB %d][SR %x] Frame %d subframeP %d Signaling SR for UE %d on CC_id %d\n",
-            mod_idP, 
-            rntiP, 
-            frameP, 
-            subframeP, 
-            UE_id, 
+            mod_idP,
+            rntiP,
+            frameP,
+            subframeP,
+            UE_id,
             cc_idP);
     }
     UE_list->UE_template[cc_idP][UE_id].ul_SR = 1;
@@ -4973,11 +4969,11 @@ SR_indication(module_id_t mod_idP,
     //     AssertFatal(0, "find_UE_id(%u,rnti %d) not found", enb_mod_idP, rntiP);
     //    AssertError(0, 0, "Frame %d: find_UE_id(%u,rnti %d) not found\n", frameP, enb_mod_idP, rntiP);
     LOG_D(MAC, "[eNB %d][SR %x] Frame %d subframeP %d Signaling SR for UE %d (unknown UEid) on CC_id %d\n",
-          mod_idP, 
-          rntiP, 
-          frameP, 
-          subframeP, 
-          UE_id, 
+          mod_idP,
+          rntiP,
+          frameP,
+          subframeP,
+          UE_id,
           cc_idP);
   }
   return;
@@ -4985,11 +4981,11 @@ SR_indication(module_id_t mod_idP,
 
 //------------------------------------------------------------------------------
 void
-UL_failure_indication(module_id_t mod_idP, 
-                      int cc_idP, 
+UL_failure_indication(module_id_t mod_idP,
+                      int cc_idP,
                       frame_t frameP,
-                      rnti_t rntiP, 
-                      sub_frame_t subframeP) 
+                      rnti_t rntiP,
+                      sub_frame_t subframeP)
 //------------------------------------------------------------------------------
 {
   int UE_id = find_UE_id(mod_idP, rntiP);
@@ -4997,12 +4993,12 @@ UL_failure_indication(module_id_t mod_idP,
 
   if (UE_id != -1) {
     LOG_D(MAC, "[eNB %d][UE %d/%x] Frame %d subframeP %d Signaling UL Failure for UE %d on CC_id %d (timer %d)\n",
-          mod_idP, 
-          UE_id, 
-          rntiP, 
-          frameP, 
-          subframeP, 
-          UE_id, 
+          mod_idP,
+          UE_id,
+          rntiP,
+          frameP,
+          subframeP,
+          UE_id,
           cc_idP,
           UE_list->UE_sched_ctrl[UE_id].ul_failure_timer);
 
@@ -5011,19 +5007,19 @@ UL_failure_indication(module_id_t mod_idP,
     //     AssertFatal(0, "find_UE_id(%u,rnti %d) not found", enb_mod_idP, rntiP);
     //    AssertError(0, 0, "Frame %d: find_UE_id(%u,rnti %d) not found\n", frameP, enb_mod_idP, rntiP);
     LOG_W(MAC, "[eNB %d][SR %x] Frame %d subframeP %d Signaling UL Failure for UE %d (unknown UEid) on CC_id %d\n",
-          mod_idP, 
-          rntiP, 
-          frameP, 
-          subframeP, 
-          UE_id, 
+          mod_idP,
+          rntiP,
+          frameP,
+          subframeP,
+          UE_id,
           cc_idP);
   }
 }
 
 //------------------------------------------------------------------------------
-static int 
+static int
 nack_or_dtx_reported(COMMON_channels_t *cc,
-                     nfapi_harq_indication_pdu_t *harq_pdu) 
+                     nfapi_harq_indication_pdu_t *harq_pdu)
 //------------------------------------------------------------------------------
 {
   int i;
@@ -5036,7 +5032,7 @@ nack_or_dtx_reported(COMMON_channels_t *cc,
         return 1;
     }
     return 0;
-  } 
+  }
 
   nfapi_harq_indication_fdd_rel13_t *hi = &harq_pdu->harq_indication_fdd_rel13;
   for (i = 0; i < hi->number_of_ack_nack; hi++) {
@@ -5048,11 +5044,11 @@ nack_or_dtx_reported(COMMON_channels_t *cc,
 
 //------------------------------------------------------------------------------
 void
-harq_indication(module_id_t mod_idP, 
-                int CC_idP, 
+harq_indication(module_id_t mod_idP,
+                int CC_idP,
                 frame_t frameP,
                 sub_frame_t subframeP,
-                nfapi_harq_indication_pdu_t *harq_pdu) 
+                nfapi_harq_indication_pdu_t *harq_pdu)
 //------------------------------------------------------------------------------
 {
   rnti_t rnti = harq_pdu->rx_ue_information.rnti;
@@ -5061,7 +5057,7 @@ harq_indication(module_id_t mod_idP,
   int UE_id = find_UE_id(mod_idP, rnti);
 
   if (UE_id == -1) {
-    LOG_W(MAC, "harq_indication: UE %x not found\n", 
+    LOG_W(MAC, "harq_indication: UE %x not found\n",
           rnti);
     return;
   }
@@ -5071,33 +5067,33 @@ harq_indication(module_id_t mod_idP,
   COMMON_channels_t *cc = &RC.mac[mod_idP]->common_channels[CC_idP];
   // extract HARQ Information
   LOG_D(MAC, "Frame %d, subframe %d: Received harq indication (%d) from UE %d/%x, ul_cqi %d\n",
-        frameP, 
-        subframeP, 
-        channel, 
-        UE_id, 
-        rnti, 
+        frameP,
+        subframeP,
+        channel,
+        UE_id,
+        rnti,
         ul_cqi);
 
   if (cc->tdd_Config) {
-    extract_harq(mod_idP, 
-                 CC_idP, 
-                 UE_id, 
-                 frameP, 
+    extract_harq(mod_idP,
+                 CC_idP,
+                 UE_id,
+                 frameP,
                  subframeP,
                  (void *) &harq_pdu->harq_indication_tdd_rel13,
                  channel);
   }
   else {
-    extract_harq(mod_idP, 
-                 CC_idP, 
-                 UE_id, 
-                 frameP, 
+    extract_harq(mod_idP,
+                 CC_idP,
+                 UE_id,
+                 frameP,
                  subframeP,
                  (void *) &harq_pdu->harq_indication_fdd_rel13,
                  channel);
   }
   /* don't care about cqi reporting if NACK/DTX is there */
-  if (channel == 0 && !nack_or_dtx_reported(cc, 
+  if (channel == 0 && !nack_or_dtx_reported(cc,
                                             harq_pdu)) {
     sched_ctl->pucch1_snr[CC_idP] = ul_cqi;
     sched_ctl->pucch1_cqi_update[CC_idP] = 1;
@@ -5107,26 +5103,26 @@ harq_indication(module_id_t mod_idP,
 
 // Flexran Slicing functions
 //------------------------------------------------------------------------------
-uint16_t 
-nb_rbs_allowed_slice(float rb_percentage, 
-                     int total_rbs) 
+uint16_t
+nb_rbs_allowed_slice(float rb_percentage,
+                     int total_rbs)
 //------------------------------------------------------------------------------
 {
   return (uint16_t) floor(rb_percentage * total_rbs);
 }
 
 //------------------------------------------------------------------------------
-int 
-ue_dl_slice_membership(module_id_t mod_id, 
-                       int UE_id, 
-                       int slice_idx) 
+int
+ue_dl_slice_membership(module_id_t mod_id,
+                       int UE_id,
+                       int slice_idx)
 //------------------------------------------------------------------------------
 {
   eNB_MAC_INST *eNB = RC.mac[mod_id];
 
   if (slice_idx < 0 || slice_idx >= eNB->slice_info.n_dl) {
     LOG_W(MAC, "out of range slice index %d (slice ID %d)\n",
-          slice_idx, 
+          slice_idx,
           eNB->slice_info.dl[slice_idx].id);
     return 0;
   }
@@ -5135,17 +5131,17 @@ ue_dl_slice_membership(module_id_t mod_id,
 }
 
 //------------------------------------------------------------------------------
-int 
-ue_ul_slice_membership(module_id_t mod_id, 
-                       int UE_id, 
-                       int slice_idx) 
+int
+ue_ul_slice_membership(module_id_t mod_id,
+                       int UE_id,
+                       int slice_idx)
 //------------------------------------------------------------------------------
 {
   eNB_MAC_INST *eNB = RC.mac[mod_id];
 
   if (slice_idx < 0 || slice_idx >= eNB->slice_info.n_ul) {
     LOG_W(MAC, "out of range slice index %d (slice ID %d)\n",
-          slice_idx, 
+          slice_idx,
           eNB->slice_info.dl[slice_idx].id);
     return 0;
   }
diff --git a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c
index d86622ec52c665821e9e1329cd457e1b08deb0c9..efe60be84f2997dee3b2ef958cf96484a33f419e 100644
--- a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c
+++ b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c
@@ -97,8 +97,8 @@ rx_sdu(const module_id_t enb_mod_idP,
        const rnti_t rntiP,
        uint8_t *sduP,
        const uint16_t sdu_lenP,
-       const uint16_t timing_advance, 
-       const uint8_t ul_cqi) 
+       const uint16_t timing_advance,
+       const uint8_t ul_cqi)
 //-----------------------------------------------------------------------------
 {
   int current_rnti = 0;
@@ -137,24 +137,24 @@ rx_sdu(const module_id_t enb_mod_idP,
 
   if (opt_enabled == 1) {
     trace_pdu(DIRECTION_UPLINK, sduP, sdu_lenP, 0, WS_C_RNTI, current_rnti, frameP, subframeP, 0, 0);
-    
+
     LOG_D(OPT, "[eNB %d][ULSCH] Frame %d rnti %x with size %d\n",
-      enb_mod_idP, 
-      frameP, 
-      current_rnti, 
+      enb_mod_idP,
+      frameP,
+      current_rnti,
       sdu_lenP);
   }
 
   if (UE_id != -1) {
     LOG_D(MAC, "[eNB %d][PUSCH %d] CC_id %d %d.%d Received ULSCH sdu round %d from PHY (rnti %x, UE_id %d) ul_cqi %d\n",
-          enb_mod_idP, 
-          harq_pid, 
+          enb_mod_idP,
+          harq_pid,
           CC_idP,
           frameP,
           subframeP,
           UE_list->UE_sched_ctrl[UE_id].round_UL[CC_idP][harq_pid],
-          current_rnti, 
-          UE_id, 
+          current_rnti,
+          UE_id,
           ul_cqi);
 
     AssertFatal(UE_list->UE_sched_ctrl[UE_id].round_UL[CC_idP][harq_pid] < 8, "round >= 8\n");
@@ -188,8 +188,8 @@ rx_sdu(const module_id_t enb_mod_idP,
 
     } else {  // sduP == NULL => error
       LOG_W(MAC, "[eNB %d][PUSCH %d] CC_id %d %d.%d ULSCH in error in round %d, ul_cqi %d, UE_id %d, RNTI %x\n",
-        enb_mod_idP, 
-        harq_pid, 
+        enb_mod_idP,
+        harq_pid,
         CC_idP,
         frameP,
         subframeP,
@@ -230,8 +230,8 @@ rx_sdu(const module_id_t enb_mod_idP,
 
       /* Program NACK for PHICH */
       LOG_D(MAC, "Programming PHICH NACK for rnti %x harq_pid %d (first_rb %d)\n",
-        current_rnti, 
-        harq_pid, 
+        current_rnti,
+        harq_pid,
         first_rb);
 
       nfapi_hi_dci0_request_t *hi_dci0_req = NULL;
@@ -240,9 +240,9 @@ rx_sdu(const module_id_t enb_mod_idP,
 
       nfapi_hi_dci0_request_body_t *hi_dci0_req_body = &hi_dci0_req->hi_dci0_request_body;
       nfapi_hi_dci0_request_pdu_t *hi_dci0_pdu = &hi_dci0_req_body->hi_dci0_pdu_list[hi_dci0_req_body->number_of_dci + hi_dci0_req_body->number_of_hi];
-      
+
       memset((void *) hi_dci0_pdu, 0, sizeof(nfapi_hi_dci0_request_pdu_t));
-      
+
       hi_dci0_pdu->pdu_type = NFAPI_HI_DCI0_HI_PDU_TYPE;
       hi_dci0_pdu->pdu_size = 2 + sizeof(nfapi_hi_dci0_hi_pdu);
       hi_dci0_pdu->hi_pdu.hi_pdu_rel8.tl.tag = NFAPI_HI_DCI0_REQUEST_HI_PDU_REL8_TAG;
@@ -260,7 +260,7 @@ rx_sdu(const module_id_t enb_mod_idP,
   } else if ((RA_id = find_RA_id(enb_mod_idP, CC_idP, current_rnti)) != -1) { // Check if this is an RA process for the rnti
 
     RA_t *ra = (RA_t *) &(mac->common_channels[CC_idP].ra[RA_id]);
-	  
+
 #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
     if (ra->rach_resource_type > 0) {
       harq_pid = 0;
@@ -272,20 +272,20 @@ rx_sdu(const module_id_t enb_mod_idP,
                 (int) mac->common_channels[CC_idP].radioResourceConfigCommon->rach_ConfigCommon.maxHARQ_Msg3Tx);
 
     LOG_D(MAC, "[eNB %d][PUSCH %d] CC_id %d [RAPROC Msg3] Received ULSCH sdu round %d from PHY (rnti %x, RA_id %d) ul_cqi %d\n",
-      enb_mod_idP, 
-      harq_pid, 
-      CC_idP, 
+      enb_mod_idP,
+      harq_pid,
+      CC_idP,
       ra->msg3_round,
-      current_rnti, 
-      RA_id, 
+      current_rnti,
+      RA_id,
       ul_cqi);
 
     first_rb = ra->msg3_first_rb;
 
     if (sduP == NULL) { // we've got an error on Msg3
       LOG_D(MAC, "[eNB %d] CC_id %d, RA %d ULSCH in error in round %d/%d\n",
-        enb_mod_idP, 
-        CC_idP, 
+        enb_mod_idP,
+        CC_idP,
         RA_id,
         ra->msg3_round,
         (int) mac->common_channels[CC_idP].radioResourceConfigCommon->rach_ConfigCommon.maxHARQ_Msg3Tx);
@@ -298,12 +298,12 @@ rx_sdu(const module_id_t enb_mod_idP,
 
         /* Prepare handling of retransmission */
         get_Msg3allocret(&mac->common_channels[CC_idP],
-                         ra->Msg3_subframe, 
+                         ra->Msg3_subframe,
                          ra->Msg3_frame,
-                         &ra->Msg3_frame, 
+                         &ra->Msg3_frame,
                          &ra->Msg3_subframe);
         // prepare handling of retransmission
-        
+
         add_msg3(enb_mod_idP, CC_idP, ra, frameP, subframeP);
       }
 
@@ -312,7 +312,7 @@ rx_sdu(const module_id_t enb_mod_idP,
     }
   } else {
     LOG_W(MAC, "Cannot find UE or RA corresponding to ULSCH rnti %x, dropping it\n", current_rnti);
-    
+
     return;
   }
 
@@ -320,35 +320,35 @@ rx_sdu(const module_id_t enb_mod_idP,
 
   if (payload_ptr == NULL) {
     LOG_E(MAC,"[eNB %d][PUSCH %d] CC_id %d ulsch header unknown lcid(rnti %x, UE_id %d)\n",
-      enb_mod_idP, 
-      harq_pid, 
+      enb_mod_idP,
+      harq_pid,
       CC_idP,
-      current_rnti, 
+      current_rnti,
       UE_id);
 
     return;
   }
 
-  T(T_ENB_MAC_UE_UL_PDU, 
-    T_INT(enb_mod_idP), 
+  T(T_ENB_MAC_UE_UL_PDU,
+    T_INT(enb_mod_idP),
     T_INT(CC_idP),
-    T_INT(current_rnti), 
-    T_INT(frameP), 
+    T_INT(current_rnti),
+    T_INT(frameP),
     T_INT(subframeP),
-    T_INT(harq_pid), 
-    T_INT(sdu_lenP), 
-    T_INT(num_ce), 
+    T_INT(harq_pid),
+    T_INT(sdu_lenP),
+    T_INT(num_ce),
     T_INT(num_sdu));
-  
-  T(T_ENB_MAC_UE_UL_PDU_WITH_DATA, 
-    T_INT(enb_mod_idP), 
+
+  T(T_ENB_MAC_UE_UL_PDU_WITH_DATA,
+    T_INT(enb_mod_idP),
     T_INT(CC_idP),
-    T_INT(current_rnti), 
-    T_INT(frameP), 
+    T_INT(current_rnti),
+    T_INT(frameP),
     T_INT(subframeP),
-    T_INT(harq_pid), 
-    T_INT(sdu_lenP), 
-    T_INT(num_ce), 
+    T_INT(harq_pid),
+    T_INT(sdu_lenP),
+    T_INT(num_ce),
     T_INT(num_sdu),
     T_BUFFER(sduP, sdu_lenP));
 
@@ -358,14 +358,14 @@ rx_sdu(const module_id_t enb_mod_idP,
   if (UE_id != -1) {
     UE_list->UE_sched_ctrl[UE_id].round_UL[CC_idP][harq_pid] = 0;
   }
- 
+
   /* Control element */
   for (int i = 0; i < num_ce; i++) {
-    T(T_ENB_MAC_UE_UL_CE, 
-      T_INT(enb_mod_idP), 
+    T(T_ENB_MAC_UE_UL_CE,
+      T_INT(enb_mod_idP),
       T_INT(CC_idP),
-      T_INT(current_rnti), 
-      T_INT(frameP), 
+      T_INT(current_rnti),
+      T_INT(frameP),
       T_INT(subframeP),
       T_INT(rx_ces[i]));
 
@@ -379,11 +379,11 @@ rx_sdu(const module_id_t enb_mod_idP,
           }
 
           LOG_D(MAC, "[eNB %d] CC_id %d MAC CE_LCID %d : Received PHR PH = %d (db)\n",
-            enb_mod_idP, 
-            CC_idP, 
+            enb_mod_idP,
+            CC_idP,
             rx_ces[i],
             UE_list->UE_template[CC_idP][UE_id].phr_info);
-          
+
           UE_list->UE_template[CC_idP][UE_id].phr_info_configured = 1;
           UE_list->UE_sched_ctrl[UE_id].phr_received = 1;
         }
@@ -392,19 +392,19 @@ rx_sdu(const module_id_t enb_mod_idP,
 
         break;
 
-      case CRNTI: 
+      case CRNTI:
         old_rnti = (((uint16_t) payload_ptr[0]) << 8) + payload_ptr[1];
         old_UE_id = find_UE_id(enb_mod_idP, old_rnti);
 
         LOG_D(MAC, "[eNB %d] Frame %d, Subframe %d CC_id %d MAC CE_LCID %d (ce %d/%d): CRNTI %x (UE_id %d) in Msg3\n",
-          enb_mod_idP, 
-          frameP, 
-          subframeP, 
-          CC_idP, 
-          rx_ces[i], 
+          enb_mod_idP,
+          frameP,
+          subframeP,
+          CC_idP,
+          rx_ces[i],
           i,
-          num_ce, 
-          old_rnti, 
+          num_ce,
+          old_rnti,
           old_UE_id);
 
         /* Receiving CRNTI means that the current rnti has to go away */
@@ -449,6 +449,7 @@ rx_sdu(const module_id_t enb_mod_idP,
               mac_rrc_data_ind(enb_mod_idP,
                                CC_idP,
                                frameP, subframeP,
+                               UE_id,
                                old_rnti,
                                DCCH,
                                (uint8_t *) payload_ptr,
@@ -504,15 +505,15 @@ rx_sdu(const module_id_t enb_mod_idP,
         lcgid = (payload_ptr[0] >> 6);
 
         LOG_D(MAC, "[eNB %d] CC_id %d MAC CE_LCID %d : Received short BSR LCGID = %u bsr = %d\n",
-          enb_mod_idP, 
-          CC_idP, 
-          rx_ces[i], 
+          enb_mod_idP,
+          CC_idP,
+          rx_ces[i],
           lcgid,
           payload_ptr[0] & 0x3f);
 
         if (UE_id != -1) {
           int bsr = 0;
-          
+
           bsr = payload_ptr[0] & 0x3f;
           lcgid_updated[lcgid] = 1;
 
@@ -536,8 +537,8 @@ rx_sdu(const module_id_t enb_mod_idP,
 
           if (mac_eNB_get_rrc_status(enb_mod_idP,UE_RNTI(enb_mod_idP, UE_id)) < RRC_CONNECTED) {
             LOG_D(MAC, "[eNB %d] CC_id %d MAC CE_LCID %d : estimated_ul_buffer = %d (lcg increment %d)\n",
-              enb_mod_idP, 
-              CC_idP, 
+              enb_mod_idP,
+              CC_idP,
               rx_ces[i],
               UE_list->UE_template[CC_idP][UE_id].estimated_ul_buffer,
               UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[lcgid]);
@@ -548,7 +549,7 @@ rx_sdu(const module_id_t enb_mod_idP,
         }
 
         payload_ptr += 1;  // sizeof(SHORT_BSR)
-        
+
         break;
 
       case LONG_BSR:
@@ -574,9 +575,9 @@ rx_sdu(const module_id_t enb_mod_idP,
             UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID1] +
             UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID2] +
             UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID3];
-               
-          LOG_D(MAC, "[eNB %d] CC_id %d MAC CE_LCID %d: Received long BSR. Size is LCGID0 = %u LCGID1 = %u LCGID2 = %u LCGID3 = %u\n", 
-            enb_mod_idP, 
+
+          LOG_D(MAC, "[eNB %d] CC_id %d MAC CE_LCID %d: Received long BSR. Size is LCGID0 = %u LCGID1 = %u LCGID2 = %u LCGID3 = %u\n",
+            enb_mod_idP,
             CC_idP,
             rx_ces[i],
             UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID0],
@@ -585,12 +586,12 @@ rx_sdu(const module_id_t enb_mod_idP,
             UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID3]);
 
           if (crnti_rx == 1) {
-            LOG_D(MAC, "[eNB %d] CC_id %d MAC CE_LCID %d: Received CRNTI.\n", 
+            LOG_D(MAC, "[eNB %d] CC_id %d MAC CE_LCID %d: Received CRNTI.\n",
               enb_mod_idP,
-              CC_idP, 
+              CC_idP,
               rx_ces[i]);
           }
-          
+
           for(int lcgid = 0; lcgid <= LCGID3; lcgid++) {
             if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[lcgid] == 0) {
               UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[lcgid] = 0;
@@ -605,8 +606,8 @@ rx_sdu(const module_id_t enb_mod_idP,
 
       default:
         LOG_E(MAC, "[eNB %d] CC_id %d Received unknown MAC header (0x%02x)\n",
-          enb_mod_idP, 
-          CC_idP, 
+          enb_mod_idP,
+          CC_idP,
           rx_ces[i]);
 
         break;
@@ -616,48 +617,48 @@ rx_sdu(const module_id_t enb_mod_idP,
 
   for (int i = 0; i < num_sdu; i++) {
     LOG_D(MAC, "SDU Number %d MAC Subheader SDU_LCID %d, length %d\n",
-      i, 
-      rx_lcids[i], 
+      i,
+      rx_lcids[i],
       rx_lengths[i]);
 
-    T(T_ENB_MAC_UE_UL_SDU, 
-      T_INT(enb_mod_idP), 
+    T(T_ENB_MAC_UE_UL_SDU,
+      T_INT(enb_mod_idP),
       T_INT(CC_idP),
-      T_INT(current_rnti), 
-      T_INT(frameP), 
+      T_INT(current_rnti),
+      T_INT(frameP),
       T_INT(subframeP),
       T_INT(rx_lcids[i]),
       T_INT(rx_lengths[i]));
-      
-    T(T_ENB_MAC_UE_UL_SDU_WITH_DATA, 
-      T_INT(enb_mod_idP), 
+
+    T(T_ENB_MAC_UE_UL_SDU_WITH_DATA,
+      T_INT(enb_mod_idP),
       T_INT(CC_idP),
-      T_INT(current_rnti), 
-      T_INT(frameP), 
+      T_INT(current_rnti),
+      T_INT(frameP),
       T_INT(subframeP),
-      T_INT(rx_lcids[i]), 
-      T_INT(rx_lengths[i]), 
+      T_INT(rx_lcids[i]),
+      T_INT(rx_lengths[i]),
       T_BUFFER(payload_ptr, rx_lengths[i]));
 
     switch (rx_lcids[i]) {
       case CCCH:
         if (rx_lengths[i] > CCCH_PAYLOAD_SIZE_MAX) {
           LOG_E(MAC, "[eNB %d/%d] frame %d received CCCH of size %d (too big, maximum allowed is %d, sdu_len %d), dropping packet\n",
-            enb_mod_idP, 
-            CC_idP, 
-            frameP, 
+            enb_mod_idP,
+            CC_idP,
+            frameP,
             rx_lengths[i],
-            CCCH_PAYLOAD_SIZE_MAX, 
+            CCCH_PAYLOAD_SIZE_MAX,
             sdu_lenP);
 
           break;
         }
 
         LOG_D(MAC, "[eNB %d][RAPROC] CC_id %d Frame %d, Received CCCH:  %x.%x.%x.%x.%x.%x, Terminating RA procedure for UE rnti %x\n",
-          enb_mod_idP, 
-          CC_idP, 
-          frameP, 
-          payload_ptr[0], payload_ptr[1], payload_ptr[2], payload_ptr[3], payload_ptr[4], payload_ptr[5], 
+          enb_mod_idP,
+          CC_idP,
+          frameP,
+          payload_ptr[0], payload_ptr[1], payload_ptr[2], payload_ptr[3], payload_ptr[4], payload_ptr[5],
           current_rnti);
 
         VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_TERMINATE_RA_PROC, 1);
@@ -669,20 +670,20 @@ rx_sdu(const module_id_t enb_mod_idP,
           RA_t *ra = &(mac->common_channels[CC_idP].ra[RA_id]);
 
           LOG_D(MAC, "[mac %d][RAPROC] CC_id %d Checking proc %d : rnti (%x, %x), state %d\n",
-            enb_mod_idP, 
-            CC_idP, 
-            RA_id, 
+            enb_mod_idP,
+            CC_idP,
+            RA_id,
             ra->rnti,
-            current_rnti, 
+            current_rnti,
             ra->state);
 
           if (UE_id < 0) {
             memcpy(&(ra->cont_res_id[0]), payload_ptr, 6);
 
             LOG_D(MAC, "[eNB %d][RAPROC] CC_id %d Frame %d CCCH: Received Msg3: length %d, offset %ld\n",
-              enb_mod_idP, 
-              CC_idP, 
-              frameP, 
+              enb_mod_idP,
+              CC_idP,
+              frameP,
               rx_lengths[i],
               payload_ptr - sduP);
 
@@ -692,26 +693,26 @@ rx_sdu(const module_id_t enb_mod_idP,
 #endif
                                     )) == -1) {
               LOG_E(MAC,"[MAC][eNB] Max user count reached\n");
-              
+
               cancel_ra_proc(enb_mod_idP, CC_idP, frameP, current_rnti); // send Connection Reject ???
-              
+
               break;
               // kill RA proc
             } else {
               LOG_D(MAC, "[eNB %d][RAPROC] CC_id %d Frame %d Added user with rnti %x => UE %d\n",
-                    enb_mod_idP, 
-                    CC_idP, 
-                    frameP, 
+                    enb_mod_idP,
+                    CC_idP,
+                    frameP,
                     ra->rnti,
                     UE_id);
             }
           } else {
             LOG_D(MAC, "[eNB %d][RAPROC] CC_id %d Frame %d CCCH: Received Msg3 from already registered UE %d: length %d, offset %ld\n",
-                  enb_mod_idP, 
-                  CC_idP, 
-                  frameP, 
+                  enb_mod_idP,
+                  CC_idP,
+                  frameP,
                   UE_id,
-                  rx_lengths[i], 
+                  rx_lengths[i],
                   payload_ptr - sduP);
             // kill RA proc
           }
@@ -719,6 +720,7 @@ rx_sdu(const module_id_t enb_mod_idP,
           mac_rrc_data_ind(enb_mod_idP,
                             CC_idP,
                             frameP, subframeP,
+                            UE_id,
                             current_rnti,
                             CCCH,
                             (uint8_t *) payload_ptr,
@@ -749,7 +751,7 @@ rx_sdu(const module_id_t enb_mod_idP,
                 // TODO need to be complete for other tdd configs.
             }
           } else {
-            /* Program Msg4 PDCCH+DLSCH/MPDCCH transmission 4 subframes from now, 
+            /* Program Msg4 PDCCH+DLSCH/MPDCCH transmission 4 subframes from now,
               * Check if this is ok for BL/CE, or if the rule is different
               */
             ra->Msg4_frame = frameP + ((subframeP > 5) ? 1 : 0);
@@ -762,7 +764,7 @@ rx_sdu(const module_id_t enb_mod_idP,
         break;
 
       case DCCH:
-  
+
       case DCCH1:
 
 #if defined(ENABLE_MAC_PAYLOAD_DEBUG)
@@ -855,10 +857,10 @@ rx_sdu(const module_id_t enb_mod_idP,
               mac_rlc_data_ind(enb_mod_idP, current_rnti, enb_mod_idP, frameP, ENB_FLAG_YES, MBMS_FLAG_NO, rx_lcids[i], (char *) payload_ptr, rx_lengths[i], 1, NULL);
               UE_list->eNB_UE_stats[CC_idP][UE_id].num_pdu_rx[rx_lcids[i]] += 1;
               UE_list->eNB_UE_stats[CC_idP][UE_id].num_bytes_rx[rx_lcids[i]] += rx_lengths[i];
-              
+
               /* Clear uplane_inactivity_timer */
               UE_list->UE_sched_ctrl[UE_id].uplane_inactivity_timer = 0;
-              
+
               /* Reset RRC inactivity timer after uplane activity */
               ue_contextP = rrc_eNB_get_ue_context(RC.rrc[enb_mod_idP], current_rnti);
               if (ue_contextP != NULL) {
@@ -897,17 +899,17 @@ rx_sdu(const module_id_t enb_mod_idP,
 
   /* Program ACK for PHICH */
   LOG_D(MAC, "Programming PHICH ACK for rnti %x harq_pid %d (first_rb %d)\n",
-    current_rnti, 
-    harq_pid, 
+    current_rnti,
+    harq_pid,
     first_rb);
 
   nfapi_hi_dci0_request_t *hi_dci0_req;
 
   uint8_t sf_ahead_dl = ul_subframe2_k_phich(&mac->common_channels[CC_idP], subframeP);
-  
+
   hi_dci0_req = &mac->HI_DCI0_req[CC_idP][(subframeP+sf_ahead_dl)%10];
   nfapi_hi_dci0_request_body_t *hi_dci0_req_body = &hi_dci0_req->hi_dci0_request_body;
-  nfapi_hi_dci0_request_pdu_t *hi_dci0_pdu = &hi_dci0_req_body->hi_dci0_pdu_list[hi_dci0_req_body->number_of_dci + 
+  nfapi_hi_dci0_request_pdu_t *hi_dci0_pdu = &hi_dci0_req_body->hi_dci0_pdu_list[hi_dci0_req_body->number_of_dci +
                                               hi_dci0_req_body->number_of_hi];
 
   memset((void *) hi_dci0_pdu, 0, sizeof(nfapi_hi_dci0_request_pdu_t));
@@ -945,8 +947,8 @@ rx_sdu(const module_id_t enb_mod_idP,
 /*
  * Return the BSR table index corresponding to the number of bytes in input
  */
-uint32_t 
-bytes_to_bsr_index(int32_t nbytes) 
+uint32_t
+bytes_to_bsr_index(int32_t nbytes)
 //-----------------------------------------------------------------------------
 {
   uint32_t i = 0;
@@ -967,12 +969,12 @@ bytes_to_bsr_index(int32_t nbytes)
  * Add ue info in eNB_ulsch_info[module_idP][CC_id][UE_id] struct
  */
 void
-add_ue_ulsch_info(module_id_t module_idP, 
-  int CC_id, 
+add_ue_ulsch_info(module_id_t module_idP,
+  int CC_id,
   int UE_id,
-  sub_frame_t subframeP, 
-  UE_ULSCH_STATUS status) 
-//-----------------------------------------------------------------------------  
+  sub_frame_t subframeP,
+  UE_ULSCH_STATUS status)
+//-----------------------------------------------------------------------------
 {
   eNB_ulsch_info[module_idP][CC_id][UE_id].rnti     = UE_RNTI(module_idP, UE_id);
   eNB_ulsch_info[module_idP][CC_id][UE_id].subframe = subframeP;
@@ -991,7 +993,7 @@ parse_ulsch_header(unsigned char *mac_header,
   unsigned char *rx_ces,
   unsigned char *rx_lcids,
   unsigned short *rx_lengths,
-  unsigned short tb_length) 
+  unsigned short tb_length)
 //-----------------------------------------------------------------------------
 {
   unsigned char not_done = 1;
@@ -1032,16 +1034,16 @@ parse_ulsch_header(unsigned char *mac_header,
       }
 
       LOG_D(MAC, "[eNB] sdu %d lcid %d tb_length %d length %d (offset now %ld)\n",
-        num_sdus, 
-        lcid, 
-        tb_length, 
+        num_sdus,
+        lcid,
+        tb_length,
         length,
         mac_header_ptr - mac_header);
-      
+
       rx_lcids[num_sdus] = lcid;
       rx_lengths[num_sdus] = length;
       num_sdus++;
-    
+
     } else {  // This is a control element subheader POWER_HEADROOM, BSR and CRNTI
       if (lcid == SHORT_PADDING) {
         mac_header_ptr++;
@@ -1082,16 +1084,16 @@ set_msg3_subframe(module_id_t mod_id,
   int CC_id,
   int frame, // Not used, remove?
   int subframe, // Not used, remove?
-  int rnti, 
+  int rnti,
   int Msg3_frame, // Not used, remove?
-  int Msg3_subframe) 
+  int Msg3_subframe)
 //-----------------------------------------------------------------------------
 {
   int RA_id = 0;
 
   /* Init */
   RA_id = find_RA_id(mod_id, CC_id, rnti); // state == WAITMSG3 instead of state != IDLE (?)
- 
+
   if (RA_id != -1) {
     RC.mac[mod_id]->common_channels[CC_id].ra[RA_id].Msg3_subframe = Msg3_subframe;
   } else {
@@ -1106,9 +1108,9 @@ set_msg3_subframe(module_id_t mod_id,
  * Main function called for uplink scheduling (DCI0).
  */
 void
-schedule_ulsch(module_id_t module_idP, 
+schedule_ulsch(module_id_t module_idP,
   frame_t frameP,
-  sub_frame_t subframeP) 
+  sub_frame_t subframeP)
 //-----------------------------------------------------------------------------
 {
   uint16_t first_rb[NFAPI_CC_MAX];
@@ -1216,7 +1218,7 @@ schedule_ulsch(module_id_t module_idP,
           return;
 
         break;
-      
+
       default:
         return;
     }
@@ -1247,9 +1249,9 @@ schedule_ulsch(module_id_t module_idP,
     /* From Louis-Adrien to François:
      * The comment bloc below is to configure with a command line.
      * I took it from the equivalent part in the fairRR scheduler (around line 2578 in eNB_scheduler_fairRR.c).
-     * As said in the meeting, it seems to work only for small TBS. 
+     * As said in the meeting, it seems to work only for small TBS.
      * The cause of false RA still present with this fix is to investigate.
-     * 
+     *
      * Note: in the get_prach_prb_offset() function below, the last argument is frameP in eNB_scheduler_fairRR.c
      * I think it should be sched_frame instead. This parameter has only impacts in case TDD and preamble format 4.
      * To confirm.
@@ -1258,14 +1260,14 @@ schedule_ulsch(module_id_t module_idP,
     int start_rb = 0;
     int nb_rb = 6;
     LTE_DL_FRAME_PARMS *frame_parms = &(RC.eNB[module_idP][CC_id]->frame_parms);
-    
+
     if (is_prach_subframe(frame_parms, sched_frame, sched_subframe) == 1) {
-      start_rb = get_prach_prb_offset(frame_parms, 
+      start_rb = get_prach_prb_offset(frame_parms,
                                       frame_parms->prach_config_common.prach_ConfigInfo.prach_ConfigIndex,
                                       frame_parms->prach_config_common.prach_ConfigInfo.prach_FreqOffset,
                                       0, // tdd_mapindex
                                       sched_frame); // Nf
-      
+
       first_rb[CC_id] = start_rb + nb_rb;
     }
     */
@@ -1274,14 +1276,14 @@ schedule_ulsch(module_id_t module_idP,
      * Check if RA (Msg3) is active in this subframeP, if so skip the PRB used for Msg3
      * Msg3 is using 1 PRB so we need to increase first_rb accordingly
      * Not sure about the break (can there be more than 1 active RA procedure per CC_id and per subframe?)
-     */ 
+     */
     for (int ra_index = 0; ra_index < NB_RA_PROC_MAX; ra_index++, ra_ptr++) {
       if ((ra_ptr->state == WAITMSG3) && (ra_ptr->Msg3_subframe == sched_subframe)) {
         if (first_rb[CC_id] < ra_ptr->msg3_first_rb + ra_ptr->msg3_nb_rb) {
           first_rb[CC_id] = ra_ptr->msg3_first_rb + ra_ptr->msg3_nb_rb;
         }
-        /* Louis-Adrien: I couldn't find an interdiction of multiple Msg3 scheduling 
-         * on the same time resources. Also the performance improvement of breaking is low, 
+        /* Louis-Adrien: I couldn't find an interdiction of multiple Msg3 scheduling
+         * on the same time resources. Also the performance improvement of breaking is low,
          * since we will loop until the end, most of the time.
          * I'm letting the break as a reminder, in case of misunderstanding the spec.
          */
@@ -1308,8 +1310,8 @@ schedule_ulsch_rnti(module_id_t module_idP,
   int slice_idx,
   frame_t frameP,
   sub_frame_t subframeP,
-  unsigned char sched_subframeP, 
-  uint16_t *first_rb) 
+  unsigned char sched_subframeP,
+  uint16_t *first_rb)
 //-----------------------------------------------------------------------------
 {
   rnti_t rnti = -1;
@@ -1324,7 +1326,7 @@ schedule_ulsch_rnti(module_id_t module_idP,
   uint32_t cshift = 0;
   uint32_t ndi = 0;
   uint32_t tpc = 0;
-  int32_t normalized_rx_power = 0; 
+  int32_t normalized_rx_power = 0;
   int32_t target_rx_power = 0;
   int32_t framex10psubframe = 0;
   static int32_t tpc_accumulated = 0;
@@ -1347,7 +1349,7 @@ schedule_ulsch_rnti(module_id_t module_idP,
   sli = &(mac->slice_info);
   memset(first_rb_slice, 0, NFAPI_CC_MAX * sizeof(int));
   memset(n_rb_ul_tab, 0, NFAPI_CC_MAX * sizeof(int));
-  sched_frame = frameP; 
+  sched_frame = frameP;
 
   if (sched_subframeP < subframeP) {
     sched_frame++;
@@ -1390,9 +1392,9 @@ schedule_ulsch_rnti(module_id_t module_idP,
     // don't schedule if Msg5 is not received yet
     if (UE_list->UE_template[UE_PCCID(module_idP, UE_id)][UE_id].configured == FALSE) {
       LOG_D(MAC, "[eNB %d] frame %d, subframe %d, UE %d: not configured, skipping UE scheduling \n",
-        module_idP, 
-        frameP, 
-        subframeP, 
+        module_idP,
+        frameP,
+        subframeP,
         UE_id);
 
       continue;
@@ -1402,9 +1404,9 @@ schedule_ulsch_rnti(module_id_t module_idP,
 
     if (rnti == NOT_A_RNTI) {
       LOG_W(MAC, "[eNB %d] frame %d, subframe %d, UE %d: no RNTI \n",
-        module_idP, 
-        frameP, 
-        subframeP, 
+        module_idP,
+        frameP,
+        subframeP,
         UE_id);
 
       continue;
@@ -1418,11 +1420,11 @@ schedule_ulsch_rnti(module_id_t module_idP,
       /* Be sure that there are some free RBs */
       if (first_rb_slice[CC_id] >= n_rb_ul_tab[CC_id] - 1) {
         LOG_W(MAC, "[eNB %d] frame %d, subframe %d, UE %d/%x CC %d: dropping, not enough RBs\n",
-          module_idP, 
-          frameP, 
-          subframeP, 
-          UE_id, 
-          rnti, 
+          module_idP,
+          frameP,
+          subframeP,
+          UE_id,
+          rnti,
           CC_id);
 
         continue;
@@ -1432,15 +1434,15 @@ schedule_ulsch_rnti(module_id_t module_idP,
       /* This test seems to be way too long, can we provide an optimization? */
       if (CCE_allocation_infeasible(module_idP, CC_id, 1, subframeP, aggregation, rnti)) {
         LOG_W(MAC, "[eNB %d] frame %d, subframe %d, UE %d/%x CC %d: not enough CCE\n",
-          module_idP, 
-          frameP, 
-          subframeP, 
-          UE_id, 
-          rnti, 
+          module_idP,
+          frameP,
+          subframeP,
+          UE_id,
+          rnti,
           CC_id);
 
         continue;
-      }     
+      }
 
       /* UE is active and can be scheduled, setting up struct */
       UE_template_ptr = &(UE_list->UE_template[CC_id][UE_id]);
@@ -1448,47 +1450,47 @@ schedule_ulsch_rnti(module_id_t module_idP,
       harq_pid = subframe2harqpid(&cc[CC_id], sched_frame, sched_subframeP);
       round_index = UE_sched_ctrl_ptr->round_UL[CC_id][harq_pid];
 
-      AssertFatal(round_index < 8, "round %d > 7 for UE %d/%x\n", 
+      AssertFatal(round_index < 8, "round %d > 7 for UE %d/%x\n",
         round_index,
         UE_id,
         rnti);
 
       LOG_D(MAC, "[eNB %d] frame %d subframe %d (sched_frame %d, sched_subframe %d), Checking PUSCH %d for UE %d/%x CC %d : aggregation level %d, N_RB_UL %d\n",
-        module_idP, 
-        frameP, 
-        subframeP, 
-        sched_frame, 
-        sched_subframeP, 
-        harq_pid, 
-        UE_id, 
+        module_idP,
+        frameP,
+        subframeP,
+        sched_frame,
+        sched_subframeP,
+        harq_pid,
+        UE_id,
         rnti,
-        CC_id, 
-        aggregation, 
+        CC_id,
+        aggregation,
         n_rb_ul_tab[CC_id]);
 
       /* Seems unused, only for debug */
       RC.eNB[module_idP][CC_id]->pusch_stats_BO[UE_id][(frameP * 10) + subframeP] = UE_template_ptr->estimated_ul_buffer;
       VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE0_BO, UE_template_ptr->estimated_ul_buffer);
 
-      /* 
-       * If there is information on bsr of DCCH, DTCH or if there is UL_SR, 
-       * or if there is a packet to retransmit, or we want to schedule a periodic feedback 
+      /*
+       * If there is information on bsr of DCCH, DTCH or if there is UL_SR,
+       * or if there is a packet to retransmit, or we want to schedule a periodic feedback
        */
       /* Shouldn't this test be done earlier?? */
       if (UE_is_to_be_scheduled(module_idP, CC_id, UE_id) > 0 || round_index > 0) {
         LOG_D(MAC, "[eNB %d][PUSCH %d] Frame %d subframe %d Scheduling UE %d/%x in round %d(SR %d,UL_inactivity timer %d,UL_failure timer %d,cqi_req_timer %d)\n",
-          module_idP, 
-          harq_pid, 
-          frameP, 
-          subframeP, 
-          UE_id, 
+          module_idP,
+          harq_pid,
+          frameP,
+          subframeP,
+          UE_id,
           rnti,
-          round_index, 
+          round_index,
           UE_template_ptr->ul_SR,
           UE_sched_ctrl_ptr->ul_inactivity_timer,
           UE_sched_ctrl_ptr->ul_failure_timer,
           UE_sched_ctrl_ptr->cqi_req_timer);
-          
+
         // reset the scheduling request
         UE_template_ptr->ul_SR = 0;
         status = mac_eNB_get_rrc_status(module_idP, rnti);
@@ -1526,7 +1528,7 @@ schedule_ulsch_rnti(module_id_t module_idP,
 
               if(cqi_req == 1) {
                 UE_sched_ctrl_ptr->cqi_req_flag |= 1 << sched_subframeP;
-              } 
+              }
             }
           } else {
             UE_sched_ctrl_ptr->cqi_req_flag = 0;
@@ -1548,12 +1550,12 @@ schedule_ulsch_rnti(module_id_t module_idP,
         /*
          * This assumes accumulated tpc
          * Make sure that we are only sending a tpc update once a frame, otherwise the control loop will freak out
-         */ 
+         */
         framex10psubframe = (UE_template_ptr->pusch_tpc_tx_frame * 10) + UE_template_ptr->pusch_tpc_tx_subframe;
 
         if (((framex10psubframe + 10) <= (frameP * 10 + subframeP)) || // normal case
             ((framex10psubframe > (frameP * 10 + subframeP)) && (((10240 - framex10psubframe + frameP * 10 + subframeP) >= 10)))) { //frame wrap-around
-          
+
           UE_template_ptr->pusch_tpc_tx_frame = frameP;
           UE_template_ptr->pusch_tpc_tx_subframe = subframeP;
 
@@ -1572,12 +1574,12 @@ schedule_ulsch_rnti(module_id_t module_idP,
 
         if (tpc != 1) {
           LOG_D(MAC, "[eNB %d] ULSCH scheduler: frame %d, subframe %d, harq_pid %d, tpc %d, accumulated %d, normalized/target rx power %d/%d\n",
-            module_idP, 
-            frameP, 
-            subframeP, 
-            harq_pid, 
+            module_idP,
+            frameP,
+            subframeP,
+            harq_pid,
             tpc,
-            tpc_accumulated, 
+            tpc_accumulated,
             normalized_rx_power,
             target_rx_power);
         }
@@ -1599,8 +1601,8 @@ schedule_ulsch_rnti(module_id_t module_idP,
           }
 
           UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_mcs2 = UE_template_ptr->mcs_UL[harq_pid];
-          
-          while (((rb_table[rb_table_index] > (n_rb_ul_tab[CC_id] - first_rb_slice[CC_id])) || 
+
+          while (((rb_table[rb_table_index] > (n_rb_ul_tab[CC_id] - first_rb_slice[CC_id])) ||
                   (rb_table[rb_table_index] > 45)) && (rb_table_index > 0)) {
             rb_table_index--;
           }
@@ -1609,18 +1611,18 @@ schedule_ulsch_rnti(module_id_t module_idP,
           UE_list->eNB_UE_stats[CC_id][UE_id].total_rbs_used_rx += rb_table[rb_table_index];
           UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_TBS = UE_template_ptr->TBS_UL[harq_pid];
           UE_list->eNB_UE_stats[CC_id][UE_id].total_ulsch_TBS += UE_template_ptr->TBS_UL[harq_pid];
-          
-          T(T_ENB_MAC_UE_UL_SCHEDULE, 
+
+          T(T_ENB_MAC_UE_UL_SCHEDULE,
             T_INT(module_idP),
-            T_INT(CC_id), 
-            T_INT(rnti), 
+            T_INT(CC_id),
+            T_INT(rnti),
             T_INT(frameP),
-            T_INT(subframeP), 
+            T_INT(subframeP),
             T_INT(harq_pid),
             T_INT(UE_template_ptr->mcs_UL[harq_pid]),
             T_INT(first_rb_slice[CC_id]),
             T_INT(rb_table[rb_table_index]),
-            T_INT(UE_template_ptr->TBS_UL[harq_pid]), 
+            T_INT(UE_template_ptr->TBS_UL[harq_pid]),
             T_INT(ndi));
 
           /* Store information for possible retransmission */
@@ -1634,21 +1636,21 @@ schedule_ulsch_rnti(module_id_t module_idP,
 
           /* Adjust scheduled UL bytes by TBS, wait for UL sdus to do final update */
           LOG_D(MAC, "[eNB %d] CC_id %d UE %d/%x : adjusting scheduled_ul_bytes, old %d, TBS %d\n",
-            module_idP, 
-            CC_id, 
-            UE_id, 
+            module_idP,
+            CC_id,
+            UE_id,
             rnti,
             UE_template_ptr->scheduled_ul_bytes,
             UE_template_ptr->TBS_UL[harq_pid]);
 
           UE_template_ptr->scheduled_ul_bytes += UE_template_ptr->TBS_UL[harq_pid];
 
-          LOG_D(MAC, "scheduled_ul_bytes, new %d\n", 
+          LOG_D(MAC, "scheduled_ul_bytes, new %d\n",
             UE_template_ptr->scheduled_ul_bytes);
 
           /* Cyclic shift for DM-RS */
           cshift = 0; // values from 0 to 7 can be used for mapping the cyclic shift (36.211 , Table 5.5.2.1.1-1)
-          
+
           /* Save it for a potential retransmission */
           UE_template_ptr->cshift[harq_pid] = cshift;
 
@@ -1679,44 +1681,44 @@ schedule_ulsch_rnti(module_id_t module_idP,
           hi_dci0_req->header.message_id = NFAPI_HI_DCI0_REQUEST;
 
           LOG_D(MAC, "[PUSCH %d] Frame %d, Subframe %d: Adding UL CONFIG.Request for UE %d/%x, ulsch_frame %d, ulsch_subframe %d\n",
-            harq_pid, 
-            frameP, 
-            subframeP, 
-            UE_id, 
+            harq_pid,
+            frameP,
+            subframeP,
+            UE_id,
             rnti,
-            sched_frame, 
+            sched_frame,
             sched_subframeP);
-          
+
           ul_req_index = 0;
           dlsch_flag = 0;
 
           for(ul_req_index = 0; ul_req_index < ul_req_tmp_body->number_of_pdus; ul_req_index++) {
             if(ul_req_tmp_body->ul_config_pdu_list[ul_req_index].pdu_type == NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE &&
                ul_req_tmp_body->ul_config_pdu_list[ul_req_index].uci_harq_pdu.ue_information.ue_information_rel8.rnti == rnti) {
-              
+
               dlsch_flag = 1;
-              
+
               LOG_D(MAC, "Frame %d, Subframe %d:rnti %x ul_req_index %d Switched UCI HARQ to ULSCH HARQ(first)\n",
                 frameP,
                 subframeP,
                 rnti,
                 ul_req_index);
-              
+
               break;
             }
           }
 
           /* Add UL_config PDUs */
-          fill_nfapi_ulsch_config_request_rel8(&ul_req_tmp_body->ul_config_pdu_list[ul_req_index], 
-            cqi_req, 
-            cc, 
-            UE_template_ptr->physicalConfigDedicated, 
-            get_tmode(module_idP, CC_id, UE_id), 
-            mac->ul_handle, 
+          fill_nfapi_ulsch_config_request_rel8(&ul_req_tmp_body->ul_config_pdu_list[ul_req_index],
+            cqi_req,
+            cc,
+            UE_template_ptr->physicalConfigDedicated,
+            get_tmode(module_idP, CC_id, UE_id),
+            mac->ul_handle,
             rnti,
             first_rb_slice[CC_id],     // resource_block_start
             rb_table[rb_table_index],  // number_of_resource_blocks
-            UE_template_ptr->mcs_UL[harq_pid], 
+            UE_template_ptr->mcs_UL[harq_pid],
             cshift,    // cyclic_shift_2_for_drms
             0,         // frequency_hopping_enabled_flag
             0,         // frequency_hopping_bits
@@ -1731,8 +1733,8 @@ schedule_ulsch_rnti(module_id_t module_idP,
 #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
           /* This is a BL/CE UE allocation */
           if (UE_template_ptr->rach_resource_type > 0) {
-            fill_nfapi_ulsch_config_request_emtc(&ul_req_tmp_body->ul_config_pdu_list[ul_req_index], 
-              UE_template_ptr->rach_resource_type > 2 ? 2 : 1, 
+            fill_nfapi_ulsch_config_request_emtc(&ul_req_tmp_body->ul_config_pdu_list[ul_req_index],
+              UE_template_ptr->rach_resource_type > 2 ? 2 : 1,
               1,  // total_number_of_repetitions
               1,  // repetition_number
               (frameP * 10) + subframeP);
@@ -1768,14 +1770,14 @@ schedule_ulsch_rnti(module_id_t module_idP,
 
           add_ue_ulsch_info(module_idP, CC_id, UE_id, subframeP, S_UL_SCHEDULED);
 
-          LOG_D(MAC, "[eNB %d] CC_id %d Frame %d, subframeP %d: Generated ULSCH DCI for next UE_id %d, format 0\n", 
-            module_idP, 
-            CC_id, 
-            frameP, 
-            subframeP, 
+          LOG_D(MAC, "[eNB %d] CC_id %d Frame %d, subframeP %d: Generated ULSCH DCI for next UE_id %d, format 0\n",
+            module_idP,
+            CC_id,
+            frameP,
+            subframeP,
             UE_id);
-          
-          LOG_D(MAC, "[PUSCH %d] SFN/SF:%04d%d UL_CFG:SFN/SF:%04d%d CQI:%d for UE %d/%x\n", 
+
+          LOG_D(MAC, "[PUSCH %d] SFN/SF:%04d%d UL_CFG:SFN/SF:%04d%d CQI:%d for UE %d/%x\n",
             harq_pid,
             frameP,
             subframeP,
@@ -1784,33 +1786,33 @@ schedule_ulsch_rnti(module_id_t module_idP,
             cqi_req,
             UE_id,
             rnti);
-          
+
           /* Increment first rb for next UE allocation */
           first_rb_slice[CC_id] += rb_table[rb_table_index];
 
         } else { // round_index > 0 => retransmission
           T(T_ENB_MAC_UE_UL_SCHEDULE_RETRANSMISSION,
-            T_INT(module_idP), 
-            T_INT(CC_id), 
+            T_INT(module_idP),
+            T_INT(CC_id),
             T_INT(rnti),
-            T_INT(frameP), 
-            T_INT(subframeP), 
+            T_INT(frameP),
+            T_INT(subframeP),
             T_INT(harq_pid),
             T_INT(UE_template_ptr->mcs_UL[harq_pid]),
             T_INT(first_rb_slice[CC_id]),
-            T_INT(rb_table[rb_table_index]), 
+            T_INT(rb_table[rb_table_index]),
             T_INT(round_index));
 
           /* Add UL_config PDUs */
           LOG_D(MAC, "[PUSCH %d] Frame %d, Subframe %d: Adding UL CONFIG.Request for UE %d/%x, ulsch_frame %d, ulsch_subframe %d\n",
-            harq_pid, 
+            harq_pid,
             frameP,
-            subframeP, 
-            UE_id, 
+            subframeP,
+            UE_id,
             rnti,
-            sched_frame, 
+            sched_frame,
             sched_subframeP);
-          
+
           ul_req_index = 0;
           dlsch_flag = 0;
 
@@ -1819,27 +1821,27 @@ schedule_ulsch_rnti(module_id_t module_idP,
                ul_req_tmp_body->ul_config_pdu_list[ul_req_index].uci_harq_pdu.ue_information.ue_information_rel8.rnti == rnti) {
 
               dlsch_flag = 1;
-              
+
               LOG_D(MAC, "Frame %d, Subframe %d:rnti %x ul_req_index %d Switched UCI HARQ to ULSCH HARQ(first)\n",
                 frameP,
                 subframeP,
                 rnti,
                 ul_req_index);
-              
+
               break;
             }
           }
 
-          fill_nfapi_ulsch_config_request_rel8(&ul_req_tmp_body->ul_config_pdu_list[ul_req_index], 
-            cqi_req, 
-            cc, 
-            UE_template_ptr->physicalConfigDedicated, 
-            get_tmode(module_idP, CC_id, UE_id), 
-            mac->ul_handle, 
+          fill_nfapi_ulsch_config_request_rel8(&ul_req_tmp_body->ul_config_pdu_list[ul_req_index],
+            cqi_req,
+            cc,
+            UE_template_ptr->physicalConfigDedicated,
+            get_tmode(module_idP, CC_id, UE_id),
+            mac->ul_handle,
             rnti,
             UE_template_ptr->first_rb_ul[harq_pid], // resource_block_start
             UE_template_ptr->nb_rb_ul[harq_pid],    // number_of_resource_blocks
-            UE_template_ptr->mcs_UL[harq_pid], 
+            UE_template_ptr->mcs_UL[harq_pid],
             cshift, // cyclic_shift_2_for_drms
             0,      // frequency_hopping_enabled_flag
             0,      // frequency_hopping_bits
@@ -1855,8 +1857,8 @@ schedule_ulsch_rnti(module_id_t module_idP,
 
           /* This is a BL/CE UE allocation */
           if (UE_template_ptr->rach_resource_type > 0) {
-            fill_nfapi_ulsch_config_request_emtc(&ul_req_tmp_body->ul_config_pdu_list[ul_req_index], 
-              UE_template_ptr->rach_resource_type > 2 ? 2 : 1, 
+            fill_nfapi_ulsch_config_request_emtc(&ul_req_tmp_body->ul_config_pdu_list[ul_req_index],
+              UE_template_ptr->rach_resource_type > 2 ? 2 : 1,
               1, // total_number_of_repetitions
               1, // repetition_number
               (frameP * 10) + subframeP);
@@ -1884,7 +1886,7 @@ schedule_ulsch_rnti(module_id_t module_idP,
             }
 
             fill_nfapi_ulsch_harq_information(module_idP, CC_id,rnti, ulsch_harq_information, subframeP);
-            
+
           } else {
             ul_req_tmp_body->number_of_pdus++;
           }
@@ -1903,7 +1905,7 @@ schedule_ulsch_rnti(module_id_t module_idP,
             sched_frame,
             sched_subframeP,
             cqi_req);
-        }  // end of round > 0 
+        }  // end of round > 0
       }  // UE_is_to_be_scheduled
     }  // loop over all active CC_ids
   }  // loop over UE_ids
@@ -1915,10 +1917,10 @@ schedule_ulsch_rnti(module_id_t module_idP,
  * default ULSCH scheduler for LTE-M
  */
 void schedule_ulsch_rnti_emtc(module_id_t   module_idP,
-                              frame_t       frameP,
-                              sub_frame_t   subframeP,
-                              unsigned char sched_subframeP,
-                              int          *emtc_active)
+			     frame_t       frameP,
+			     sub_frame_t   subframeP,
+			     unsigned char sched_subframeP,
+			     int          *emtc_active)
 //-----------------------------------------------------------------------------
 {
   int               UE_id          = -1;
@@ -1931,7 +1933,7 @@ void schedule_ulsch_rnti_emtc(module_id_t   module_idP,
   int32_t           normalized_rx_power = 0;
   int32_t           target_rx_power = -90;
   int               n       = 0;
-  int               CC_id   = 0;
+  int               CC_id = 0;
   int               N_RB_UL = 0;
   int               sched_frame = frameP;
   int               rvidx_tab[4] = {0,2,3,1};
@@ -1989,8 +1991,8 @@ void schedule_ulsch_rnti_emtc(module_id_t   module_idP,
     /* Loop over all active UL CC_ids for this UE */
     for (n = 0; n < UE_list->numactiveULCCs[UE_id]; n++) {
       /* This is the actual CC_id in the list */
-      CC_id   = UE_list->ordered_ULCCids[n][UE_id];
-      N_RB_UL = to_prb(cc[CC_id].ul_Bandwidth);
+      CC_id        = UE_list->ordered_ULCCids[n][UE_id];
+      N_RB_UL      = to_prb(cc[CC_id].ul_Bandwidth);
 
       UE_template   = &(UE_list->UE_template[CC_id][UE_id]);
       UE_sched_ctrl = &UE_list->UE_sched_ctrl[UE_id];
@@ -2016,7 +2018,7 @@ void schedule_ulsch_rnti_emtc(module_id_t   module_idP,
 
       RC.eNB[module_idP][CC_id]->pusch_stats_BO[UE_id][(frameP*10)+subframeP] = UE_template->estimated_ul_buffer;
       VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE0_BO, UE_template->estimated_ul_buffer);
-      
+
       //if ((UE_is_to_be_scheduled(module_idP, CC_id, UE_id) > 0) && (subframeP == 5)) {
       if ((UE_template->ul_SR > 0 || round_UL > 0 || status < RRC_CONNECTED) && (subframeP == 5)) {
         /* 
@@ -2025,7 +2027,7 @@ void schedule_ulsch_rnti_emtc(module_id_t   module_idP,
          * or if there is a packet to retransmit, 
          * or we want to schedule a periodic feedback every frame
          */
-        
+
         LOG_D(MAC,"[eNB %d][PUSCH %d] Frame %d subframe %d Scheduling UE %d/%x in round_UL %d(SR %d,UL_inactivity timer %d,UL_failure timer %d,cqi_req_timer %d)\n",
               module_idP,
               harq_pid,
@@ -2037,42 +2039,42 @@ void schedule_ulsch_rnti_emtc(module_id_t   module_idP,
               UE_template->ul_SR,
               UE_sched_ctrl->ul_inactivity_timer,
               UE_sched_ctrl->ul_failure_timer,
-              UE_sched_ctrl->cqi_req_timer);
+                UE_sched_ctrl->cqi_req_timer);
 
         /* Reset the scheduling request */
         emtc_active[CC_id] = 1;
-        UE_template->ul_SR = 0;
-        status = mac_eNB_get_rrc_status(module_idP,rnti);
-        cqi_req = 0;
+          UE_template->ul_SR = 0;
+          status = mac_eNB_get_rrc_status(module_idP,rnti);
+            cqi_req = 0;
 
         /* Power control: compute the expected ULSCH RX power (for the stats) */
         /* This is the normalized RX power and this should be constant (regardless of mcs) */
-        normalized_rx_power = UE_sched_ctrl->pusch_snr[CC_id];
-        target_rx_power = 178;
+          normalized_rx_power = UE_sched_ctrl->pusch_snr[CC_id];
+          target_rx_power = 178;
 
         /* This assumes accumulated tpc */
         /* Make sure that we are only sending a tpc update once a frame, otherwise the control loop will freak out */
         int32_t framex10psubframe = UE_template->pusch_tpc_tx_frame * 10 + UE_template->pusch_tpc_tx_subframe;
         if (((framex10psubframe + 10) <= (frameP * 10 + subframeP)) || // normal case
             ((framex10psubframe > (frameP * 10 + subframeP)) && (((10240 - framex10psubframe + frameP * 10 + subframeP) >= 10)))) // frame wrap-around
-          {
+            {
             UE_template->pusch_tpc_tx_frame = frameP;
             UE_template->pusch_tpc_tx_subframe = subframeP;
             if (normalized_rx_power > (target_rx_power + 4)) {
-              tpc = 0; //-1
-              UE_sched_ctrl->tpc_accumulated[CC_id]--;
+                tpc = 0; //-1
+                UE_sched_ctrl->tpc_accumulated[CC_id]--;
             } else if (normalized_rx_power < (target_rx_power - 4)) {
-              tpc = 2; //+1
-              UE_sched_ctrl->tpc_accumulated[CC_id]++;
+                tpc = 2; //+1
+                UE_sched_ctrl->tpc_accumulated[CC_id]++;
+              } else {
+                tpc = 1; //0
+              }
             } else {
-              tpc = 1; //0
-            }
-          } else {
             tpc = 1; //0
-        }
+          }
 
         if (tpc != 1) {
-          LOG_D(MAC,"[eNB %d] ULSCH scheduler: frame %d, subframe %d, harq_pid %d, tpc %d, accumulated %d, normalized/target rx power %d/%d\n",
+            LOG_D(MAC,"[eNB %d] ULSCH scheduler: frame %d, subframe %d, harq_pid %d, tpc %d, accumulated %d, normalized/target rx power %d/%d\n",
                 module_idP,
                 frameP,
                 subframeP,
@@ -2081,14 +2083,14 @@ void schedule_ulsch_rnti_emtc(module_id_t   module_idP,
                 UE_sched_ctrl->tpc_accumulated[CC_id],
                 normalized_rx_power,
                 target_rx_power);
-        }
+          }
 
         /* New transmission */
         if (round_UL == 0) {
           ndi = 1 - UE_template->oldNDI_UL[harq_pid];
-          
+
           UE_template->oldNDI_UL[harq_pid] = ndi;
-          UE_template->mcs_UL[harq_pid] = 4;
+            UE_template->mcs_UL[harq_pid] = 4;
           UE_template->TBS_UL[harq_pid] = get_TBS_UL(UE_template->mcs_UL[harq_pid], 6);
 
           UE_list->eNB_UE_stats[CC_id][UE_id].normalized_rx_power = normalized_rx_power;
@@ -2097,7 +2099,7 @@ void schedule_ulsch_rnti_emtc(module_id_t   module_idP,
           UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_mcs2 = UE_template->mcs_UL[harq_pid];
           UE_list->eNB_UE_stats[CC_id][UE_id].total_rbs_used_rx += 6;
           UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_TBS = UE_template->TBS_UL[harq_pid];
-          
+
           T(T_ENB_MAC_UE_UL_SCHEDULE, 
             T_INT(module_idP), 
             T_INT(CC_id), 
@@ -2112,7 +2114,7 @@ void schedule_ulsch_rnti_emtc(module_id_t   module_idP,
             T_INT(ndi));
 
           /* Store for possible retransmission */
-          UE_template->nb_rb_ul[harq_pid] = 6;
+            UE_template->nb_rb_ul[harq_pid]    = 6;
           UE_sched_ctrl->ul_scheduled |= (1 << harq_pid);
 
           if (UE_id == UE_list->head) {
@@ -2120,33 +2122,33 @@ void schedule_ulsch_rnti_emtc(module_id_t   module_idP,
           }
 
           /* Adjust total UL buffer status by TBS, wait for UL sdus to do final update */
-          UE_template->scheduled_ul_bytes += UE_template->TBS_UL[harq_pid];
+            UE_template->scheduled_ul_bytes += UE_template->TBS_UL[harq_pid];
 
-          LOG_D(MAC, "scheduled_ul_bytes, new %d\n", UE_template->scheduled_ul_bytes);
+            LOG_D(MAC, "scheduled_ul_bytes, new %d\n", UE_template->scheduled_ul_bytes);
 
           /* Cyclic shift for DMRS */
           cshift = 0; // values from 0 to 7 can be used for mapping the cyclic shift (36.211 , Table 5.5.2.1.1-1)
           /* save it for a potential retransmission */
-          UE_template->cshift[harq_pid] = cshift;
+            UE_template->cshift[harq_pid] = cshift;
 
           AssertFatal (UE_template->physicalConfigDedicated != NULL, "UE_template->physicalConfigDedicated is null\n");
           AssertFatal (UE_template->physicalConfigDedicated->ext4 != NULL, "UE_template->physicalConfigDedicated->ext4 is null\n");
           AssertFatal (UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11 != NULL, "UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11 is null\n");
-          AssertFatal (UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.present == LTE_EPDCCH_Config_r11__config_r11_PR_setup, 
-                      "UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.present != setup\n");
-          AssertFatal (UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.setConfigToAddModList_r11 != NULL,
-                      "UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.setConfigToAddModList_r11 = NULL\n");
+	    AssertFatal (UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.present == LTE_EPDCCH_Config_r11__config_r11_PR_setup,
+	      "UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.present != setup\n");
+	    AssertFatal (UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.setConfigToAddModList_r11 != NULL,
+	      "UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.setConfigToAddModList_r11 = NULL\n");
           
-          LTE_EPDCCH_SetConfig_r11_t *epdcch_setconfig_r11 = UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.setConfigToAddModList_r11->list.array[0];
+	    LTE_EPDCCH_SetConfig_r11_t *epdcch_setconfig_r11 = UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.setConfigToAddModList_r11->list.array[0];
 
-          AssertFatal(epdcch_setconfig_r11 != NULL, "epdcch_setconfig_r11 is null\n");
+	    AssertFatal(epdcch_setconfig_r11 != NULL, "epdcch_setconfig_r11 is null\n");
           AssertFatal(epdcch_setconfig_r11->ext2 != NULL, "epdcch_setconfig_r11->ext2 is null\n");
           AssertFatal(epdcch_setconfig_r11->ext2->mpdcch_config_r13 != NULL, "epdcch_setconfig_r11->ext2->mpdcch_config_r13 is null");
           AssertFatal(epdcch_setconfig_r11->ext2->mpdcch_config_r13->present == LTE_EPDCCH_SetConfig_r11__ext2__mpdcch_config_r13_PR_setup, 
-                      "epdcch_setconfig_r11->ext2->mpdcch_config_r13->present is not setup\n");
+			"epdcch_setconfig_r11->ext2->mpdcch_config_r13->present is not setup\n");
           AssertFatal(epdcch_setconfig_r11->ext2->numberPRB_Pairs_v1310 != NULL, "epdcch_setconfig_r11->ext2->numberPRB_Pairs_v1310 is null");
           AssertFatal(epdcch_setconfig_r11->ext2->numberPRB_Pairs_v1310->present == LTE_EPDCCH_SetConfig_r11__ext2__numberPRB_Pairs_v1310_PR_setup, 
-                      "epdcch_setconfig_r11->ext2->numberPRB_Pairs_v1310->present is not setup\n");
+			"epdcch_setconfig_r11->ext2->numberPRB_Pairs_v1310->present is not setup\n");
 
           LOG_D(MAC,"[PUSCH %d] Frame %d, Subframe %d: Adding UL 6-0A MPDCCH for BL/CE UE %d/%x, ulsch_frame %d, ulsch_subframe %d, UESS MPDCCH Narrowband %d\n",
                 harq_pid,
@@ -2163,51 +2165,51 @@ void schedule_ulsch_rnti_emtc(module_id_t   module_idP,
           hi_dci0_pdu = &(hi_dci0_req->hi_dci0_pdu_list[hi_dci0_req->number_of_dci + hi_dci0_req->number_of_hi]);
           memset((void*) hi_dci0_pdu, 0, sizeof(nfapi_hi_dci0_request_pdu_t));
 
-          hi_dci0_pdu->pdu_type = NFAPI_HI_DCI0_MPDCCH_DCI_PDU_TYPE;
-          hi_dci0_pdu->pdu_size = (uint8_t) (2 + sizeof (nfapi_dl_config_mpdcch_pdu));
-          hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.dci_format = (UE_template->rach_resource_type > 1) ? 5 : 4;
-          hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.ce_mode = (UE_template->rach_resource_type > 1) ? 2 : 1;
+	    hi_dci0_pdu->pdu_type = NFAPI_HI_DCI0_MPDCCH_DCI_PDU_TYPE;
+	    hi_dci0_pdu->pdu_size = (uint8_t) (2 + sizeof (nfapi_dl_config_mpdcch_pdu));
+	    hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.dci_format = (UE_template->rach_resource_type > 1) ? 5 : 4;
+	    hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.ce_mode = (UE_template->rach_resource_type > 1) ? 2 : 1;
           hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.mpdcch_narrowband = epdcch_setconfig_r11->ext2->mpdcch_config_r13->choice.setup.mpdcch_Narrowband_r13 - 1; 
-          hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.number_of_prb_pairs = 6;       // checked above that it has to be this
-          hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.resource_block_assignment = 0; // Note: this can be dynamic
-          hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.mpdcch_transmission_type = epdcch_setconfig_r11->transmissionType_r11;  // distibuted
+	    hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.number_of_prb_pairs = 6;       // checked above that it has to be this
+	    hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.resource_block_assignment = 0; // Note: this can be dynamic
+	    hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.mpdcch_transmission_type = epdcch_setconfig_r11->transmissionType_r11;  // distibuted
 
           AssertFatal(UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.startSymbol_r11 != NULL,
-                      "UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.startSymbol_r11 is null\n");
+	      "UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.startSymbol_r11 is null\n");
 
-          hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.start_symbol = *UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.startSymbol_r11;
-          hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.ecce_index = 0;          // Note: this should be dynamic
-          hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.aggreagation_level = 24; // OK for CEModeA r1-3 (9.1.5-1b) or CEModeB r1-4
-          hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.rnti_type = 4; // other
-          hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.rnti = rnti;
+	    hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.start_symbol = *UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.startSymbol_r11;
+	    hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.ecce_index = 0;        // Note: this should be dynamic
+	    hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.aggreagation_level = 24;        // OK for CEModeA r1-3 (9.1.5-1b) or CEModeB r1-4
+	    hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.rnti_type = 4; // other
+	    hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.rnti = rnti;
           hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.ce_mode = (UE_template->rach_resource_type < 3) ? 1 : 2; // already set above...
-          hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.drms_scrambling_init = epdcch_setconfig_r11->dmrs_ScramblingSequenceInt_r11;
-          hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.initial_transmission_sf_io = (frameP * 10) + subframeP;
-          hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.transmission_power = 6000;     // 0dB
-          hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.resource_block_start = UE_template->first_rb_ul[harq_pid];
-          hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.number_of_resource_blocks = 6;
+	    hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.drms_scrambling_init = epdcch_setconfig_r11->dmrs_ScramblingSequenceInt_r11;
+	    hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.initial_transmission_sf_io = (frameP * 10) + subframeP;
+	    hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.transmission_power = 6000;     // 0dB
+	    hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.resource_block_start = UE_template->first_rb_ul[harq_pid];
+	    hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.number_of_resource_blocks = 6;
           hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.mcs = 4;       // adjust according to size of RAR, 208 bits with N1A_PRB = 3
-          hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.pusch_repetition_levels = 0;
+	    hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.pusch_repetition_levels = 0;
 
           AssertFatal(epdcch_setconfig_r11->ext2->mpdcch_config_r13->choice.setup.mpdcch_pdsch_HoppingConfig_r13 == LTE_EPDCCH_SetConfig_r11__ext2__mpdcch_config_r13__setup__mpdcch_pdsch_HoppingConfig_r13_off,
-                      "epdcch_setconfig_r11->ext2->mpdcch_config_r13->mpdcch_pdsch_HoppingConfig_r13 is not off\n"); 
+			"epdcch_setconfig_r11->ext2->mpdcch_config_r13->mpdcch_pdsch_HoppingConfig_r13 is not off\n");
           
           hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.frequency_hopping_flag = 1 - epdcch_setconfig_r11->ext2->mpdcch_config_r13->choice.setup.mpdcch_pdsch_HoppingConfig_r13;
-          hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.redudency_version = 0;
-          hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.new_data_indication = UE_template->oldNDI_UL[harq_pid];
-          hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.harq_process = 0;
-          hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.tpc = tpc;       
-          hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.csi_request = cqi_req;
-          hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.ul_inex = 0;
-          hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.dai_presence_flag = 0;
-          hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.dl_assignment_index = 0;
-          hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.srs_request = 0;
-          hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.dci_subframe_repetition_number = 0;
-          hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.tcp_bitmap = 0;
-          hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.total_dci_length_include_padding = 29; // hard-coded for 10 MHz
-          hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.number_of_tx_antenna_ports = 1;
-
-          hi_dci0_req->number_of_dci++;
+	    hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.redudency_version = 0;
+	    hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.new_data_indication = UE_template->oldNDI_UL[harq_pid];
+	    hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.harq_process = 0;
+	    hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.tpc = tpc;
+	    hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.csi_request = cqi_req;
+	    hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.ul_inex = 0;
+	    hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.dai_presence_flag = 0;
+	    hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.dl_assignment_index = 0;
+	    hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.srs_request = 0;
+	    hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.dci_subframe_repetition_number = 0;
+	    hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.tcp_bitmap = 0;
+	    hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.total_dci_length_include_padding = 29; // hard-coded for 10 MHz
+	    hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.number_of_tx_antenna_ports = 1;
+
+            hi_dci0_req->number_of_dci++;
 
           LOG_D(MAC,"[PUSCH %d] Frame %d, Subframe %d: Adding UL CONFIG. Request for BL/CE UE %d/%x, ulsch_frame %d, ulsch_subframe %d, UESS mpdcch narrowband %d\n",
                 harq_pid,
@@ -2219,42 +2221,42 @@ void schedule_ulsch_rnti_emtc(module_id_t   module_idP,
                 sched_subframeP,
                 (int)epdcch_setconfig_r11->ext2->mpdcch_config_r13->choice.setup.mpdcch_Narrowband_r13 - 1);
 
-          fill_nfapi_ulsch_config_request_rel8(&ul_req_tmp->ul_config_pdu_list[ul_req_tmp->number_of_pdus],
-                                                cqi_req,
-                                                cc,
-                                                UE_template->physicalConfigDedicated,
-                                                get_tmode(module_idP,CC_id,UE_id),
-                                                eNB->ul_handle,
-                                                rnti,
-                                                UE_template->first_rb_ul[harq_pid], // resource_block_start
-                                                UE_template->nb_rb_ul[harq_pid], // number_of_resource_blocks
-                                                UE_template->mcs_UL[harq_pid],
-                                                cshift, // cyclic_shift_2_for_drms
-                                                0, // frequency_hopping_enabled_flag
-                                                0, // frequency_hopping_bits
-                                                UE_template->oldNDI_UL[harq_pid], // new_data_indication
+            fill_nfapi_ulsch_config_request_rel8(&ul_req_tmp->ul_config_pdu_list[ul_req_tmp->number_of_pdus],
+                                                 cqi_req,
+                                                 cc,
+                                                 UE_template->physicalConfigDedicated,
+                                                 get_tmode(module_idP,CC_id,UE_id),
+                                                 eNB->ul_handle,
+                                                 rnti,
+                                                 UE_template->first_rb_ul[harq_pid], // resource_block_start
+                                                 UE_template->nb_rb_ul[harq_pid], // number_of_resource_blocks
+                                                 UE_template->mcs_UL[harq_pid],
+                                                 cshift, // cyclic_shift_2_for_drms
+                                                 0, // frequency_hopping_enabled_flag
+                                                 0, // frequency_hopping_bits
+                                                 UE_template->oldNDI_UL[harq_pid], // new_data_indication
                                                 rvidx_tab[round_UL&3], // redundancy_version
-                                                harq_pid, // harq_process_number
-                                                0, // ul_tx_mode
-                                                0, // current_tx_nb
-                                                0, // n_srs
-                                                UE_template->TBS_UL[harq_pid]
-                                                );
+                                                 harq_pid, // harq_process_number
+                                                 0, // ul_tx_mode
+                                                 0, // current_tx_nb
+                                                 0, // n_srs
+                                                 UE_template->TBS_UL[harq_pid]
+                                                 );
 
           fill_nfapi_ulsch_config_request_emtc(&ul_req_tmp->ul_config_pdu_list[ul_req_tmp->number_of_pdus],
                                               UE_template->rach_resource_type > 2 ? 2 : 1,
                                               1, // total_number_of_repetitions
                                               1, // repetition_number
                                               (frameP * 10) + subframeP);
-  
-          ul_req_tmp->number_of_pdus++;
-          eNB->ul_handle++;
 
-          add_ue_ulsch_info(module_idP,
-                            CC_id,
-                            UE_id,
-                            subframeP,
-                            S_UL_SCHEDULED);
+            ul_req_tmp->number_of_pdus++;
+            eNB->ul_handle++;
+
+            add_ue_ulsch_info(module_idP,
+                              CC_id,
+                              UE_id,
+                              subframeP,
+                              S_UL_SCHEDULED);
 
           LOG_D(MAC,"[eNB %d] CC_id %d Frame %d, subframeP %d: Generated ULSCH DCI for next UE_id %d, format 0\n", 
                 module_idP,
@@ -2280,22 +2282,22 @@ void schedule_ulsch_rnti_emtc(module_id_t   module_idP,
           AssertFatal (UE_template->physicalConfigDedicated != NULL, "UE_template->physicalConfigDedicated is null\n");
           AssertFatal (UE_template->physicalConfigDedicated->ext4 != NULL, "UE_template->physicalConfigDedicated->ext4 is null\n");
           AssertFatal (UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11 != NULL, "UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11 is null\n");
-          AssertFatal (UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.present == LTE_EPDCCH_Config_r11__config_r11_PR_setup, 
-                      "UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.present != setup\n");
-          AssertFatal (UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.setConfigToAddModList_r11 != NULL,
-                      "UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.setConfigToAddModList_r11 = NULL\n");
+	    AssertFatal (UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.present == LTE_EPDCCH_Config_r11__config_r11_PR_setup,
+	      "UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.present != setup\n");
+	    AssertFatal (UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.setConfigToAddModList_r11 != NULL,
+	      "UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.setConfigToAddModList_r11 = NULL\n");
           
-          LTE_EPDCCH_SetConfig_r11_t *epdcch_setconfig_r11 = UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.setConfigToAddModList_r11->list.array[0];
+	    LTE_EPDCCH_SetConfig_r11_t *epdcch_setconfig_r11 = UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.setConfigToAddModList_r11->list.array[0];
           
-          AssertFatal(epdcch_setconfig_r11 != NULL, "epdcch_setconfig_r11 is null\n");
+	    AssertFatal(epdcch_setconfig_r11 != NULL, "epdcch_setconfig_r11 is null\n");
           AssertFatal(epdcch_setconfig_r11->ext2 != NULL, "epdcch_setconfig_r11->ext2 is null\n");
           AssertFatal(epdcch_setconfig_r11->ext2->mpdcch_config_r13 != NULL, "epdcch_setconfig_r11->ext2->mpdcch_config_r13 is null");
           AssertFatal(epdcch_setconfig_r11->ext2->mpdcch_config_r13 != NULL, "epdcch_setconfig_r11->ext2->mpdcch_config_r13 is null");
           AssertFatal(epdcch_setconfig_r11->ext2->mpdcch_config_r13->present == LTE_EPDCCH_SetConfig_r11__ext2__mpdcch_config_r13_PR_setup, 
-                      "epdcch_setconfig_r11->ext2->mpdcch_config_r13->present is not setup\n");
+			"epdcch_setconfig_r11->ext2->mpdcch_config_r13->present is not setup\n");
           AssertFatal(epdcch_setconfig_r11->ext2->numberPRB_Pairs_v1310 != NULL, "epdcch_setconfig_r11->ext2->numberPRB_Pairs_v1310 is null");
           AssertFatal(epdcch_setconfig_r11->ext2->numberPRB_Pairs_v1310->present == LTE_EPDCCH_SetConfig_r11__ext2__numberPRB_Pairs_v1310_PR_setup, 
-                      "epdcch_setconfig_r11->ext2->numberPRB_Pairs_v1310->present is not setup\n");
+			"epdcch_setconfig_r11->ext2->numberPRB_Pairs_v1310->present is not setup\n");
 
           LOG_D(MAC,"[PUSCH %d] Frame %d, Subframe %d: Adding UL 6-0A MPDCCH for BL/CE UE %d/%x, ulsch_frame %d, ulsch_subframe %d,UESS MPDCCH Narrowband %d\n",
                       harq_pid,
@@ -2310,87 +2312,87 @@ void schedule_ulsch_rnti_emtc(module_id_t   module_idP,
           UE_template->first_rb_ul[harq_pid] = narrowband_to_first_rb(cc, epdcch_setconfig_r11->ext2->mpdcch_config_r13->choice.setup.mpdcch_Narrowband_r13-1);	     
           
           hi_dci0_pdu = &(hi_dci0_req->hi_dci0_pdu_list[hi_dci0_req->number_of_dci+hi_dci0_req->number_of_hi]);
-          
+
           memset((void*) hi_dci0_pdu, 0, sizeof(nfapi_hi_dci0_request_pdu_t));
 
-          hi_dci0_pdu->pdu_type = NFAPI_HI_DCI0_MPDCCH_DCI_PDU_TYPE;
-          hi_dci0_pdu->pdu_size = (uint8_t) (2 + sizeof (nfapi_dl_config_mpdcch_pdu));
-          hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.dci_format = (UE_template->rach_resource_type > 1) ? 5 : 4;
-          hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.ce_mode = (UE_template->rach_resource_type > 1) ? 2 : 1;
+	    hi_dci0_pdu->pdu_type = NFAPI_HI_DCI0_MPDCCH_DCI_PDU_TYPE;
+	    hi_dci0_pdu->pdu_size = (uint8_t) (2 + sizeof (nfapi_dl_config_mpdcch_pdu));
+	    hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.dci_format = (UE_template->rach_resource_type > 1) ? 5 : 4;
+	    hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.ce_mode = (UE_template->rach_resource_type > 1) ? 2 : 1;
           hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.mpdcch_narrowband = epdcch_setconfig_r11->ext2->mpdcch_config_r13->choice.setup.mpdcch_Narrowband_r13 - 1;
-          hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.number_of_prb_pairs = 6;       // checked above that it has to be this
-          hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.resource_block_assignment = 0; // Note: this can be dynamic
-          hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.mpdcch_transmission_type = epdcch_setconfig_r11->transmissionType_r11;  // distibuted
+	    hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.number_of_prb_pairs = 6;       // checked above that it has to be this
+	    hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.resource_block_assignment = 0; // Note: this can be dynamic
+	    hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.mpdcch_transmission_type = epdcch_setconfig_r11->transmissionType_r11;  // distibuted
 
           AssertFatal(UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.startSymbol_r11 != NULL,
-                      "UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.startSymbol_r11 is null\n");
-
-          hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.start_symbol = *UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.startSymbol_r11;
-          hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.ecce_index = 0;          // Note: this should be dynamic
-          hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.aggreagation_level = 24; // OK for CEModeA r1-3 (9.1.5-1b) or CEModeB r1-4
-          hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.rnti_type = 4; // other
-          hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.rnti = rnti;
-          hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.ce_mode = (UE_template->rach_resource_type < 3) ? 1 : 2;
-          hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.drms_scrambling_init = epdcch_setconfig_r11->dmrs_ScramblingSequenceInt_r11;
-          hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.initial_transmission_sf_io = (frameP * 10) + subframeP;
-          hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.transmission_power = 6000;     // 0dB
-          hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.resource_block_start = UE_template->first_rb_ul[harq_pid];
-          hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.number_of_resource_blocks = 6;
-          hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.mcs = 4;       // adjust according to size of RAR, 208 bits with N1A_PRB=3
-          hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.pusch_repetition_levels = 0;
+	      "UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.startSymbol_r11 is null\n");
+
+	    hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.start_symbol = *UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.startSymbol_r11;
+	    hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.ecce_index = 0;        // Note: this should be dynamic
+	    hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.aggreagation_level = 24;        // OK for CEModeA r1-3 (9.1.5-1b) or CEModeB r1-4
+	    hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.rnti_type = 4; // other
+	    hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.rnti = rnti;
+	    hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.ce_mode = (UE_template->rach_resource_type < 3) ? 1 : 2;
+	    hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.drms_scrambling_init = epdcch_setconfig_r11->dmrs_ScramblingSequenceInt_r11;
+	    hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.initial_transmission_sf_io = (frameP * 10) + subframeP;
+	    hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.transmission_power = 6000;     // 0dB
+	    hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.resource_block_start = UE_template->first_rb_ul[harq_pid];
+	    hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.number_of_resource_blocks = 6;
+	    hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.mcs = 4;       // adjust according to size of RAR, 208 bits with N1A_PRB=3
+	    hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.pusch_repetition_levels = 0;
 
           AssertFatal(epdcch_setconfig_r11->ext2->mpdcch_config_r13->choice.setup.mpdcch_pdsch_HoppingConfig_r13 == LTE_EPDCCH_SetConfig_r11__ext2__mpdcch_config_r13__setup__mpdcch_pdsch_HoppingConfig_r13_off,
-                      "epdcch_setconfig_r11->ext2->mpdcch_config_r13->mpdcch_pdsch_HoppingConfig_r13 is not off\n"); 
+			"epdcch_setconfig_r11->ext2->mpdcch_config_r13->mpdcch_pdsch_HoppingConfig_r13 is not off\n");
           
           hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.frequency_hopping_flag  = 1 - epdcch_setconfig_r11->ext2->mpdcch_config_r13->choice.setup.mpdcch_pdsch_HoppingConfig_r13;
           hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.redudency_version = rvidx_tab[round_UL&3];
-          hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.new_data_indication = UE_template->oldNDI_UL[harq_pid];
-          hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.harq_process = harq_pid;
-          hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.tpc = tpc;
-          hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.csi_request = cqi_req;
-          hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.ul_inex = 0;
-          hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.dai_presence_flag = 0;
-          hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.dl_assignment_index = 0;
-          hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.srs_request = 0;
-          hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.dci_subframe_repetition_number = 0;
-          hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.tcp_bitmap = 0;
-          hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.total_dci_length_include_padding = 29; // hard-coded for 10 MHz
-          hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.number_of_tx_antenna_ports = 1;
-
-          hi_dci0_req->number_of_dci++;
-
-          fill_nfapi_ulsch_config_request_rel8(&ul_req_tmp->ul_config_pdu_list[ul_req_tmp->number_of_pdus],
-                                                cqi_req,
-                                                cc,
-                                                UE_template->physicalConfigDedicated,
-                                                get_tmode(module_idP,CC_id,UE_id),
-                                                eNB->ul_handle,
-                                                rnti,
-                                                UE_template->first_rb_ul[harq_pid], // resource_block_start
-                                                UE_template->nb_rb_ul[harq_pid], // number_of_resource_blocks
-                                                UE_template->mcs_UL[harq_pid],
-                                                cshift, // cyclic_shift_2_for_drms
-                                                0, // frequency_hopping_enabled_flag
-                                                0, // frequency_hopping_bits
-                                                UE_template->oldNDI_UL[harq_pid], // new_data_indication
+	    hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.new_data_indication = UE_template->oldNDI_UL[harq_pid];
+	    hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.harq_process = harq_pid;
+	    hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.tpc = tpc;
+	    hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.csi_request = cqi_req;
+	    hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.ul_inex = 0;
+	    hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.dai_presence_flag = 0;
+	    hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.dl_assignment_index = 0;
+	    hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.srs_request = 0;
+	    hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.dci_subframe_repetition_number = 0;
+	    hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.tcp_bitmap = 0;
+	    hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.total_dci_length_include_padding = 29; // hard-coded for 10 MHz
+	    hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.number_of_tx_antenna_ports = 1;
+
+	    hi_dci0_req->number_of_dci++;
+
+            fill_nfapi_ulsch_config_request_rel8(&ul_req_tmp->ul_config_pdu_list[ul_req_tmp->number_of_pdus],
+                                                 cqi_req,
+                                                 cc,
+                                                 UE_template->physicalConfigDedicated,
+                                                 get_tmode(module_idP,CC_id,UE_id),
+                                                 eNB->ul_handle,
+                                                 rnti,
+                                                 UE_template->first_rb_ul[harq_pid], // resource_block_start
+                                                 UE_template->nb_rb_ul[harq_pid], // number_of_resource_blocks
+                                                 UE_template->mcs_UL[harq_pid],
+                                                 cshift, // cyclic_shift_2_for_drms
+                                                 0, // frequency_hopping_enabled_flag
+                                                 0, // frequency_hopping_bits
+                                                 UE_template->oldNDI_UL[harq_pid], // new_data_indication
                                                 rvidx_tab[round_UL&3], // redundancy_version
-                                                harq_pid, // harq_process_number
-                                                0, // ul_tx_mode
-                                                0, // current_tx_nb
-                                                0, // n_srs
-                                                UE_template->TBS_UL[harq_pid]
-                                                );
-
-          fill_nfapi_ulsch_config_request_emtc(&ul_req_tmp->ul_config_pdu_list[ul_req_tmp->number_of_pdus],
-                                              UE_template->rach_resource_type>2 ? 2 : 1,
-                                              1, //total_number_of_repetitions
-                                              1, //repetition_number
+                                                 harq_pid, // harq_process_number
+                                                 0, // ul_tx_mode
+                                                 0, // current_tx_nb
+                                                 0, // n_srs
+                                                 UE_template->TBS_UL[harq_pid]
+                                                 );
+
+	    fill_nfapi_ulsch_config_request_emtc(&ul_req_tmp->ul_config_pdu_list[ul_req_tmp->number_of_pdus],
+						 UE_template->rach_resource_type>2 ? 2 : 1,
+						 1, //total_number_of_repetitions
+						 1, //repetition_number
                                               (frameP * 10) + subframeP);
-                
-          ul_req_tmp->number_of_pdus++;
-          eNB->ul_handle++;
-        }
-      } // UE_is_to_be_scheduled
+
+	    ul_req_tmp->number_of_pdus++;
+	    eNB->ul_handle++;
+          }
+        } // UE_is_to_be_scheduled
     } // ULCCs
   } // loop over UE_id
 }
diff --git a/openair2/LAYER2/MAC/mac.h b/openair2/LAYER2/MAC/mac.h
index 5aefdf14e73983ea0b17d253697c1aa2fa548b06..fc457c2ee75ca8378e86ee9d995ca69197871401 100644
--- a/openair2/LAYER2/MAC/mac.h
+++ b/openair2/LAYER2/MAC/mac.h
@@ -82,6 +82,7 @@
  * @{
  */
 
+#define MAX_MAC_INST 16
 #define BCCH_PAYLOAD_SIZE_MAX 128
 #define CCCH_PAYLOAD_SIZE_MAX 128
 #define PCCH_PAYLOAD_SIZE_MAX 128
@@ -1010,6 +1011,8 @@ typedef struct {
   sub_frame_t Msg3_subframe;
   /// Frame where Msg3 is to be sent
   frame_t Msg3_frame;
+  /// Delay cnt for Msg4 transmission (waiting for RRC message piggyback)
+  int Msg4_delay_cnt;
   /// Subframe where Msg4 is to be sent
   sub_frame_t Msg4_subframe;
   /// Frame where Msg4 is to be sent
@@ -1098,13 +1101,13 @@ typedef struct {
   int avail;
   int num_UEs;
   boolean_t active[MAX_MOBILES_PER_ENB];
-  
+
   /// Sorting criteria for the UE list in the MAC preprocessor
   uint16_t sorting_criteria[MAX_NUM_SLICES][CR_NUM];
   uint16_t first_rb_offset[NFAPI_CC_MAX][MAX_NUM_SLICES];
-  
+
   int assoc_dl_slice_idx[MAX_MOBILES_PER_ENB];
-  int assoc_ul_slice_idx[MAX_MOBILES_PER_ENB];  
+  int assoc_ul_slice_idx[MAX_MOBILES_PER_ENB];
 } UE_list_t;
 
 /*! \brief deleting control information*/
diff --git a/openair2/LAYER2/MAC/mac_proto.h b/openair2/LAYER2/MAC/mac_proto.h
index d29debb2a30d3a4f5766e9176c6517314fac0bfd..8943a21d60ae6d349610c63fab4991a76db11945 100644
--- a/openair2/LAYER2/MAC/mac_proto.h
+++ b/openair2/LAYER2/MAC/mac_proto.h
@@ -1222,7 +1222,7 @@ void fill_nfapi_ulsch_harq_information(module_id_t module_idP,
 uint16_t fill_nfapi_uci_acknak(module_id_t module_idP,
 							int CC_idP,
 							uint16_t rntiP,
-							uint16_t absSFP, 
+							uint16_t absSFP,
 							uint8_t cce_idxP);
 
 void fill_nfapi_dl_dci_1A(nfapi_dl_config_request_pdu_t * dl_config_pdu,
diff --git a/openair2/LAYER2/MAC/pre_processor.c b/openair2/LAYER2/MAC/pre_processor.c
index 88c7db83c02be05b4c374e9959d5a7a47bf2386b..89756e7baa5058c12bf4f7f30340de5c6614fd4c 100644
--- a/openair2/LAYER2/MAC/pre_processor.c
+++ b/openair2/LAYER2/MAC/pre_processor.c
@@ -460,10 +460,10 @@ void decode_slice_positioning(module_id_t Mod_idP,
 
 
 // This fuction sorts the UE in order their dlsch buffer and CQI
-void 
-sort_UEs(module_id_t Mod_idP, 
-         int slice_idx, 
-         int frameP, 
+void
+sort_UEs(module_id_t Mod_idP,
+         int slice_idx,
+         int frameP,
          sub_frame_t subframeP)
 {
   int i;
@@ -1196,9 +1196,9 @@ dlsch_scheduler_pre_processor(module_id_t Mod_id,
   // Initialize scheduling information for all active UEs
   memset(&sli->pre_processor_results[slice_idx], 0, sizeof(sli->pre_processor_results[slice_idx]));
   // FIXME: After the memset above, some of the resets in reset() are redundant
-  dlsch_scheduler_pre_processor_reset(Mod_id, 
-                                      slice_idx, 
-                                      frameP, 
+  dlsch_scheduler_pre_processor_reset(Mod_id,
+                                      slice_idx,
+                                      frameP,
                                       subframeP,
                                       min_rb_unit,
                                       nb_rbs_required,
@@ -1207,37 +1207,37 @@ dlsch_scheduler_pre_processor(module_id_t Mod_id,
                                       mbsfn_flag); // FIXME: Not sure if useful
   // STATUS
   // Store the DLSCH buffer for each logical channel
-  store_dlsch_buffer(Mod_id, 
-                     slice_idx, 
-                     frameP, 
+  store_dlsch_buffer(Mod_id,
+                     slice_idx,
+                     frameP,
                      subframeP);
 
   // Calculate the number of RBs required by each UE on the basis of logical channel's buffer
-  assign_rbs_required(Mod_id, 
-                      slice_idx, 
-                      frameP, 
-                      subframeP, 
-                      nb_rbs_required, 
+  assign_rbs_required(Mod_id,
+                      slice_idx,
+                      frameP,
+                      subframeP,
+                      nb_rbs_required,
                       min_rb_unit);
 
   // Sorts the user on the basis of dlsch logical channel buffer and CQI
-  sort_UEs(Mod_id, 
-           slice_idx, 
-           frameP, 
+  sort_UEs(Mod_id,
+           slice_idx,
+           frameP,
            subframeP);
 
   // ACCOUNTING
   // This procedure decides the number of RBs to allocate
-  dlsch_scheduler_pre_processor_accounting(Mod_id, 
-                                           slice_idx, 
-                                           frameP, 
+  dlsch_scheduler_pre_processor_accounting(Mod_id,
+                                           slice_idx,
+                                           frameP,
                                            subframeP,
                                            min_rb_unit,
                                            nb_rbs_required,
                                            nb_rbs_accounted);
   // POSITIONING
   // This procedure does the main allocation of the RBs
-  dlsch_scheduler_pre_processor_positioning(Mod_id, 
+  dlsch_scheduler_pre_processor_positioning(Mod_id,
                                             slice_idx,
                                             min_rb_unit,
                                             nb_rbs_required,
@@ -1249,7 +1249,7 @@ dlsch_scheduler_pre_processor(module_id_t Mod_id,
   // SHARING
   // If there are available RBs left in the slice, allocate them to the highest priority UEs
   if (eNB->slice_info.intraslice_share_active) {
-    dlsch_scheduler_pre_processor_intraslice_sharing(Mod_id, 
+    dlsch_scheduler_pre_processor_intraslice_sharing(Mod_id,
                                                      slice_idx,
                                                      min_rb_unit,
                                                      nb_rbs_required,
@@ -1304,25 +1304,25 @@ dlsch_scheduler_pre_processor(module_id_t Mod_id,
       int N_RBG = to_rbg(cc->mib->message.dl_Bandwidth);
 
       if (ue_sched_ctl->pre_nb_available_rbs[CC_id] > 0) {
-        LOG_D(MAC, "******************DL Scheduling Information for UE%d ************************\n", 
+        LOG_D(MAC, "******************DL Scheduling Information for UE%d ************************\n",
               UE_id);
-        LOG_D(MAC, "dl power offset UE%d = %d \n", 
-              UE_id, 
+        LOG_D(MAC, "dl power offset UE%d = %d \n",
+              UE_id,
               ue_sched_ctl->dl_pow_off[CC_id]);
-        LOG_D(MAC, "***********RB Alloc for every subband for UE%d ***********\n", 
+        LOG_D(MAC, "***********RB Alloc for every subband for UE%d ***********\n",
               UE_id);
 
         for (j = 0; j < N_RBG; j++) {
           //PHY_vars_eNB_g[Mod_id]->mu_mimo_mode[UE_id].rballoc_sub[UE_id] = rballoc_sub_UE[CC_id][UE_id][UE_id];
-          LOG_D(MAC, "RB Alloc for UE%d and Subband%d = %d\n", 
-                UE_id, j, 
+          LOG_D(MAC, "RB Alloc for UE%d and Subband%d = %d\n",
+                UE_id, j,
                 ue_sched_ctl->rballoc_sub_UE[CC_id][j]);
         }
 
         //PHY_vars_eNB_g[Mod_id]->mu_mimo_mode[UE_id].pre_nb_available_rbs = pre_nb_available_rbs[CC_id][UE_id];
         LOG_D(MAC, "[eNB %d][SLICE %d]Total RBs allocated for UE%d = %d\n",
-              Mod_id, 
-              eNB->slice_info.dl[slice_idx].id, 
+              Mod_id,
+              eNB->slice_info.dl[slice_idx].id,
               UE_id,
               ue_sched_ctl->pre_nb_available_rbs[CC_id]);
       }
@@ -1628,7 +1628,7 @@ void ulsch_scheduler_pre_processor(module_id_t module_idP,
                                    sub_frame_t subframeP,
                                    unsigned char sched_subframeP,
                                    uint16_t *first_rb) {
-  int UE_id;                                   
+  int UE_id;
   uint16_t n;
   uint8_t CC_id, harq_pid;
   uint16_t nb_allocated_rbs[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB];
@@ -1679,16 +1679,16 @@ void ulsch_scheduler_pre_processor(module_id_t module_idP,
   for (UE_id = UE_list->head_ul; UE_id >= 0; UE_id = UE_list->next_ul[UE_id]) {
     if (UE_list->UE_template[CC_id][UE_id].rach_resource_type > 0) continue;
 
-    LOG_D(MAC, "In ulsch_preprocessor: handling UE %d/%x\n", 
+    LOG_D(MAC, "In ulsch_preprocessor: handling UE %d/%x\n",
           UE_id,
           rntiTable[UE_id]);
 
     for (n = 0; n < UE_list->numactiveULCCs[UE_id]; n++) {
       // This is the actual CC_id in the list
       CC_id = UE_list->ordered_ULCCids[n][UE_id];
-      LOG_D(MAC, "In ulsch_preprocessor: handling UE %d/%x CCid %d\n", 
-            UE_id, 
-            rntiTable[UE_id], 
+      LOG_D(MAC, "In ulsch_preprocessor: handling UE %d/%x CCid %d\n",
+            UE_id,
+            rntiTable[UE_id],
             CC_id);
       /*
           if((mac_xface->get_nCCE_max(module_idP,CC_id,3,subframeP) - nCCE_to_be_used[CC_id])  > (1<<aggregation)) {
@@ -1700,7 +1700,7 @@ void ulsch_scheduler_pre_processor(module_id_t module_idP,
       ue_sched_ctl->max_rbs_allowed_slice_uplink[CC_id][slice_idx] =
         nb_rbs_allowed_slice(sli->ul[slice_idx].pct, N_RB_UL);
       first_rb_offset = UE_list->first_rb_offset[CC_id][slice_idx];
-      available_rbs = 
+      available_rbs =
         cmin(ue_sched_ctl->max_rbs_allowed_slice_uplink[CC_id][slice_idx], N_RB_UL - first_rb[CC_id] - first_rb_offset);
 
       if (available_rbs < 0)
@@ -1715,18 +1715,18 @@ void ulsch_scheduler_pre_processor(module_id_t module_idP,
       } else {
         average_rbs_per_user[CC_id] = 1;
         LOG_W(MAC, "[eNB %d] frame %d subframe %d: UE %d CC %d: can't get average rb per user (should not be here)\n",
-              module_idP, 
-              frameP, 
-              subframeP, 
-              UE_id, 
+              module_idP,
+              frameP,
+              subframeP,
+              UE_id,
               CC_id);
       }
 
       if (total_ue_count[CC_id] > 0) {
         LOG_D(MAC, "[eNB %d] Frame %d subframe %d: total ue to be scheduled %d\n",
-              module_idP, 
-              frameP, 
-              subframeP, 
+              module_idP,
+              frameP,
+              subframeP,
               total_ue_count[CC_id]);
       }
     }
@@ -1754,9 +1754,9 @@ void ulsch_scheduler_pre_processor(module_id_t module_idP,
 
       total_allocated_rbs[CC_id] += nb_allocated_rbs[CC_id][UE_id];
       LOG_D(MAC, "In ulsch_preprocessor: assigning %d RBs for UE %d/%x CCid %d, harq_pid %d\n",
-            nb_allocated_rbs[CC_id][UE_id], 
-            UE_id, 
-            rntiTable[UE_id], 
+            nb_allocated_rbs[CC_id][UE_id],
+            UE_id,
+            rntiTable[UE_id],
             CC_id,
             harq_pid);
     }
@@ -1781,7 +1781,7 @@ void ulsch_scheduler_pre_processor(module_id_t module_idP,
         total_remaining_rbs[CC_id]++;
       }
 
-      while (UE_template->pre_allocated_nb_rb_ul[slice_idx] > 0 && 
+      while (UE_template->pre_allocated_nb_rb_ul[slice_idx] > 0 &&
              nb_allocated_rbs[CC_id][UE_id] < UE_template->pre_allocated_nb_rb_ul[slice_idx] &&
              total_remaining_rbs[CC_id] > 0) {
         nb_allocated_rbs[CC_id][UE_id] = cmin(nb_allocated_rbs[CC_id][UE_id] + 1, UE_template->pre_allocated_nb_rb_ul[slice_idx]);
@@ -1791,12 +1791,12 @@ void ulsch_scheduler_pre_processor(module_id_t module_idP,
 
       UE_template->pre_allocated_nb_rb_ul[slice_idx] = nb_allocated_rbs[CC_id][UE_id];
       LOG_D(MAC, "******************UL Scheduling Information for UE%d CC_id %d ************************\n",
-            UE_id, 
+            UE_id,
             CC_id);
       LOG_D(MAC, "[eNB %d] total RB allocated for UE%d CC_id %d  = %d\n",
-            module_idP, 
-            UE_id, 
-            CC_id, 
+            module_idP,
+            UE_id,
+            CC_id,
             UE_template->pre_allocated_nb_rb_ul[slice_idx]);
     }
   }
@@ -1805,10 +1805,10 @@ void ulsch_scheduler_pre_processor(module_id_t module_idP,
 }
 
 void
-assign_max_mcs_min_rb(module_id_t module_idP, 
-                      int slice_idx, 
+assign_max_mcs_min_rb(module_id_t module_idP,
+                      int slice_idx,
                       int frameP,
-                      sub_frame_t subframeP, 
+                      sub_frame_t subframeP,
                       uint16_t *first_rb) {
   int i;
   uint16_t n, UE_id;
@@ -1840,9 +1840,9 @@ assign_max_mcs_min_rb(module_id_t module_idP,
       // This is the actual CC_id in the list
       CC_id = UE_list->ordered_ULCCids[n][UE_id];
       AssertFatal(CC_id < RC.nb_mac_CC[module_idP], "CC_id %u should be < %u, loop n=%u < numactiveULCCs[%u]=%u",
-                  CC_id, 
-                  NFAPI_CC_MAX, 
-                  n, 
+                  CC_id,
+                  NFAPI_CC_MAX,
+                  n,
                   UE_id,
                   UE_list->numactiveULCCs[UE_id]);
       UE_template = &UE_list->UE_template[CC_id][UE_id];
@@ -1871,12 +1871,12 @@ assign_max_mcs_min_rb(module_id_t module_idP,
         }
 
         first_rb_offset = UE_list->first_rb_offset[CC_id][slice_idx];
-        available_rbs = 
+        available_rbs =
           cmin(ue_sched_ctl->max_rbs_allowed_slice_uplink[CC_id][slice_idx], N_RB_UL - first_rb[CC_id] - first_rb_offset);
 
-        while (tbs < bits_to_schedule && 
-               rb_table[rb_table_index] < available_rbs && 
-               UE_template->phr_info - tx_power > 0 && 
+        while (tbs < bits_to_schedule &&
+               rb_table[rb_table_index] < available_rbs &&
+               UE_template->phr_info - tx_power > 0 &&
                rb_table_index < 32) {
           rb_table_index++;
           tbs = get_TBS_UL(UE_template->pre_assigned_mcs_ul, rb_table[rb_table_index]) << 3;
@@ -1895,10 +1895,10 @@ assign_max_mcs_min_rb(module_id_t module_idP,
         UE_template->pre_allocated_rb_table_index_ul = rb_table_index;
         UE_template->pre_allocated_nb_rb_ul[slice_idx] = rb_table[rb_table_index];
         LOG_D(MAC, "[eNB %d] frame %d subframe %d: for UE %d CC %d: pre-assigned mcs %d, pre-allocated rb_table[%d]=%d RBs (phr %d, tx power %d)\n",
-              module_idP, 
-              frameP, 
-              subframeP, 
-              UE_id, 
+              module_idP,
+              frameP,
+              subframeP,
+              UE_id,
               CC_id,
               UE_template->pre_assigned_mcs_ul,
               UE_template->pre_allocated_rb_table_index_ul,
@@ -1981,12 +1981,12 @@ static int ue_ul_compare(const void *_a, const void *_b, void *_params) {
   return 0;
 }
 
-void 
-sort_ue_ul(module_id_t module_idP, 
-           int slice_idx, 
-           int frameP, 
-           sub_frame_t subframeP, 
-           rnti_t *rntiTable) 
+void
+sort_ue_ul(module_id_t module_idP,
+           int slice_idx,
+           int frameP,
+           sub_frame_t subframeP,
+           rnti_t *rntiTable)
 {
   int i;
   int list[MAX_MOBILES_PER_ENB];
@@ -1997,8 +1997,8 @@ sort_ue_ul(module_id_t module_idP,
   for (i = 0; i < MAX_MOBILES_PER_ENB; i++) {
     rntiTable[i] = UE_RNTI(module_idP, i);
     // Valid element and is not the actual CC_id in the list
-    if (UE_list->active[i] == TRUE &&                           
-        rntiTable[i] != NOT_A_RNTI &&                 
+    if (UE_list->active[i] == TRUE &&
+        rntiTable[i] != NOT_A_RNTI &&
         UE_list->UE_sched_ctrl[i].ul_out_of_sync != 1 &&
         ue_ul_slice_membership(module_idP, i, slice_idx)) {
       list[list_size++] = i; // Add to list
diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c
index 99736939c49c0b07dece41b82b25a0378becb734..b72f26780c57941eb1f5e5e73e35ae733198f312 100644
--- a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c
+++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c
@@ -48,6 +48,7 @@
 #include "platform_constants.h"
 #include "common/utils/LOG/vcd_signal_dumper.h"
 #include "msc.h"
+#include "common/ngran_types.h"
 #include "targets/COMMON/openairinterface5g_limits.h"
 #include "SIMULATION/ETH_TRANSPORT/proto.h"
 #include "UTIL/OSA/osa_defs.h"
@@ -58,6 +59,11 @@
 #  include "gtpv1u_eNB_task.h"
 #  include "gtpv1u.h"
 
+#include "ENB_APP/enb_config.h"
+#ifndef UETARGET
+#include "LAYER2/PROTO_AGENT/proto_agent.h"
+#endif
+
 extern int otg_enabled;
 extern uint8_t nfapi_mode;
 #include "common/ran_context.h"
@@ -184,10 +190,22 @@ boolean_t pdcp_data_req(
                                   sdu_buffer_sizeP);
         LOG_UI(PDCP, "Before rlc_data_req 1, srb_flagP: %d, rb_idP: %d \n", srb_flagP, rb_idP);
       }
-
-      rlc_status = rlc_data_req(ctxt_pP, srb_flagP, MBMS_FLAG_YES, rb_idP, muiP, confirmP, sdu_buffer_sizeP, pdcp_pdu_p
-                                ,NULL, NULL
-                               );
+#ifndef UETARGET
+      if (NODE_IS_CU(RC.rrc[ctxt_pP->module_id]->node_type)) {
+        /* currently, there is no support to send also the source/destinationL2Id */
+        proto_agent_send_rlc_data_req(ctxt_pP, srb_flagP, MBMS_FLAG_NO, rb_idP, muiP,
+                                      confirmP, sdu_buffer_sizeP, pdcp_pdu_p);
+        /* assume good status */
+        rlc_status = RLC_OP_STATUS_OK;
+
+      } else
+#endif
+      {
+        rlc_status = rlc_data_req(ctxt_pP, srb_flagP, MBMS_FLAG_YES, rb_idP, muiP,
+                                  confirmP, sdu_buffer_sizeP, pdcp_pdu_p
+                                  ,NULL, NULL
+                                  );
+      }
     } else {
       rlc_status = RLC_OP_STATUS_OUT_OF_RESSOURCES;
       LOG_E(PDCP,PROTOCOL_CTXT_FMT" PDCP_DATA_REQ SDU DROPPED, OUT OF MEMORY \n",
@@ -346,38 +364,129 @@ boolean_t pdcp_data_req(
      */
     LOG_DUMPMSG(PDCP,DEBUG_PDCP,(char *)pdcp_pdu_p->data,pdcp_pdu_size,
                 "[MSG] PDCP DL %s PDU on rb_id %d\n",(srb_flagP)? "CONTROL" : "DATA", rb_idP);
-    LOG_D(PDCP, "Before rlc_data_req 2, srb_flagP: %d, rb_idP: %d \n", srb_flagP, rb_idP);
-    rlc_status = rlc_data_req(ctxt_pP, srb_flagP, MBMS_FLAG_NO, rb_idP, muiP, confirmP, pdcp_pdu_size, pdcp_pdu_p
-                              ,sourceL2Id
-                              ,destinationL2Id
+   
+    if ((pdcp_pdu_p!=NULL) && (srb_flagP == 0) && (ctxt_pP->enb_flag == 1))
+    {
+
+#ifndef UETARGET
+       LOG_D(PDCP, "pdcp data req on drb %d, size %d, rnti %x, node_type %d \n", 
+            rb_idP, pdcp_pdu_size, ctxt_pP->rnti, RC.rrc[ctxt_pP->module_id]->node_type);
+
+       if (NODE_IS_CU(RC.rrc[ctxt_pP->module_id]->node_type)) {
+         /* currently, there is no support to send also the source/destinationL2Id */
+         proto_agent_send_rlc_data_req(ctxt_pP, srb_flagP, MBMS_FLAG_NO, rb_idP, muiP,
+                                       confirmP, pdcp_pdu_size, pdcp_pdu_p);
+         /* assume good status */
+         rlc_status = RLC_OP_STATUS_OK;
+         ret = TRUE;
+         LOG_D(PDCP, "proto_agent_send_rlc_data_req for UE RNTI %x, rb %d, pdu size %d \n", 
+               ctxt_pP->rnti, rb_idP, pdcp_pdu_size);
+
+      } else if (NODE_IS_DU(RC.rrc[ctxt_pP->module_id]->node_type)){
+        LOG_E(PDCP, "Can't be DU, bad node type %d \n", RC.rrc[ctxt_pP->module_id]->node_type);
+        ret=FALSE;
+      } else
+#endif
+      {
+        rlc_status = rlc_data_req(ctxt_pP, srb_flagP, MBMS_FLAG_NO, rb_idP, muiP,
+                                  confirmP, pdcp_pdu_size, pdcp_pdu_p, sourceL2Id,
+                                  destinationL2Id
                              );
-  }
+          switch (rlc_status) {
+            case RLC_OP_STATUS_OK:
+              LOG_D(PDCP, "Data sending request over RLC succeeded!\n");
+              ret=TRUE;
+              break;
 
-  switch (rlc_status) {
-    case RLC_OP_STATUS_OK:
-      LOG_D(PDCP, "Data sending request over RLC succeeded!\n");
-      ret=TRUE;
-      break;
+            case RLC_OP_STATUS_BAD_PARAMETER:
+              LOG_W(PDCP, "Data sending request over RLC failed with 'Bad Parameter' reason!\n");
+              ret= FALSE;
+              break;
 
-    case RLC_OP_STATUS_BAD_PARAMETER:
-      LOG_W(PDCP, "Data sending request over RLC failed with 'Bad Parameter' reason!\n");
-      ret= FALSE;
-      break;
+            case RLC_OP_STATUS_INTERNAL_ERROR:
+              LOG_W(PDCP, "Data sending request over RLC failed with 'Internal Error' reason!\n");
+              ret= FALSE;
+              break;
 
-    case RLC_OP_STATUS_INTERNAL_ERROR:
-      LOG_W(PDCP, "Data sending request over RLC failed with 'Internal Error' reason!\n");
-      ret= FALSE;
-      break;
+            case RLC_OP_STATUS_OUT_OF_RESSOURCES:
+              LOG_W(PDCP, "Data sending request over RLC failed with 'Out of Resources' reason!\n");
+              ret= FALSE;
+              break;
 
-    case RLC_OP_STATUS_OUT_OF_RESSOURCES:
-      LOG_W(PDCP, "Data sending request over RLC failed with 'Out of Resources' reason!\n");
-      ret= FALSE;
-      break;
+            default:
+              LOG_W(PDCP, "RLC returned an unknown status code after PDCP placed the order to send some data (Status Code:%d)\n", rlc_status);
+              ret= FALSE;
+              break;
+          } // switch case 
+      } /* end if node_type is CU */
+    }
+    else // SRB
+    {
+
+#ifndef UETARGET
+      if (NODE_IS_CU(RC.rrc[ctxt_pP->module_id]->node_type)) {
+        // DL transfer
+        MessageDef                            *message_p;
+        // Note: the acyual task must be TASK_PDCP_ENB, but this task is not created
+        message_p = itti_alloc_new_message (TASK_PDCP_ENB, F1AP_DL_RRC_MESSAGE);
+        F1AP_DL_RRC_MESSAGE (message_p).rrc_container =  &pdcp_pdu_p->data[0] ;
+        F1AP_DL_RRC_MESSAGE (message_p).rrc_container_length = pdcp_pdu_size;
+        F1AP_DL_RRC_MESSAGE (message_p).gNB_CU_ue_id  = 0;  
+        F1AP_DL_RRC_MESSAGE (message_p).gNB_DU_ue_id  = 0;
+        F1AP_DL_RRC_MESSAGE (message_p).old_gNB_DU_ue_id  = 0xFFFFFFFF; // unknown
+        F1AP_DL_RRC_MESSAGE (message_p).rnti = ctxt_pP->rnti;
+        F1AP_DL_RRC_MESSAGE (message_p).srb_id = rb_idP;
+        F1AP_DL_RRC_MESSAGE (message_p).execute_duplication      = 1;
+        F1AP_DL_RRC_MESSAGE (message_p).RAT_frequency_priority_information.en_dc      = 0;
+        itti_send_msg_to_task (TASK_CU_F1, ctxt_pP->module_id, message_p);
+        //CU_send_DL_RRC_MESSAGE_TRANSFER(ctxt_pP->module_id, message_p);
+        LOG_I(PDCP, "Send F1AP_DL_RRC_MESSAGE with ITTI\n");
+        ret=TRUE;
+
+      } else
+#endif
+      {
+        rlc_status = rlc_data_req(ctxt_pP
+                                  , srb_flagP
+                                  , MBMS_FLAG_NO
+                                  , rb_idP
+                                  , muiP
+                                  , confirmP
+                                  , pdcp_pdu_size
+                                  , pdcp_pdu_p
+#ifdef Rel14
+                                  ,NULL
+                                  ,NULL
+#endif
+                                  );
+        switch (rlc_status) {
+          case RLC_OP_STATUS_OK:
+            LOG_D(PDCP, "Data sending request over RLC succeeded!\n");
+            ret=TRUE;
+            break;
 
-    default:
-      LOG_W(PDCP, "RLC returned an unknown status code after PDCP placed the order to send some data (Status Code:%d)\n", rlc_status);
-      ret= FALSE;
-      break;
+          case RLC_OP_STATUS_BAD_PARAMETER:
+            LOG_W(PDCP, "Data sending request over RLC failed with 'Bad Parameter' reason!\n");
+            ret= FALSE;
+            break;
+
+          case RLC_OP_STATUS_INTERNAL_ERROR:
+            LOG_W(PDCP, "Data sending request over RLC failed with 'Internal Error' reason!\n");
+            ret= FALSE;
+            break;
+
+          case RLC_OP_STATUS_OUT_OF_RESSOURCES:
+            LOG_W(PDCP, "Data sending request over RLC failed with 'Out of Resources' reason!\n");
+            ret= FALSE;
+            break;
+
+          default:
+            LOG_W(PDCP, "RLC returned an unknown status code after PDCP placed the order to send some data (Status Code:%d)\n", rlc_status);
+            ret= FALSE;
+            break;
+        } // switch case
+      }
+    }
   }
 
   if (ctxt_pP->enb_flag == ENB_FLAG_YES) {
@@ -610,13 +719,13 @@ pdcp_data_ind(
         }
 
         security_ok = pdcp_validate_security(ctxt_pP,
-                                             pdcp_p,
-                                             srb_flagP,
-                                             rb_idP,
-                                             pdcp_header_len,
+                               pdcp_p,
+                               srb_flagP,
+                               rb_idP,
+                               pdcp_header_len,
                                              rx_hfn_for_count,
                                              pdcp_sn_for_count,
-                                             sdu_buffer_pP->data,
+                               sdu_buffer_pP->data,
                                              sdu_buffer_sizeP - pdcp_tailer_len) == 0;
 
         if (ctxt_pP->enb_flag == ENB_FLAG_NO) {
@@ -679,156 +788,156 @@ pdcp_data_ind(
     payload_offset=pdcp_header_len;// PDCP_USER_PLANE_DATA_PDU_LONG_SN_HEADER_SIZE;
 
     switch (pdcp_p->rlc_mode) {
-      case RLC_MODE_AM: {
-        /* process as described in 36.323 5.1.2.1.2 */
-        int reordering_window;
+    case RLC_MODE_AM: {
+      /* process as described in 36.323 5.1.2.1.2 */
+      int reordering_window;
 
-        if (pdcp_p->seq_num_size == 7)
-          reordering_window = REORDERING_WINDOW_SN_7BIT;
-        else
-          reordering_window = REORDERING_WINDOW_SN_12BIT;
-
-        if (sequence_number - pdcp_p->last_submitted_pdcp_rx_sn > reordering_window ||
-            (pdcp_p->last_submitted_pdcp_rx_sn - sequence_number >= 0 &&
-             pdcp_p->last_submitted_pdcp_rx_sn - sequence_number < reordering_window)) {
-          /* TODO: specs say to decipher and do header decompression */
-          LOG_W(PDCP,
-                PROTOCOL_PDCP_CTXT_FMT"discard PDU, out of\n",
-                PROTOCOL_PDCP_CTXT_ARGS(ctxt_pP, pdcp_p));
-          LOG_W(PDCP, "Ignoring PDU...\n");
-          free_mem_block(sdu_buffer_pP, __func__);
-          /* TODO: indicate integrity verification failure to upper layer */
-          return FALSE;
-        } else if (pdcp_p->next_pdcp_rx_sn - sequence_number > reordering_window) {
+      if (pdcp_p->seq_num_size == 7)
+        reordering_window = REORDERING_WINDOW_SN_7BIT;
+      else
+        reordering_window = REORDERING_WINDOW_SN_12BIT;
+
+      if (sequence_number - pdcp_p->last_submitted_pdcp_rx_sn > reordering_window ||
+          (pdcp_p->last_submitted_pdcp_rx_sn - sequence_number >= 0 &&
+           pdcp_p->last_submitted_pdcp_rx_sn - sequence_number < reordering_window)) {
+        /* TODO: specs say to decipher and do header decompression */
+        LOG_W(PDCP,
+              PROTOCOL_PDCP_CTXT_FMT"discard PDU, out of\n",
+              PROTOCOL_PDCP_CTXT_ARGS(ctxt_pP, pdcp_p));
+        LOG_W(PDCP, "Ignoring PDU...\n");
+        free_mem_block(sdu_buffer_pP, __func__);
+        /* TODO: indicate integrity verification failure to upper layer */
+        return FALSE;
+      } else if (pdcp_p->next_pdcp_rx_sn - sequence_number > reordering_window) {
+        pdcp_p->rx_hfn++;
+        rx_hfn_for_count  = pdcp_p->rx_hfn;
+        pdcp_sn_for_count = sequence_number;
+        pdcp_p->next_pdcp_rx_sn = sequence_number + 1;
+      } else if (sequence_number - pdcp_p->next_pdcp_rx_sn >= reordering_window) {
+        rx_hfn_for_count  = pdcp_p->rx_hfn - 1;
+        pdcp_sn_for_count = sequence_number;
+      } else if (sequence_number >= pdcp_p->next_pdcp_rx_sn) {
+        rx_hfn_for_count  = pdcp_p->rx_hfn;
+        pdcp_sn_for_count = sequence_number;
+        pdcp_p->next_pdcp_rx_sn = sequence_number + 1;
+
+        if (pdcp_p->next_pdcp_rx_sn > pdcp_p->maximum_pdcp_rx_sn) {
+          pdcp_p->next_pdcp_rx_sn = 0;
           pdcp_p->rx_hfn++;
-          rx_hfn_for_count  = pdcp_p->rx_hfn;
-          pdcp_sn_for_count = sequence_number;
-          pdcp_p->next_pdcp_rx_sn = sequence_number + 1;
-        } else if (sequence_number - pdcp_p->next_pdcp_rx_sn >= reordering_window) {
-          rx_hfn_for_count  = pdcp_p->rx_hfn - 1;
-          pdcp_sn_for_count = sequence_number;
-        } else if (sequence_number >= pdcp_p->next_pdcp_rx_sn) {
-          rx_hfn_for_count  = pdcp_p->rx_hfn;
-          pdcp_sn_for_count = sequence_number;
-          pdcp_p->next_pdcp_rx_sn = sequence_number + 1;
-
-          if (pdcp_p->next_pdcp_rx_sn > pdcp_p->maximum_pdcp_rx_sn) {
-            pdcp_p->next_pdcp_rx_sn = 0;
-            pdcp_p->rx_hfn++;
-          }
-        } else { /* sequence_number < pdcp_p->next_pdcp_rx_sn */
-          rx_hfn_for_count  = pdcp_p->rx_hfn;
-          pdcp_sn_for_count = sequence_number;
         }
+      } else { /* sequence_number < pdcp_p->next_pdcp_rx_sn */
+        rx_hfn_for_count  = pdcp_p->rx_hfn;
+        pdcp_sn_for_count = sequence_number;
+      }
 
-        if (pdcp_p->security_activated == 1) {
-          if (ctxt_pP->enb_flag == ENB_FLAG_NO) {
-            start_meas(&eNB_pdcp_stats[ctxt_pP->module_id].validate_security);
-          } else {
-            start_meas(&UE_pdcp_stats[ctxt_pP->module_id].validate_security);
-          }
+    if (pdcp_p->security_activated == 1) {
+      if (ctxt_pP->enb_flag == ENB_FLAG_NO) {
+        start_meas(&eNB_pdcp_stats[ctxt_pP->module_id].validate_security);
+      } else {
+        start_meas(&UE_pdcp_stats[ctxt_pP->module_id].validate_security);
+      }
 
-          security_ok = pdcp_validate_security(ctxt_pP,
-                                               pdcp_p,
-                                               srb_flagP,
-                                               rb_idP,
-                                               pdcp_header_len,
-                                               rx_hfn_for_count,
-                                               pdcp_sn_for_count,
-                                               sdu_buffer_pP->data,
-                                               sdu_buffer_sizeP - pdcp_tailer_len) == 0;
+        security_ok = pdcp_validate_security(ctxt_pP,
+        pdcp_p,
+        srb_flagP,
+        rb_idP,
+        pdcp_header_len,
+                                             rx_hfn_for_count,
+                                             pdcp_sn_for_count,
+        sdu_buffer_pP->data,
+                                             sdu_buffer_sizeP - pdcp_tailer_len) == 0;
 
-          if (ctxt_pP->enb_flag == ENB_FLAG_NO) {
-            stop_meas(&eNB_pdcp_stats[ctxt_pP->module_id].validate_security);
-          } else {
-            stop_meas(&UE_pdcp_stats[ctxt_pP->module_id].validate_security);
-          }
-        } else {
-          security_ok = 1;
-        }
+      if (ctxt_pP->enb_flag == ENB_FLAG_NO) {
+        stop_meas(&eNB_pdcp_stats[ctxt_pP->module_id].validate_security);
+      } else {
+        stop_meas(&UE_pdcp_stats[ctxt_pP->module_id].validate_security);
+      }
+      } else {
+        security_ok = 1;
+    }
 
-        if (security_ok == 0) {
-          LOG_W(PDCP,
-                PROTOCOL_PDCP_CTXT_FMT"security not validated for incoming PDPC DRB RLC/AM PDU\n",
-                PROTOCOL_PDCP_CTXT_ARGS(ctxt_pP, pdcp_p));
-          LOG_W(PDCP, "Ignoring PDU...\n");
-          free_mem_block(sdu_buffer_pP, __func__);
-          /* TODO: indicate integrity verification failure to upper layer */
-          return FALSE;
-        }
+      if (security_ok == 0) {
+        LOG_W(PDCP,
+              PROTOCOL_PDCP_CTXT_FMT"security not validated for incoming PDPC DRB RLC/AM PDU\n",
+              PROTOCOL_PDCP_CTXT_ARGS(ctxt_pP, pdcp_p));
+        LOG_W(PDCP, "Ignoring PDU...\n");
+        free_mem_block(sdu_buffer_pP, __func__);
+        /* TODO: indicate integrity verification failure to upper layer */
+        return FALSE;
+      }
 
-        /* TODO: specs say we have to store this PDU in a list and then deliver
-         *       stored packets to upper layers according to a well defined
-         *       procedure. The code below that deals with delivery is today
-         *       too complex to do this properly, so we only send the current
-         *       received packet. This is not correct and has to be fixed
-         *       some day.
-         *       In the meantime, let's pretend the last submitted PDCP SDU
-         *       is the current one.
-         * TODO: we also have to deal with re-establishment PDU (control PDUs)
-         *       that contain no SDU.
-         */
-        pdcp_p->last_submitted_pdcp_rx_sn = sequence_number;
-        break;
-        } /* case RLC_MODE_AM */
+      /* TODO: specs say we have to store this PDU in a list and then deliver
+       *       stored packets to upper layers according to a well defined
+       *       procedure. The code below that deals with delivery is today
+       *       too complex to do this properly, so we only send the current
+       *       received packet. This is not correct and has to be fixed
+       *       some day.
+       *       In the meantime, let's pretend the last submitted PDCP SDU
+       *       is the current one.
+       * TODO: we also have to deal with re-establishment PDU (control PDUs)
+       *       that contain no SDU.
+       */
+      pdcp_p->last_submitted_pdcp_rx_sn = sequence_number;
+      break;
+    } /* case RLC_MODE_AM */
 
-      case RLC_MODE_UM:
+    case RLC_MODE_UM:
 
-        /* process as described in 36.323 5.1.2.1.3 */
-        if (sequence_number < pdcp_p->next_pdcp_rx_sn) {
-          pdcp_p->rx_hfn++;
-        }
+      /* process as described in 36.323 5.1.2.1.3 */
+      if (sequence_number < pdcp_p->next_pdcp_rx_sn) {
+        pdcp_p->rx_hfn++;
+      }
 
-        rx_hfn_for_count  = pdcp_p->rx_hfn;
-        pdcp_sn_for_count = sequence_number;
-        pdcp_p->next_pdcp_rx_sn = sequence_number + 1;
+      rx_hfn_for_count  = pdcp_p->rx_hfn;
+      pdcp_sn_for_count = sequence_number;
+      pdcp_p->next_pdcp_rx_sn = sequence_number + 1;
 
-        if (pdcp_p->next_pdcp_rx_sn > pdcp_p->maximum_pdcp_rx_sn) {
-          pdcp_p->next_pdcp_rx_sn = 0;
-          pdcp_p->rx_hfn++;
-        }
+      if (pdcp_p->next_pdcp_rx_sn > pdcp_p->maximum_pdcp_rx_sn) {
+        pdcp_p->next_pdcp_rx_sn = 0;
+        pdcp_p->rx_hfn++;
+      }
 
-        if (pdcp_p->security_activated == 1) {
-          if (ctxt_pP->enb_flag == ENB_FLAG_NO) {
-            start_meas(&eNB_pdcp_stats[ctxt_pP->module_id].validate_security);
-          } else {
-            start_meas(&UE_pdcp_stats[ctxt_pP->module_id].validate_security);
-          }
+      if (pdcp_p->security_activated == 1) {
+        if (ctxt_pP->enb_flag == ENB_FLAG_NO) {
+          start_meas(&eNB_pdcp_stats[ctxt_pP->module_id].validate_security);
+  } else {
+          start_meas(&UE_pdcp_stats[ctxt_pP->module_id].validate_security);
+        }
 
-          security_ok = pdcp_validate_security(ctxt_pP,
-                                               pdcp_p,
-                                               srb_flagP,
-                                               rb_idP,
-                                               pdcp_header_len,
-                                               rx_hfn_for_count,
-                                               pdcp_sn_for_count,
-                                               sdu_buffer_pP->data,
-                                               sdu_buffer_sizeP - pdcp_tailer_len) == 0;
+        security_ok = pdcp_validate_security(ctxt_pP,
+                                             pdcp_p,
+                                             srb_flagP,
+                                             rb_idP,
+                                             pdcp_header_len,
+                                             rx_hfn_for_count,
+                                             pdcp_sn_for_count,
+                                             sdu_buffer_pP->data,
+                                             sdu_buffer_sizeP - pdcp_tailer_len) == 0;
 
-          if (ctxt_pP->enb_flag == ENB_FLAG_NO) {
-            stop_meas(&eNB_pdcp_stats[ctxt_pP->module_id].validate_security);
-          } else {
-            stop_meas(&UE_pdcp_stats[ctxt_pP->module_id].validate_security);
-          }
+        if (ctxt_pP->enb_flag == ENB_FLAG_NO) {
+          stop_meas(&eNB_pdcp_stats[ctxt_pP->module_id].validate_security);
         } else {
-          security_ok = 1;
+          stop_meas(&UE_pdcp_stats[ctxt_pP->module_id].validate_security);
         }
+      } else {
+        security_ok = 1;
+      }
 
-        if (security_ok == 0) {
-          LOG_W(PDCP,
-                PROTOCOL_PDCP_CTXT_FMT"security not validated for incoming PDPC DRB RLC/UM PDU\n",
-                PROTOCOL_PDCP_CTXT_ARGS(ctxt_pP, pdcp_p));
-          LOG_W(PDCP, "Ignoring PDU...\n");
-          free_mem_block(sdu_buffer_pP, __func__);
-          /* TODO: indicate integrity verification failure to upper layer */
-          return FALSE;
-        }
+      if (security_ok == 0) {
+        LOG_W(PDCP,
+              PROTOCOL_PDCP_CTXT_FMT"security not validated for incoming PDPC DRB RLC/UM PDU\n",
+              PROTOCOL_PDCP_CTXT_ARGS(ctxt_pP, pdcp_p));
+        LOG_W(PDCP, "Ignoring PDU...\n");
+        free_mem_block(sdu_buffer_pP, __func__);
+        /* TODO: indicate integrity verification failure to upper layer */
+        return FALSE;
+      }
 
-        break;
+      break;
 
-      default:
-        LOG_E(PDCP, "bad RLC mode, cannot happen.\n");
-        exit(1);
+    default:
+      LOG_E(PDCP, "bad RLC mode, cannot happen.\n");
+      exit(1);
     } /* switch (pdcp_p->rlc_mode) */
   } else { /* MBMS_flagP == 0 */
     payload_offset=0;
@@ -857,32 +966,37 @@ pdcp_data_ind(
    */
 
   if (LINK_ENB_PDCP_TO_GTPV1U) {
-    if ((TRUE == ctxt_pP->enb_flag) && (FALSE == srb_flagP)) {
-      MSC_LOG_TX_MESSAGE(
-        MSC_PDCP_ENB,
-        MSC_GTPU_ENB,
-        NULL,0,
-        "0 GTPV1U_ENB_TUNNEL_DATA_REQ  ue %x rab %u len %u",
-        ctxt_pP->rnti,
-        rb_id + 4,
-        sdu_buffer_sizeP - payload_offset);
-      //LOG_T(PDCP,"Sending to GTPV1U %d bytes\n", sdu_buffer_sizeP - payload_offset);
-      gtpu_buffer_p = itti_malloc(TASK_PDCP_ENB, TASK_GTPV1_U,
-                                  sdu_buffer_sizeP - payload_offset + GTPU_HEADER_OVERHEAD_MAX);
-      AssertFatal(gtpu_buffer_p != NULL, "OUT OF MEMORY");
-      memcpy(&gtpu_buffer_p[GTPU_HEADER_OVERHEAD_MAX], &sdu_buffer_pP->data[payload_offset], sdu_buffer_sizeP - payload_offset);
-      message_p = itti_alloc_new_message(TASK_PDCP_ENB, GTPV1U_ENB_TUNNEL_DATA_REQ);
-      AssertFatal(message_p != NULL, "OUT OF MEMORY");
-      GTPV1U_ENB_TUNNEL_DATA_REQ(message_p).buffer   = gtpu_buffer_p;
-      GTPV1U_ENB_TUNNEL_DATA_REQ(message_p).length   = sdu_buffer_sizeP - payload_offset;
-      GTPV1U_ENB_TUNNEL_DATA_REQ(message_p).offset   = GTPU_HEADER_OVERHEAD_MAX;
-      GTPV1U_ENB_TUNNEL_DATA_REQ(message_p).rnti   = ctxt_pP->rnti;
-      GTPV1U_ENB_TUNNEL_DATA_REQ(message_p).rab_id   = rb_id + 4;
-      itti_send_msg_to_task(TASK_GTPV1_U, INSTANCE_DEFAULT, message_p);
-      packet_forwarded = TRUE;
-    }
+  if ((TRUE == ctxt_pP->enb_flag) && (FALSE == srb_flagP)) {
+    LOG_D(PDCP, "Sending packet to GTP, Calling GTPV1U_ENB_TUNNEL_DATA_REQ  ue %x rab %u len %u\n",
+            ctxt_pP->rnti,
+            rb_id + 4,
+            sdu_buffer_sizeP - payload_offset );
+
+    MSC_LOG_TX_MESSAGE(
+      MSC_PDCP_ENB,
+      MSC_GTPU_ENB,
+      NULL,0,
+      "0 GTPV1U_ENB_TUNNEL_DATA_REQ  ue %x rab %u len %u",
+      ctxt_pP->rnti,
+      rb_id + 4,
+      sdu_buffer_sizeP - payload_offset);
+    //LOG_T(PDCP,"Sending to GTPV1U %d bytes\n", sdu_buffer_sizeP - payload_offset);
+    gtpu_buffer_p = itti_malloc(TASK_PDCP_ENB, TASK_GTPV1_U,
+                                sdu_buffer_sizeP - payload_offset + GTPU_HEADER_OVERHEAD_MAX);
+    AssertFatal(gtpu_buffer_p != NULL, "OUT OF MEMORY");
+    memcpy(&gtpu_buffer_p[GTPU_HEADER_OVERHEAD_MAX], &sdu_buffer_pP->data[payload_offset], sdu_buffer_sizeP - payload_offset);
+    message_p = itti_alloc_new_message(TASK_PDCP_ENB, GTPV1U_ENB_TUNNEL_DATA_REQ);
+    AssertFatal(message_p != NULL, "OUT OF MEMORY");
+    GTPV1U_ENB_TUNNEL_DATA_REQ(message_p).buffer       = gtpu_buffer_p;
+    GTPV1U_ENB_TUNNEL_DATA_REQ(message_p).length       = sdu_buffer_sizeP - payload_offset;
+    GTPV1U_ENB_TUNNEL_DATA_REQ(message_p).offset       = GTPU_HEADER_OVERHEAD_MAX;
+    GTPV1U_ENB_TUNNEL_DATA_REQ(message_p).rnti         = ctxt_pP->rnti;
+    GTPV1U_ENB_TUNNEL_DATA_REQ(message_p).rab_id       = rb_id + 4;
+    itti_send_msg_to_task(TASK_GTPV1_U, INSTANCE_DEFAULT, message_p);
+    packet_forwarded = TRUE;
+  }
   } else {
-    packet_forwarded = FALSE;
+  packet_forwarded = FALSE;
   }
 
 #ifdef MBMS_MULTICAST_OUT
@@ -921,28 +1035,28 @@ pdcp_data_ind(
         ((pdcp_data_ind_header_t *) new_sdu_p->data)->rb_id = rb_id;
 
         if (EPC_MODE_ENABLED) {
-          /* for the UE compiled in S1 mode, we need 1 here
-           * for the UE compiled in noS1 mode, we need 0
-           * TODO: be sure of this
-           */
-          if (nfapi_mode == 3) {
+        /* for the UE compiled in S1 mode, we need 1 here
+         * for the UE compiled in noS1 mode, we need 0
+         * TODO: be sure of this
+         */
+        if (nfapi_mode == 3) {
 #ifdef UESIM_EXPANSION
 
             if (UE_NAS_USE_TUN) {
               ((pdcp_data_ind_header_t *) new_sdu_p->data)->inst  = ctxt_pP->module_id;
             } else {
-              ((pdcp_data_ind_header_t *) new_sdu_p->data)->inst  = 0;
+          ((pdcp_data_ind_header_t *) new_sdu_p->data)->inst  = 0;
             }
 
 #else
-            ((pdcp_data_ind_header_t *) new_sdu_p->data)->inst  = ctxt_pP->module_id;
+          ((pdcp_data_ind_header_t *) new_sdu_p->data)->inst  = ctxt_pP->module_id;
 #endif
           } else {  // nfapi_mode
             if (UE_NAS_USE_TUN) {
               ((pdcp_data_ind_header_t *) new_sdu_p->data)->inst  = ctxt_pP->module_id;
-            } else {
-              ((pdcp_data_ind_header_t *) new_sdu_p->data)->inst  = 1;
-            }
+        } else {
+          ((pdcp_data_ind_header_t *) new_sdu_p->data)->inst  = 1;
+        }
           } // nfapi_mode
         }
       } else {
@@ -951,9 +1065,9 @@ pdcp_data_ind(
       }
 
       if( LOG_DEBUGFLAG(DEBUG_PDCP) ) {
-        static uint32_t pdcp_inst = 0;
-        ((pdcp_data_ind_header_t *) new_sdu_p->data)->inst = pdcp_inst++;
-        LOG_D(PDCP, "inst=%d size=%d\n", ((pdcp_data_ind_header_t *) new_sdu_p->data)->inst, ((pdcp_data_ind_header_t *) new_sdu_p->data)->data_size);
+      static uint32_t pdcp_inst = 0;
+      ((pdcp_data_ind_header_t *) new_sdu_p->data)->inst = pdcp_inst++;
+      LOG_D(PDCP, "inst=%d size=%d\n", ((pdcp_data_ind_header_t *) new_sdu_p->data)->inst, ((pdcp_data_ind_header_t *) new_sdu_p->data)->data_size);
       }
 
       memcpy(&new_sdu_p->data[sizeof (pdcp_data_ind_header_t)],
@@ -969,27 +1083,34 @@ pdcp_data_ind(
     //util_print_hex_octets(PDCP, &new_sdu_p->data[sizeof (pdcp_data_ind_header_t)], sdu_buffer_sizeP - payload_offset);
     //util_flush_hex_octets(PDCP, &new_sdu_p->data[sizeof (pdcp_data_ind_header_t)], sdu_buffer_sizeP - payload_offset);
 
-    /*
-       * Update PDCP statistics
-     * XXX Following two actions are identical, is there a merge error?
-     */
-
-    for (pdcp_uid=0; pdcp_uid< MAX_MOBILES_PER_ENB; pdcp_uid++) {
-      if (pdcp_enb[ctxt_pP->module_id].rnti[pdcp_uid] == ctxt_pP->rnti ) {
-        break;
-      }
-    }
+#if defined(STOP_ON_IP_TRAFFIC_OVERLOAD)
+    /* This was an "orphan else" in tag 2019.w07 and discovered during merge.
+     * Commenting so it could be reintegrated. */
+    //else {
+    //  AssertFatal(0, PROTOCOL_PDCP_CTXT_FMT" PDCP_DATA_IND SDU DROPPED, OUT OF MEMORY \n",
+    //              PROTOCOL_PDCP_CTXT_ARGS(ctxt_pP, pdcp_p));
+    //}
 
-    Pdcp_stats_rx[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]++;
-    Pdcp_stats_rx_tmp_w[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]++;
-    Pdcp_stats_rx_bytes[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]+=(sdu_buffer_sizeP  - payload_offset);
-    Pdcp_stats_rx_bytes_tmp_w[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]+=(sdu_buffer_sizeP  - payload_offset);
-    Pdcp_stats_rx_sn[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]=sequence_number;
-    Pdcp_stats_rx_aiat[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]+= (pdcp_enb[ctxt_pP->module_id].sfn - Pdcp_stats_rx_iat[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]);
-    Pdcp_stats_rx_aiat_tmp_w[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]+=(pdcp_enb[ctxt_pP->module_id].sfn - Pdcp_stats_rx_iat[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]);
-    Pdcp_stats_rx_iat[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]=pdcp_enb[ctxt_pP->module_id].sfn;
+#endif
   }
 
+  /* Update PDCP statistics */
+  for (pdcp_uid=0; pdcp_uid< MAX_MOBILES_PER_ENB;pdcp_uid++){
+    if (pdcp_enb[ctxt_pP->module_id].rnti[pdcp_uid] == ctxt_pP->rnti ){
+      break;
+    }
+  }	
+  
+  Pdcp_stats_rx[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]++;
+  Pdcp_stats_rx_tmp_w[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]++;
+  Pdcp_stats_rx_bytes[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]+=(sdu_buffer_sizeP  - payload_offset);
+  Pdcp_stats_rx_bytes_tmp_w[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]+=(sdu_buffer_sizeP  - payload_offset);
+  
+  Pdcp_stats_rx_sn[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]=sequence_number;
+  Pdcp_stats_rx_aiat[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]+= (pdcp_enb[ctxt_pP->module_id].sfn - Pdcp_stats_rx_iat[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]);
+  Pdcp_stats_rx_aiat_tmp_w[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]+=(pdcp_enb[ctxt_pP->module_id].sfn - Pdcp_stats_rx_iat[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]);
+  Pdcp_stats_rx_iat[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]=pdcp_enb[ctxt_pP->module_id].sfn;
+
   free_mem_block(sdu_buffer_pP, __func__);
 
   if (ctxt_pP->enb_flag) {
@@ -1051,6 +1172,8 @@ void pdcp_update_stats(const protocol_ctxt_t *const  ctxt_pP) {
     }
   }
 }
+
+
 //-----------------------------------------------------------------------------
 void
 pdcp_run (
@@ -1173,6 +1296,41 @@ pdcp_run (
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_RUN, VCD_FUNCTION_OUT);
 }
 
+void pdcp_init_stats_UE(module_id_t mod, uint16_t uid)
+{
+  Pdcp_stats_tx_window_ms[mod][uid] = 100;
+  Pdcp_stats_rx_window_ms[mod][uid] = 100;
+
+  for (int i = 0; i < NB_RB_MAX; ++i) {
+    Pdcp_stats_tx_bytes[mod][uid][i] = 0;
+    Pdcp_stats_tx_bytes_w[mod][uid][i] = 0;
+    Pdcp_stats_tx_bytes_tmp_w[mod][uid][i] = 0;
+    Pdcp_stats_tx[mod][uid][i] = 0;
+    Pdcp_stats_tx_w[mod][uid][i] = 0;
+    Pdcp_stats_tx_tmp_w[mod][uid][i] = 0;
+    Pdcp_stats_tx_sn[mod][uid][i] = 0;
+    Pdcp_stats_tx_throughput_w[mod][uid][i] = 0;
+    Pdcp_stats_tx_aiat[mod][uid][i] = 0;
+    Pdcp_stats_tx_aiat_w[mod][uid][i] = 0;
+    Pdcp_stats_tx_aiat_tmp_w[mod][uid][i] = 0;
+    Pdcp_stats_tx_iat[mod][uid][i] = 0;
+
+    Pdcp_stats_rx[mod][uid][i] = 0;
+    Pdcp_stats_rx_w[mod][uid][i] = 0;
+    Pdcp_stats_rx_tmp_w[mod][uid][i] = 0;
+    Pdcp_stats_rx_bytes[mod][uid][i] = 0;
+    Pdcp_stats_rx_bytes_w[mod][uid][i] = 0;
+    Pdcp_stats_rx_bytes_tmp_w[mod][uid][i] = 0;
+    Pdcp_stats_rx_sn[mod][uid][i] = 0;
+    Pdcp_stats_rx_goodput_w[mod][uid][i] = 0;
+    Pdcp_stats_rx_aiat[mod][uid][i] = 0;
+    Pdcp_stats_rx_aiat_w[mod][uid][i] = 0;
+    Pdcp_stats_rx_aiat_tmp_w[mod][uid][i] = 0;
+    Pdcp_stats_rx_iat[mod][uid][i] = 0;
+    Pdcp_stats_rx_outoforder[mod][uid][i] = 0;
+  }
+}
+
 void pdcp_add_UE(const protocol_ctxt_t *const  ctxt_pP) {
   int i, ue_flag=1; //, ret=-1; to be decied later
 
@@ -1190,6 +1348,7 @@ void pdcp_add_UE(const protocol_ctxt_t *const  ctxt_pP) {
         pdcp_enb[ctxt_pP->module_id].uid[i]=i;
         pdcp_enb[ctxt_pP->module_id].num_ues++;
         printf("add new uid is %d %x\n\n", i, ctxt_pP->rnti);
+        pdcp_init_stats_UE(ctxt_pP->module_id, i);
         // ret=1;
         break;
       }
@@ -2142,9 +2301,8 @@ void pdcp_layer_init(void)
   memset(pdcp_enb, 0, sizeof(pdcp_enb_t));
   memset(Pdcp_stats_tx_window_ms, 0, sizeof(Pdcp_stats_tx_window_ms));
   memset(Pdcp_stats_rx_window_ms, 0, sizeof(Pdcp_stats_rx_window_ms));
-
-  for (i =0; i< MAX_NUM_CCs ; i ++) {
-    for (j=0; j< MAX_MOBILES_PER_ENB; j++) {
+  for (i = 0; i < MAX_eNB; i++) {
+    for (j = 0; j < MAX_MOBILES_PER_ENB; j++) {
       Pdcp_stats_tx_window_ms[i][j]=100;
       Pdcp_stats_rx_window_ms[i][j]=100;
     }
diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp.h b/openair2/LAYER2/PDCP_v10.1.0/pdcp.h
index cf8d1a1fd617c4b62ef37d82e9700b66d8a8dcf3..ce62893170397dab8f664f9656615ccd364288ae 100644
--- a/openair2/LAYER2/PDCP_v10.1.0/pdcp.h
+++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp.h
@@ -26,7 +26,7 @@
 * \version 1.0
 */
 
-/** @defgroup _pdcp PDCP
+/** @defgroup _pdcp PDCP 
 * @ingroup _oai2
 * @{
 */
@@ -76,39 +76,39 @@ extern int             pdcp_instance_cnt;
 #define PROTOCOL_PDCP_CTXT_FMT PROTOCOL_CTXT_FMT"[%s %02u] "
 
 #define PROTOCOL_PDCP_CTXT_ARGS(CTXT_Pp, pDCP_Pp) PROTOCOL_CTXT_ARGS(CTXT_Pp),\
-  (pDCP_Pp->is_srb) ? "SRB" : "DRB",\
-  pDCP_Pp->rb_id
+          (pDCP_Pp->is_srb) ? "SRB" : "DRB",\
+          pDCP_Pp->rb_id
 int init_pdcp_thread(void);
 void cleanup_pdcp_thread(void);
 
-uint32_t Pdcp_stats_tx_window_ms[MAX_NUM_CCs][MAX_MOBILES_PER_ENB];
-uint32_t Pdcp_stats_tx_bytes[MAX_NUM_CCs][MAX_MOBILES_PER_ENB][NB_RB_MAX];
-uint32_t Pdcp_stats_tx_bytes_w[MAX_NUM_CCs][MAX_MOBILES_PER_ENB][NB_RB_MAX];
-uint32_t Pdcp_stats_tx_bytes_tmp_w[MAX_NUM_CCs][MAX_MOBILES_PER_ENB][NB_RB_MAX];
-uint32_t Pdcp_stats_tx[MAX_NUM_CCs][MAX_MOBILES_PER_ENB][NB_RB_MAX];
-uint32_t Pdcp_stats_tx_w[MAX_NUM_CCs][MAX_MOBILES_PER_ENB][NB_RB_MAX];
-uint32_t Pdcp_stats_tx_tmp_w[MAX_NUM_CCs][MAX_MOBILES_PER_ENB][NB_RB_MAX];
-uint32_t Pdcp_stats_tx_sn[MAX_NUM_CCs][MAX_MOBILES_PER_ENB][NB_RB_MAX];
-uint32_t Pdcp_stats_tx_throughput_w[MAX_NUM_CCs][MAX_MOBILES_PER_ENB][NB_RB_MAX];
-uint32_t Pdcp_stats_tx_aiat[MAX_NUM_CCs][MAX_MOBILES_PER_ENB][NB_RB_MAX];
-uint32_t Pdcp_stats_tx_aiat_w[MAX_NUM_CCs][MAX_MOBILES_PER_ENB][NB_RB_MAX];
-uint32_t Pdcp_stats_tx_aiat_tmp_w[MAX_NUM_CCs][MAX_MOBILES_PER_ENB][NB_RB_MAX];
-uint32_t Pdcp_stats_tx_iat[MAX_NUM_CCs][MAX_MOBILES_PER_ENB][NB_RB_MAX];
-
-uint32_t Pdcp_stats_rx_window_ms[MAX_NUM_CCs][MAX_MOBILES_PER_ENB];
-uint32_t Pdcp_stats_rx[MAX_NUM_CCs][MAX_MOBILES_PER_ENB][NB_RB_MAX];
-uint32_t Pdcp_stats_rx_w[MAX_NUM_CCs][MAX_MOBILES_PER_ENB][NB_RB_MAX];
-uint32_t Pdcp_stats_rx_tmp_w[MAX_NUM_CCs][MAX_MOBILES_PER_ENB][NB_RB_MAX];
-uint32_t Pdcp_stats_rx_bytes[MAX_NUM_CCs][MAX_MOBILES_PER_ENB][NB_RB_MAX];
-uint32_t Pdcp_stats_rx_bytes_w[MAX_NUM_CCs][MAX_MOBILES_PER_ENB][NB_RB_MAX];
-uint32_t Pdcp_stats_rx_bytes_tmp_w[MAX_NUM_CCs][MAX_MOBILES_PER_ENB][NB_RB_MAX];
-uint32_t Pdcp_stats_rx_sn[MAX_NUM_CCs][MAX_MOBILES_PER_ENB][NB_RB_MAX];
-uint32_t Pdcp_stats_rx_goodput_w[MAX_NUM_CCs][MAX_MOBILES_PER_ENB][NB_RB_MAX];
-uint32_t Pdcp_stats_rx_aiat[MAX_NUM_CCs][MAX_MOBILES_PER_ENB][NB_RB_MAX];
-uint32_t Pdcp_stats_rx_aiat_w[MAX_NUM_CCs][MAX_MOBILES_PER_ENB][NB_RB_MAX];
-uint32_t Pdcp_stats_rx_aiat_tmp_w[MAX_NUM_CCs][MAX_MOBILES_PER_ENB][NB_RB_MAX];
-uint32_t Pdcp_stats_rx_iat[MAX_NUM_CCs][MAX_MOBILES_PER_ENB][NB_RB_MAX];
-uint32_t Pdcp_stats_rx_outoforder[MAX_NUM_CCs][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+uint32_t Pdcp_stats_tx_window_ms[MAX_eNB][MAX_MOBILES_PER_ENB];
+uint32_t Pdcp_stats_tx_bytes[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+uint32_t Pdcp_stats_tx_bytes_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+uint32_t Pdcp_stats_tx_bytes_tmp_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+uint32_t Pdcp_stats_tx[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+uint32_t Pdcp_stats_tx_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+uint32_t Pdcp_stats_tx_tmp_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+uint32_t Pdcp_stats_tx_sn[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+uint32_t Pdcp_stats_tx_throughput_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+uint32_t Pdcp_stats_tx_aiat[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+uint32_t Pdcp_stats_tx_aiat_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+uint32_t Pdcp_stats_tx_aiat_tmp_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+uint32_t Pdcp_stats_tx_iat[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+
+uint32_t Pdcp_stats_rx_window_ms[MAX_eNB][MAX_MOBILES_PER_ENB];
+uint32_t Pdcp_stats_rx[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+uint32_t Pdcp_stats_rx_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+uint32_t Pdcp_stats_rx_tmp_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+uint32_t Pdcp_stats_rx_bytes[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+uint32_t Pdcp_stats_rx_bytes_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+uint32_t Pdcp_stats_rx_bytes_tmp_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+uint32_t Pdcp_stats_rx_sn[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+uint32_t Pdcp_stats_rx_goodput_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+uint32_t Pdcp_stats_rx_aiat[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+uint32_t Pdcp_stats_rx_aiat_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+uint32_t Pdcp_stats_rx_aiat_tmp_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+uint32_t Pdcp_stats_rx_iat[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+uint32_t Pdcp_stats_rx_outoforder[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
 
 void pdcp_update_perioidical_stats(const protocol_ctxt_t *const  ctxt_pP);
 
@@ -121,12 +121,12 @@ typedef struct pdcp_enb_s {
   uint16_t uid[MAX_MOBILES_PER_ENB];
   rnti_t rnti[MAX_MOBILES_PER_ENB];
   uint16_t num_ues;
-
+  
   uint64_t sfn;
   frame_t  frame;
   sub_frame_t subframe;
-
-} pdcp_enb_t;
+  
+} pdcp_enb_t; 
 
 pdcp_enb_t pdcp_enb[MAX_NUM_CCs];
 
@@ -151,7 +151,7 @@ typedef struct pdcp_s {
   boolean_t is_ue;
   boolean_t is_srb;
 
-  /* Configured security algorithms */
+   /* Configured security algorithms */
   uint8_t cipheringAlgorithm;
   uint8_t integrityProtAlgorithm;
 
@@ -239,13 +239,13 @@ typedef struct pdcp_mbms_s {
 */
 boolean_t pdcp_data_req(
   protocol_ctxt_t  *ctxt_pP,
-  const srb_flag_t srb_flagP,
-  const rb_id_t rb_id,
-  const mui_t muiP,
-  const confirm_t confirmP, \
-  const sdu_size_t sdu_buffer_size,
+              const srb_flag_t srb_flagP,
+              const rb_id_t rb_id,
+              const mui_t muiP,
+              const confirm_t confirmP, \
+              const sdu_size_t sdu_buffer_size,
   unsigned char *const sdu_buffer,
-  const pdcp_transmission_mode_t mode
+              const pdcp_transmission_mode_t mode
 #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
   ,const uint32_t *const sourceL2Id
   ,const uint32_t *const destinationL2Id
@@ -267,10 +267,10 @@ boolean_t pdcp_data_req(
 */
 boolean_t pdcp_data_ind(
   const protocol_ctxt_t *const  ctxt_pP,
-  const srb_flag_t srb_flagP,
-  const MBMS_flag_t MBMS_flagP,
-  const rb_id_t rb_id,
-  const sdu_size_t sdu_buffer_size,
+              const srb_flag_t srb_flagP,
+              const MBMS_flag_t MBMS_flagP,
+              const rb_id_t rb_id,
+              const sdu_size_t sdu_buffer_size,
   mem_block_t *const sdu_buffer);
 
 /*! \fn void rrc_pdcp_config_req(const protocol_ctxt_t* const ,uint32_t,rb_id_t,uint8_t)
@@ -285,10 +285,10 @@ boolean_t pdcp_data_ind(
 */
 void rrc_pdcp_config_req (
   const protocol_ctxt_t *const  ctxt_pP,
-  const srb_flag_t  srb_flagP,
-  const uint32_t    actionP,
-  const rb_id_t     rb_idP,
-  const uint8_t     security_modeP);
+              const srb_flag_t  srb_flagP,
+              const uint32_t    actionP,
+              const rb_id_t     rb_idP,
+              const uint8_t     security_modeP);
 
 /*! \fn bool rrc_pdcp_config_asn1_req (const protocol_ctxt_t* const , SRB_ToAddModList_t* srb2add_list, DRB_ToAddModList_t* drb2add_list, DRB_ToReleaseList_t*  drb2release_list)
 * \brief  Function for RRC to configure a Radio Bearer.
@@ -306,17 +306,17 @@ void rrc_pdcp_config_req (
 */
 boolean_t rrc_pdcp_config_asn1_req (
   const protocol_ctxt_t *const  ctxt_pP,
-  LTE_SRB_ToAddModList_t  *const srb2add_list,
-  LTE_DRB_ToAddModList_t  *const drb2add_list,
-  LTE_DRB_ToReleaseList_t *const drb2release_list,
-  const uint8_t                   security_modeP,
-  uint8_t                  *const kRRCenc,
-  uint8_t                  *const kRRCint,
-  uint8_t                  *const kUPenc
+    LTE_SRB_ToAddModList_t  *const srb2add_list,
+    LTE_DRB_ToAddModList_t  *const drb2add_list,
+    LTE_DRB_ToReleaseList_t *const drb2release_list,
+    const uint8_t                   security_modeP,
+    uint8_t                  *const kRRCenc,
+    uint8_t                  *const kRRCint,
+    uint8_t                  *const kUPenc
 #if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0))
-  ,LTE_PMCH_InfoList_r9_t  *pmch_InfoList_r9
+    ,LTE_PMCH_InfoList_r9_t  *pmch_InfoList_r9
 #endif
-  ,rb_id_t                 *const defaultDRB
+    ,rb_id_t                 *const defaultDRB 
 );
 
 /*! \fn boolean_t pdcp_config_req_asn1 (const protocol_ctxt_t* const ctxt_pP, srb_flag_t srb_flagP, uint32_t  action, rb_id_t rb_id, uint8_t rb_sn, uint8_t rb_report, uint16_t header_compression_profile, uint8_t security_mode)
@@ -341,20 +341,20 @@ boolean_t rrc_pdcp_config_asn1_req (
 */
 boolean_t pdcp_config_req_asn1 (
   const protocol_ctxt_t *const  ctxt_pP,
-  pdcp_t         *const pdcp_pP,
-  const srb_flag_t       srb_flagP,
-  const rlc_mode_t       rlc_mode,
-  const uint32_t         action,
-  const uint16_t         lc_id,
-  const uint16_t         mch_id,
-  const rb_id_t          rb_id,
-  const uint8_t          rb_sn,
-  const uint8_t          rb_report,
-  const uint16_t         header_compression_profile,
-  const uint8_t          security_mode,
-  uint8_t         *const kRRCenc,
-  uint8_t         *const kRRCint,
-  uint8_t         *const kUPenc);
+              pdcp_t         *const pdcp_pP,
+              const srb_flag_t       srb_flagP,
+              const rlc_mode_t       rlc_mode,
+              const uint32_t         action,
+              const uint16_t         lc_id,
+              const uint16_t         mch_id,
+              const rb_id_t          rb_id,
+              const uint8_t          rb_sn,
+              const uint8_t          rb_report,
+              const uint16_t         header_compression_profile,
+              const uint8_t          security_mode,
+              uint8_t         *const kRRCenc,
+              uint8_t         *const kRRCint,
+              uint8_t         *const kUPenc);
 
 /*! \fn void pdcp_add_UE(const protocol_ctxt_t* const  ctxt_pP)
 * \brief  Function (for RRC) to add a new UE in PDCP module
@@ -362,9 +362,9 @@ boolean_t pdcp_config_req_asn1 (
 * \return     A status about the processing, OK or error code.
 */
 void pdcp_add_UE(const protocol_ctxt_t *const  ctxt_pP);
-
+  
 /*! \fn boolean_t pdcp_remove_UE(const protocol_ctxt_t* const  ctxt_pP)
-* \brief  Function for RRC to remove UE from PDCP module hashtable
+* \brief  Function for RRC to remove UE from PDCP module hashtable 
 * \param[in]  ctxt_pP           Running context.
 * \return     A status about the processing, OK or error code.
 */
@@ -449,26 +449,26 @@ struct sockaddr_in pdcp_sin;
 void pdcp_pc5_socket_init(void);
 
 typedef struct  {
-  rb_id_t             rb_id;
-  sdu_size_t          data_size;
-  signed int          inst;
-  ip_traffic_type_t   traffic_type;
-  uint32_t sourceL2Id;
-  uint32_t destinationL2Id;
+   rb_id_t             rb_id;
+   sdu_size_t          data_size;
+   signed int          inst;
+   ip_traffic_type_t   traffic_type;
+   uint32_t sourceL2Id;
+   uint32_t destinationL2Id;
 } __attribute__((__packed__)) pc5s_header_t;
 
 //new PC5S-message
 typedef struct  {
-  unsigned char bytes[PC5_SIGNALLING_PAYLOAD_SIZE];
+   unsigned char bytes[PC5_SIGNALLING_PAYLOAD_SIZE];
 }  __attribute__((__packed__)) PC5SignallingMessage ;
 
 //example of PC5-S messages
 typedef struct {
-  pc5s_header_t pc5s_header;
-  union {
-    uint8_t status;
-    PC5SignallingMessage pc5_signalling_message;
-  } pc5sPrimitive;
+   pc5s_header_t pc5s_header;
+   union {
+      uint8_t status;
+      PC5SignallingMessage pc5_signalling_message;
+   } pc5sPrimitive;
 } __attribute__((__packed__)) sidelink_pc5s_element;
 
 
@@ -513,33 +513,33 @@ sdu_size_t             pdcp_input_sdu_size_read;
 sdu_size_t             pdcp_input_sdu_remaining_size_to_read;
 
 #define PDCP_COLL_KEY_VALUE(mODULE_iD, rNTI, iS_eNB, rB_iD, iS_sRB) \
-  ((hash_key_t)mODULE_iD          | \
-   (((hash_key_t)(rNTI))   << 8)  | \
-   (((hash_key_t)(iS_eNB)) << 24) | \
-   (((hash_key_t)(rB_iD))  << 25) | \
-   (((hash_key_t)(iS_sRB)) << 33) | \
-   (((hash_key_t)(0x55))   << 34))
+   ((hash_key_t)mODULE_iD          | \
+    (((hash_key_t)(rNTI))   << 8)  | \
+    (((hash_key_t)(iS_eNB)) << 24) | \
+    (((hash_key_t)(rB_iD))  << 25) | \
+    (((hash_key_t)(iS_sRB)) << 33) | \
+    (((hash_key_t)(0x55))   << 34))
 
 // hash key to the same PDCP as indexed by PDCP_COLL_KEY_VALUE(... rB_iD, iS_sRB=0) where rB_iD
 // is the default DRB ID. The hidden code 0x55 indicates the key is indexed by (rB_iD,is_sRB)
 // whereas the hidden code 0xaa indicates the key is for default DRB only
 #define PDCP_COLL_KEY_DEFAULT_DRB_VALUE(mODULE_iD, rNTI, iS_eNB) \
-  ((hash_key_t)mODULE_iD          | \
-   (((hash_key_t)(rNTI))   << 8)  | \
-   (((hash_key_t)(iS_eNB)) << 24) | \
-   (((hash_key_t)(0xff))   << 25) | \
-   (((hash_key_t)(0x00))   << 33) | \
-   (((hash_key_t)(0xaa))   << 34))
+    ((hash_key_t)mODULE_iD          | \
+     (((hash_key_t)(rNTI))   << 8)  | \
+     (((hash_key_t)(iS_eNB)) << 24) | \
+     (((hash_key_t)(0xff))   << 25) | \
+     (((hash_key_t)(0x00))   << 33) | \
+     (((hash_key_t)(0xaa))   << 34))
 
 // service id max val is maxServiceCount = 16 (asn1_constants.h)
 
 #define PDCP_COLL_KEY_MBMS_VALUE(mODULE_iD, rNTI, iS_eNB, sERVICE_ID, sESSION_ID) \
-  ((hash_key_t)mODULE_iD              | \
-   (((hash_key_t)(rNTI))       << 8)  | \
-   (((hash_key_t)(iS_eNB))     << 24) | \
-   (((hash_key_t)(sERVICE_ID)) << 32) | \
-   (((hash_key_t)(sESSION_ID)) << 37) | \
-   (((hash_key_t)(0x0000000000000001))  << 63))
+   ((hash_key_t)mODULE_iD              | \
+    (((hash_key_t)(rNTI))       << 8)  | \
+    (((hash_key_t)(iS_eNB))     << 24) | \
+    (((hash_key_t)(sERVICE_ID)) << 32) | \
+    (((hash_key_t)(sESSION_ID)) << 37) | \
+    (((hash_key_t)(0x0000000000000001))  << 63))
 
 extern hash_table_t  *pdcp_coll_p;
 
diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c
index 4ac866cd6658ed1b8766ccea6451a211b78fa4e3..7324a7c7ea9f6f42d17f87750b237ba19c6ee915 100644
--- a/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c
+++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c
@@ -106,16 +106,16 @@ void debug_pdcp_pc5s_sdu(sidelink_pc5s_element *sl_pc5s_msg, char *title) {
 //-----------------------------------------------------------------------------
 int pdcp_fifo_flush_sdus(const protocol_ctxt_t *const  ctxt_pP) {
   mem_block_t     *sdu_p;
-  int              pdcp_nb_sdu_sent = 0;
+   int              pdcp_nb_sdu_sent = 0;
   int              ret=0;
 
   while ((sdu_p = list_get_head (&pdcp_sdu_list)) != NULL && ((pdcp_data_ind_header_t *)(sdu_p->data))->inst == ctxt_pP->module_id) {
     ((pdcp_data_ind_header_t *)(sdu_p->data))->inst = 0;
-    int rb_id = ((pdcp_data_ind_header_t *)(sdu_p->data))->rb_id;
+      int rb_id = ((pdcp_data_ind_header_t *)(sdu_p->data))->rb_id;
     int sizeToWrite= sizeof (pdcp_data_ind_header_t) +
                      ((pdcp_data_ind_header_t *) sdu_p->data)->data_size;
 
-    if (rb_id == 10) { //hardcoded for PC5-Signaling
+      if (rb_id == 10) { //hardcoded for PC5-Signaling
       if( LOG_DEBUGFLAG(DEBUG_PDCP) ) {
         debug_pdcp_pc5s_sdu((sidelink_pc5s_element *)&(sdu_p->data[sizeof(pdcp_data_ind_header_t)]),
                             "pdcp_fifo_flush_sdus received aPC5S message");
@@ -134,12 +134,12 @@ int pdcp_fifo_flush_sdus(const protocol_ctxt_t *const  ctxt_pP) {
     }  //  PDCP_USE_NETLINK
 
     AssertFatal(ret >= 0,"[PDCP_FIFOS] pdcp_fifo_flush_sdus (errno: %d %s)\n", errno, strerror(errno));
-    list_remove_head (&pdcp_sdu_list);
-    free_mem_block (sdu_p, __func__);
+               list_remove_head (&pdcp_sdu_list);
+               free_mem_block (sdu_p, __func__);
     pdcp_nb_sdu_sent ++;
-  }
+   }
 
-  return pdcp_nb_sdu_sent;
+   return pdcp_nb_sdu_sent;
 }
 
 //-----------------------------------------------------------------------------
@@ -147,24 +147,24 @@ int pdcp_fifo_read_input_sdus (const protocol_ctxt_t *const  ctxt_pP) {
   pdcp_data_req_header_t pdcp_read_header_g;
 
   if (UE_NAS_USE_TUN || ENB_NAS_USE_TUN) {
-    protocol_ctxt_t ctxt = *ctxt_pP;
-    hash_key_t key = HASHTABLE_NOT_A_KEY_VALUE;
-    hashtable_rc_t h_rc;
+  protocol_ctxt_t ctxt = *ctxt_pP;
+  hash_key_t key = HASHTABLE_NOT_A_KEY_VALUE;
+  hashtable_rc_t h_rc;
     pdcp_t *pdcp_p = NULL;
-    int len;
-    rb_id_t rab_id = DEFAULT_RAB_ID;
+  int len;
+  rb_id_t rab_id = DEFAULT_RAB_ID;
 
-    do {
-      VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_FIFO_READ, 1 );
-      VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_FIFO_READ_BUFFER, 1 );
+  do {
+    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_FIFO_READ, 1 );
+    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_FIFO_READ_BUFFER, 1 );
       len = read(UE_NAS_USE_TUN?nas_sock_fd[ctxt_pP->module_id]:nas_sock_fd[0], &nl_rx_buf, NL_MAX_PAYLOAD);
-      VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_FIFO_READ_BUFFER, 0 );
+    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_FIFO_READ_BUFFER, 0 );
 
-      if (len<=0) continue;
+    if (len<=0) continue;
 
       if (UE_NAS_USE_TUN) {
-        key = PDCP_COLL_KEY_DEFAULT_DRB_VALUE(ctxt.module_id, ctxt.rnti, ctxt.enb_flag);
-        h_rc = hashtable_get(pdcp_coll_p, key, (void **)&pdcp_p);
+    key = PDCP_COLL_KEY_DEFAULT_DRB_VALUE(ctxt.module_id, ctxt.rnti, ctxt.enb_flag);
+      h_rc = hashtable_get(pdcp_coll_p, key, (void **)&pdcp_p);
       } else {
         ctxt.rnti=pdcp_eNB_UE_instance_to_rnti[0];
         ctxt.enb_flag=ENB_FLAG_YES;
@@ -176,594 +176,594 @@ int pdcp_fifo_read_input_sdus (const protocol_ctxt_t *const  ctxt_pP) {
       LOG_D(PDCP, "PDCP_COLL_KEY_DEFAULT_DRB_VALUE(module_id=%d, rnti=%x, enb_flag=%d)\n",
             ctxt.module_id, ctxt.rnti, ctxt.enb_flag);
 
-      if (h_rc == HASH_TABLE_OK) {
-        LOG_D(PDCP, "[FRAME %5u][UE][NETLINK][IP->PDCP] INST %d: Received socket with length %d on Rab %d \n",
-              ctxt.frame, ctxt.instance, len, rab_id);
+    if (h_rc == HASH_TABLE_OK) {
+      LOG_D(PDCP, "[FRAME %5u][UE][NETLINK][IP->PDCP] INST %d: Received socket with length %d on Rab %d \n",
+            ctxt.frame, ctxt.instance, len, rab_id);
         LOG_D(PDCP, "[FRAME %5u][UE][IP][INSTANCE %u][RB %u][--- PDCP_DATA_REQ / %d Bytes --->][PDCP][MOD %u][UE %04x][RB %u]\n",
-              ctxt.frame, ctxt.instance, rab_id, len, ctxt.module_id,
-              ctxt.rnti, rab_id);
-        MSC_LOG_RX_MESSAGE((ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_PDCP_ENB:MSC_PDCP_UE,
-                           (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_IP_ENB:MSC_IP_UE,
-                           NULL, 0,
-                           MSC_AS_TIME_FMT" DATA-REQ inst %u rb %u rab %u size %u",
-                           MSC_AS_TIME_ARGS(ctxt_pP),
-                           ctxt.instance, rab_id, rab_id, len);
-        pdcp_data_req(&ctxt, SRB_FLAG_NO, rab_id, RLC_MUI_UNDEFINED,
-                      RLC_SDU_CONFIRM_NO, len, (unsigned char *)nl_rx_buf,
-                      PDCP_TRANSMISSION_MODE_DATA
-                      , NULL, NULL
-                     );
-      } else {
-        MSC_LOG_RX_DISCARDED_MESSAGE(
-          (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_PDCP_ENB:MSC_PDCP_UE,
-          (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_IP_ENB:MSC_IP_UE,
-          NULL,
-          0,
-          MSC_AS_TIME_FMT" DATA-REQ inst %u rb %u rab %u size %u",
-          MSC_AS_TIME_ARGS(ctxt_pP),
-          ctxt.instance, rab_id, rab_id, len);
-        LOG_D(PDCP,
+            ctxt.frame, ctxt.instance, rab_id, len, ctxt.module_id,
+            ctxt.rnti, rab_id);
+      MSC_LOG_RX_MESSAGE((ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_PDCP_ENB:MSC_PDCP_UE,
+                         (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_IP_ENB:MSC_IP_UE,
+                         NULL, 0,
+                         MSC_AS_TIME_FMT" DATA-REQ inst %u rb %u rab %u size %u",
+                         MSC_AS_TIME_ARGS(ctxt_pP),
+                         ctxt.instance, rab_id, rab_id, len);
+      pdcp_data_req(&ctxt, SRB_FLAG_NO, rab_id, RLC_MUI_UNDEFINED,
+                    RLC_SDU_CONFIRM_NO, len, (unsigned char *)nl_rx_buf,
+                    PDCP_TRANSMISSION_MODE_DATA
+                    , NULL, NULL
+                   );
+    } else {
+      MSC_LOG_RX_DISCARDED_MESSAGE(
+      (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_PDCP_ENB:MSC_PDCP_UE,
+      (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_IP_ENB:MSC_IP_UE,
+      NULL,
+      0,
+      MSC_AS_TIME_FMT" DATA-REQ inst %u rb %u rab %u size %u",
+      MSC_AS_TIME_ARGS(ctxt_pP),
+      ctxt.instance, rab_id, rab_id, len);
+      LOG_D(PDCP,
               "[FRAME %5u][UE][IP][INSTANCE %u][RB %u][--- PDCP_DATA_REQ / %d Bytes ---X][PDCP][MOD %u][UE %04x][RB %u] NON INSTANCIATED INSTANCE key 0x%"PRIx64", DROPPED\n",
-              ctxt.frame, ctxt.instance, rab_id, len, ctxt.module_id,
-              ctxt.rnti, rab_id, key);
-      }
-    } while (len > 0);
+            ctxt.frame, ctxt.instance, rab_id, len, ctxt.module_id,
+            ctxt.rnti, rab_id, key);
+    }
+  } while (len > 0);
 
-    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_FIFO_READ, 0 );
-    return len;
+  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_FIFO_READ, 0 );
+  return len;
   } else { /* UE_NAS_USE_TUN */
     if (PDCP_USE_NETLINK) {
-      protocol_ctxt_t                ctxt_cpy = *ctxt_pP;
-      protocol_ctxt_t                ctxt;
-      hash_key_t                     key       = HASHTABLE_NOT_A_KEY_VALUE;
-      hashtable_rc_t                 h_rc;
+   protocol_ctxt_t                ctxt_cpy = *ctxt_pP;
+   protocol_ctxt_t                ctxt;
+   hash_key_t                     key       = HASHTABLE_NOT_A_KEY_VALUE;
+   hashtable_rc_t                 h_rc;
       struct pdcp_netlink_element_s *data_p    = NULL;
-      /* avoid gcc warnings */
-      (void)data_p;
-      module_id_t                    ue_id     = 0;
+   /* avoid gcc warnings */
+   (void)data_p;
+   module_id_t                    ue_id     = 0;
       pdcp_t                        *pdcp_p    = NULL;
       //TTN for D2D (PC5S)
-      int prose_addr_len;
-      char send_buf[BUFSIZE], receive_buf[BUFSIZE];
-      //int optval;
-      int bytes_received;
-      sidelink_pc5s_element *sl_pc5s_msg_recv = NULL;
-      sidelink_pc5s_element *sl_pc5s_msg_send = NULL;
-      //uint32_t sourceL2Id;
-      //uint32_t groupL2Id;
-      //module_id_t         module_id = 0;
-      pc5s_header_t *pc5s_header;
+   int prose_addr_len;
+   char send_buf[BUFSIZE], receive_buf[BUFSIZE];
+   //int optval;
+   int bytes_received;
+   sidelink_pc5s_element *sl_pc5s_msg_recv = NULL;
+   sidelink_pc5s_element *sl_pc5s_msg_send = NULL;
+   //uint32_t sourceL2Id;
+   //uint32_t groupL2Id;
+   //module_id_t         module_id = 0;
+   pc5s_header_t *pc5s_header;
       static unsigned char pdcp_read_state_g =0;
-      int              len = 1;
-      int  msg_len;
-      rb_id_t          rab_id  = 0;
-      int rlc_data_req_flag = 3;
+   int              len = 1;
+   int  msg_len;
+   rb_id_t          rab_id  = 0;
+   int rlc_data_req_flag = 3;
       //TTN for D2D (PC5S)
-      prose_addr_len = sizeof(prose_pdcp_addr);
-      // receive a message from ProSe App
-      memset(receive_buf, 0, BUFSIZE);
-      bytes_received = recvfrom(pdcp_pc5_sockfd, receive_buf, BUFSIZE, 0,
-                                (struct sockaddr *) &prose_pdcp_addr, (socklen_t *)&prose_addr_len);
-
-      //  if (bytes_received < 0){
-      //    LOG_E(RRC, "ERROR: Failed to receive from ProSe App\n");
-      //    exit(EXIT_FAILURE);
-      // }
-      if (bytes_received > 0) {
-        pc5s_header = calloc(1, sizeof(pc5s_header_t));
-        memcpy((void *)pc5s_header, (void *)receive_buf, sizeof(pc5s_header_t));
+   prose_addr_len = sizeof(prose_pdcp_addr);
+   // receive a message from ProSe App
+   memset(receive_buf, 0, BUFSIZE);
+   bytes_received = recvfrom(pdcp_pc5_sockfd, receive_buf, BUFSIZE, 0,
+         (struct sockaddr *) &prose_pdcp_addr, (socklen_t *)&prose_addr_len);
+
+   //  if (bytes_received < 0){
+   //    LOG_E(RRC, "ERROR: Failed to receive from ProSe App\n");
+   //    exit(EXIT_FAILURE);
+   // }
+   if (bytes_received > 0) {
+      pc5s_header = calloc(1, sizeof(pc5s_header_t));
+      memcpy((void *)pc5s_header, (void *)receive_buf, sizeof(pc5s_header_t));
 
         if (pc5s_header->traffic_type == TRAFFIC_PC5S_SESSION_INIT) {
-          //send reply to ProSe app
-          LOG_D(PDCP,"Received a request to open PDCP socket and establish a new PDCP session ... send response to ProSe App \n");
-          memset(send_buf, 0, BUFSIZE);
-          sl_pc5s_msg_send = calloc(1, sizeof(sidelink_pc5s_element));
-          sl_pc5s_msg_send->pc5s_header.traffic_type = TRAFFIC_PC5S_SESSION_INIT;
-          sl_pc5s_msg_send->pc5sPrimitive.status = 1;
-          memcpy((void *)send_buf, (void *)sl_pc5s_msg_send, sizeof(sidelink_pc5s_element));
-          int prose_addr_len = sizeof(prose_pdcp_addr);
-          int bytes_sent = sendto(pdcp_pc5_sockfd, (char *)send_buf, sizeof(sidelink_pc5s_element), 0, (struct sockaddr *)&prose_pdcp_addr, prose_addr_len);
-
-          if (bytes_sent < 0) {
+         //send reply to ProSe app
+         LOG_D(PDCP,"Received a request to open PDCP socket and establish a new PDCP session ... send response to ProSe App \n");
+         memset(send_buf, 0, BUFSIZE);
+         sl_pc5s_msg_send = calloc(1, sizeof(sidelink_pc5s_element));
+         sl_pc5s_msg_send->pc5s_header.traffic_type = TRAFFIC_PC5S_SESSION_INIT;
+         sl_pc5s_msg_send->pc5sPrimitive.status = 1;
+         memcpy((void *)send_buf, (void *)sl_pc5s_msg_send, sizeof(sidelink_pc5s_element));
+         int prose_addr_len = sizeof(prose_pdcp_addr);
+         int bytes_sent = sendto(pdcp_pc5_sockfd, (char *)send_buf, sizeof(sidelink_pc5s_element), 0, (struct sockaddr *)&prose_pdcp_addr, prose_addr_len);
+
+         if (bytes_sent < 0) {
             LOG_E(PDCP, "ERROR: Failed to send to ProSe App\n");
             exit(EXIT_FAILURE);
-          }
-        } else if (pc5s_header->traffic_type == TRAFFIC_PC5S_SIGNALLING) { //if containing PC5-S message -> send to other UE
-          LOG_D(PDCP,"Received PC5-S message ... send to the other UE\n");
-          LOG_D(PDCP,"Received PC5-S message, traffic_type: %d)\n", pc5s_header->traffic_type);
-          LOG_D(PDCP,"Received PC5-S message, rbid: %d)\n", pc5s_header->rb_id);
-          LOG_D(PDCP,"Received PC5-S message, data_size: %d)\n", pc5s_header->data_size);
-          LOG_D(PDCP,"Received PC5-S message, inst: %d)\n", pc5s_header->inst);
-          LOG_D(PDCP,"Received PC5-S message,sourceL2Id: 0x%08x\n)\n", pc5s_header->sourceL2Id);
-          LOG_D(PDCP,"Received PC5-S message,destinationL1Id: 0x%08x\n)\n", pc5s_header->destinationL2Id);
+         }
+      } else if (pc5s_header->traffic_type == TRAFFIC_PC5S_SIGNALLING) { //if containing PC5-S message -> send to other UE
+         LOG_D(PDCP,"Received PC5-S message ... send to the other UE\n");
+         LOG_D(PDCP,"Received PC5-S message, traffic_type: %d)\n", pc5s_header->traffic_type);
+         LOG_D(PDCP,"Received PC5-S message, rbid: %d)\n", pc5s_header->rb_id);
+         LOG_D(PDCP,"Received PC5-S message, data_size: %d)\n", pc5s_header->data_size);
+         LOG_D(PDCP,"Received PC5-S message, inst: %d)\n", pc5s_header->inst);
+         LOG_D(PDCP,"Received PC5-S message,sourceL2Id: 0x%08x\n)\n", pc5s_header->sourceL2Id);
+         LOG_D(PDCP,"Received PC5-S message,destinationL1Id: 0x%08x\n)\n", pc5s_header->destinationL2Id);
 #ifdef OAI_EMU
 
-          // overwrite function input parameters, because only one netlink socket for all instances
-          if (pc5s_header->inst < oai_emulation.info.nb_enb_local) {
+         // overwrite function input parameters, because only one netlink socket for all instances
+         if (pc5s_header->inst < oai_emulation.info.nb_enb_local) {
             ctxt.frame         = ctxt_cpy.frame;
             ctxt.enb_flag      = ENB_FLAG_YES;
             ctxt.module_id     = pc5s_header.inst  +  oai_emulation.info.first_enb_local;
             ctxt.rnti          = oai_emulation.info.eNB_ue_module_id_to_rnti[ctxt.module_id ][pc5s_header->rb_id / LTE_maxDRB + oai_emulation.info.first_ue_local];
             rab_id    = pc5s_header->rb_id % LTE_maxDRB;
-          } else {
+         } else {
             ctxt.frame         = ctxt_cpy.frame;
             ctxt.enb_flag      = ENB_FLAG_NO;
             ctxt.module_id     = pc5s_header->inst - oai_emulation.info.nb_enb_local + oai_emulation.info.first_ue_local;
             ctxt.rnti          = pdcp_UE_UE_module_id_to_rnti[ctxt.module_id];
             rab_id    = pc5s_header->rb_id % LTE_maxDRB;
-          }
+         }
 
-          CHECK_CTXT_ARGS(&ctxt);
-          AssertFatal (rab_id    < LTE_maxDRB,                       "RB id is too high (%u/%d)!\n", rab_id, LTE_maxDRB);
-          /*LGpdcp_read_header.inst = (pc5s_header.inst >= oai_emulation.info.nb_enb_local) ? \
-                   pc5s_header.inst - oai_emulation.info.nb_enb_local+ NB_eNB_INST + oai_emulation.info.first_ue_local :
-                   pc5s_header.inst +  oai_emulation.info.first_enb_local;*/
+         CHECK_CTXT_ARGS(&ctxt);
+         AssertFatal (rab_id    < LTE_maxDRB,                       "RB id is too high (%u/%d)!\n", rab_id, LTE_maxDRB);
+         /*LGpdcp_read_header.inst = (pc5s_header.inst >= oai_emulation.info.nb_enb_local) ? \
+                  pc5s_header.inst - oai_emulation.info.nb_enb_local+ NB_eNB_INST + oai_emulation.info.first_ue_local :
+                  pc5s_header.inst +  oai_emulation.info.first_enb_local;*/
 #else // OAI_EMU
-          /* TODO: do we have to reset to 0 or not? not for a scenario with 1 UE at least */
-          //          pc5s_header.inst = 0;
-          //#warning "TO DO CORRCT VALUES FOR ue mod id, enb mod id"
-          ctxt.frame         = ctxt_cpy.frame;
-          ctxt.enb_flag      = ctxt_cpy.enb_flag;
-          LOG_I(PDCP, "[PDCP] pc5s_header->rb_id = %d\n", pc5s_header->rb_id);
-
-          if (ctxt_cpy.enb_flag) {
+         /* TODO: do we have to reset to 0 or not? not for a scenario with 1 UE at least */
+         //          pc5s_header.inst = 0;
+         //#warning "TO DO CORRCT VALUES FOR ue mod id, enb mod id"
+         ctxt.frame         = ctxt_cpy.frame;
+         ctxt.enb_flag      = ctxt_cpy.enb_flag;
+         LOG_I(PDCP, "[PDCP] pc5s_header->rb_id = %d\n", pc5s_header->rb_id);
+
+         if (ctxt_cpy.enb_flag) {
             ctxt.module_id = 0;
             rab_id      = pc5s_header->rb_id % LTE_maxDRB;
             ctxt.rnti          = pdcp_eNB_UE_instance_to_rnti[pdcp_eNB_UE_instance_to_rnti_index];
-          } else {
+         } else {
             ctxt.module_id = 0;
             rab_id      = pc5s_header->rb_id % LTE_maxDRB;
             ctxt.rnti          = pdcp_UE_UE_module_id_to_rnti[ctxt.module_id];
-          }
+         }
 
 #endif
 
-          //UE
-          if (!ctxt.enb_flag) {
+         //UE
+         if (!ctxt.enb_flag) {
             if (rab_id != 0) {
-              if (rab_id == UE_IP_DEFAULT_RAB_ID) {
-                LOG_D(PDCP, "PDCP_COLL_KEY_DEFAULT_DRB_VALUE(module_id=%d, rnti=%x, enb_flag=%d)\n",
-                      ctxt.module_id, ctxt.rnti, ctxt.enb_flag);
-                key = PDCP_COLL_KEY_DEFAULT_DRB_VALUE(ctxt.module_id, ctxt.rnti, ctxt.enb_flag);
+               if (rab_id == UE_IP_DEFAULT_RAB_ID) {
+                  LOG_D(PDCP, "PDCP_COLL_KEY_DEFAULT_DRB_VALUE(module_id=%d, rnti=%x, enb_flag=%d)\n",
+                        ctxt.module_id, ctxt.rnti, ctxt.enb_flag);
+                  key = PDCP_COLL_KEY_DEFAULT_DRB_VALUE(ctxt.module_id, ctxt.rnti, ctxt.enb_flag);
                 h_rc = hashtable_get(pdcp_coll_p, key, (void **)&pdcp_p);
-                LOG_D(PDCP,"request key %x : (%d,%x,%d,%d)\n",
-                      (uint8_t)key,ctxt.module_id, ctxt.rnti, ctxt.enb_flag, rab_id);
-              } else {
-                rab_id = rab_id % LTE_maxDRB;
-                LOG_I(PDCP, "PDCP_COLL_KEY_VALUE(module_id=%d, rnti=%x, enb_flag=%d, rab_id=%d, SRB_FLAG=%d)\n",
-                      ctxt.module_id, ctxt.rnti, ctxt.enb_flag, rab_id, SRB_FLAG_NO);
-                key = PDCP_COLL_KEY_VALUE(ctxt.module_id, ctxt.rnti, ctxt.enb_flag, rab_id, SRB_FLAG_NO);
+                  LOG_D(PDCP,"request key %x : (%d,%x,%d,%d)\n",
+                        (uint8_t)key,ctxt.module_id, ctxt.rnti, ctxt.enb_flag, rab_id);
+               } else {
+                  rab_id = rab_id % LTE_maxDRB;
+                  LOG_I(PDCP, "PDCP_COLL_KEY_VALUE(module_id=%d, rnti=%x, enb_flag=%d, rab_id=%d, SRB_FLAG=%d)\n",
+                        ctxt.module_id, ctxt.rnti, ctxt.enb_flag, rab_id, SRB_FLAG_NO);
+                  key = PDCP_COLL_KEY_VALUE(ctxt.module_id, ctxt.rnti, ctxt.enb_flag, rab_id, SRB_FLAG_NO);
                 h_rc = hashtable_get(pdcp_coll_p, key, (void **)&pdcp_p);
-                LOG_I(PDCP,"request key %x : (%d,%x,%d,%d)\n",
-                      (uint8_t)key,ctxt.module_id, ctxt.rnti, ctxt.enb_flag, rab_id);
-              }
-
-              if (h_rc == HASH_TABLE_OK) {
-                rab_id = pdcp_p->rb_id;
-                LOG_I(PDCP, "[FRAME %5u][UE][NETLINK][IP->PDCP] INST %d: Received socket with length %d  on Rab %d \n",
-                      ctxt.frame,
-                      pc5s_header->inst,
-                      bytes_received,
-                      pc5s_header->rb_id);
-                LOG_I(PDCP, "[FRAME %5u][UE][IP][INSTANCE %u][RB %u][--- PDCP_DATA_REQ / %d Bytes --->][PDCP][MOD %u][UE %u][RB %u]\n",
-                      ctxt.frame,
-                      pc5s_header->inst,
-                      pc5s_header->rb_id,
-                      pc5s_header->data_size,
-                      ctxt.module_id,
-                      ctxt.rnti,
-                      rab_id);
-                MSC_LOG_RX_MESSAGE(
-                  (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_PDCP_ENB:MSC_PDCP_UE,
-                  (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_IP_ENB:MSC_IP_UE,
-                  NULL,
-                  0,
-                  MSC_AS_TIME_FMT" DATA-REQ inst %u rb %u rab %u size %u",
-                  MSC_AS_TIME_ARGS(ctxt_pP),
-                  pc5s_header->inst,
-                  pc5s_header->rb_id,
-                  rab_id,
-                  pc5s_header->data_size);
-                pdcp_data_req(
-                  &ctxt,
-                  SRB_FLAG_NO,
-                  rab_id,
-                  RLC_MUI_UNDEFINED,
-                  RLC_SDU_CONFIRM_NO,
-                  pc5s_header->data_size,
-                  (unsigned char *)receive_buf,
+                  LOG_I(PDCP,"request key %x : (%d,%x,%d,%d)\n",
+                		  (uint8_t)key,ctxt.module_id, ctxt.rnti, ctxt.enb_flag, rab_id);
+               }
+
+               if (h_rc == HASH_TABLE_OK) {
+                  rab_id = pdcp_p->rb_id;
+                  LOG_I(PDCP, "[FRAME %5u][UE][NETLINK][IP->PDCP] INST %d: Received socket with length %d  on Rab %d \n",
+                        ctxt.frame,
+                        pc5s_header->inst,
+                        bytes_received,
+                        pc5s_header->rb_id);
+                  LOG_I(PDCP, "[FRAME %5u][UE][IP][INSTANCE %u][RB %u][--- PDCP_DATA_REQ / %d Bytes --->][PDCP][MOD %u][UE %u][RB %u]\n",
+                        ctxt.frame,
+                        pc5s_header->inst,
+                        pc5s_header->rb_id,
+                        pc5s_header->data_size,
+                        ctxt.module_id,
+                        ctxt.rnti,
+                        rab_id);
+                  MSC_LOG_RX_MESSAGE(
+                        (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_PDCP_ENB:MSC_PDCP_UE,
+                              (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_IP_ENB:MSC_IP_UE,
+                                    NULL,
+                                    0,
+                                    MSC_AS_TIME_FMT" DATA-REQ inst %u rb %u rab %u size %u",
+                                    MSC_AS_TIME_ARGS(ctxt_pP),
+                                    pc5s_header->inst,
+                                    pc5s_header->rb_id,
+                                    rab_id,
+                                    pc5s_header->data_size);
+                  pdcp_data_req(
+                        &ctxt,
+                        SRB_FLAG_NO,
+                        rab_id,
+                        RLC_MUI_UNDEFINED,
+                        RLC_SDU_CONFIRM_NO,
+                        pc5s_header->data_size,
+                        (unsigned char *)receive_buf,
                   PDCP_TRANSMISSION_MODE_DATA,
                   &pc5s_header->sourceL2Id,
                   &pc5s_header->destinationL2Id
-                );
-              } else {
-                MSC_LOG_RX_DISCARDED_MESSAGE(
-                  (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_PDCP_ENB:MSC_PDCP_UE,
-                  (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_IP_ENB:MSC_IP_UE,
-                  NULL,
-                  0,
-                  MSC_AS_TIME_FMT" DATA-REQ inst %u rb %u rab %u size %u",
-                  MSC_AS_TIME_ARGS(ctxt_pP),
-                  pc5s_header->inst,
-                  pc5s_header->rb_id,
-                  rab_id,
-                  pc5s_header->data_size);
-                LOG_D(PDCP,
-                      "[FRAME %5u][UE][IP][INSTANCE %u][RB %u][--- PDCP_DATA_REQ / %d Bytes ---X][PDCP][MOD %u][UE %u][RB %u] NON INSTANCIATED INSTANCE key 0x%"PRIx64", DROPPED\n",
-                      ctxt.frame,
-                      pc5s_header->inst,
-                      pc5s_header->rb_id,
-                      pc5s_header->data_size,
-                      ctxt.module_id,
-                      ctxt.rnti,
-                      rab_id,
-                      key);
-              }
+                        );
+               } else {
+                  MSC_LOG_RX_DISCARDED_MESSAGE(
+                        (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_PDCP_ENB:MSC_PDCP_UE,
+                              (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_IP_ENB:MSC_IP_UE,
+                                    NULL,
+                                    0,
+                                    MSC_AS_TIME_FMT" DATA-REQ inst %u rb %u rab %u size %u",
+                                    MSC_AS_TIME_ARGS(ctxt_pP),
+                                    pc5s_header->inst,
+                                    pc5s_header->rb_id,
+                                    rab_id,
+                                    pc5s_header->data_size);
+                  LOG_D(PDCP,
+                        "[FRAME %5u][UE][IP][INSTANCE %u][RB %u][--- PDCP_DATA_REQ / %d Bytes ---X][PDCP][MOD %u][UE %u][RB %u] NON INSTANCIATED INSTANCE key 0x%"PRIx64", DROPPED\n",
+                        ctxt.frame,
+                        pc5s_header->inst,
+                        pc5s_header->rb_id,
+                        pc5s_header->data_size,
+                        ctxt.module_id,
+                        ctxt.rnti,
+                        rab_id,
+                        key);
+               }
             }  else { //if (rab_id == 0)
-              LOG_D(PDCP, "Forcing send on DEFAULT_RAB_ID\n");
-              LOG_D(PDCP, "[FRAME %5u][eNB][IP][INSTANCE %u][RB %u][--- PDCP_DATA_REQ / %d Bytes --->][PDCP][MOD %u][UE %u][RB DEFAULT_RAB_ID %u]\n",
-                    ctxt.frame,
-                    pc5s_header->inst,
-                    pc5s_header->rb_id,
-                    pc5s_header->data_size,
-                    ctxt.module_id,
-                    ctxt.rnti,
-                    DEFAULT_RAB_ID);
-              MSC_LOG_RX_MESSAGE(
-                (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_PDCP_ENB:MSC_PDCP_UE,
-                (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_IP_ENB:MSC_IP_UE,
-                NULL,0,
-                MSC_AS_TIME_FMT" DATA-REQ inst %u rb %u default rab %u size %u",
-                MSC_AS_TIME_ARGS(ctxt_pP),
-                pc5s_header->inst,
-                pc5s_header->rb_id,
-                DEFAULT_RAB_ID,
-                pc5s_header->data_size);
-              pdcp_data_req (
-                &ctxt,
-                SRB_FLAG_NO,
-                DEFAULT_RAB_ID,
-                RLC_MUI_UNDEFINED,
-                RLC_SDU_CONFIRM_NO,
-                pc5s_header->data_size,
-                (unsigned char *)receive_buf,
+               LOG_D(PDCP, "Forcing send on DEFAULT_RAB_ID\n");
+               LOG_D(PDCP, "[FRAME %5u][eNB][IP][INSTANCE %u][RB %u][--- PDCP_DATA_REQ / %d Bytes --->][PDCP][MOD %u][UE %u][RB DEFAULT_RAB_ID %u]\n",
+                     ctxt.frame,
+                     pc5s_header->inst,
+                     pc5s_header->rb_id,
+                     pc5s_header->data_size,
+                     ctxt.module_id,
+                     ctxt.rnti,
+                     DEFAULT_RAB_ID);
+               MSC_LOG_RX_MESSAGE(
+                     (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_PDCP_ENB:MSC_PDCP_UE,
+                           (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_IP_ENB:MSC_IP_UE,
+                                 NULL,0,
+                                 MSC_AS_TIME_FMT" DATA-REQ inst %u rb %u default rab %u size %u",
+                                 MSC_AS_TIME_ARGS(ctxt_pP),
+                                 pc5s_header->inst,
+                                 pc5s_header->rb_id,
+                                 DEFAULT_RAB_ID,
+                                 pc5s_header->data_size);
+               pdcp_data_req (
+                     &ctxt,
+                     SRB_FLAG_NO,
+                     DEFAULT_RAB_ID,
+                     RLC_MUI_UNDEFINED,
+                     RLC_SDU_CONFIRM_NO,
+                     pc5s_header->data_size,
+                     (unsigned char *)receive_buf,
                 PDCP_TRANSMISSION_MODE_DATA,
                 &pc5s_header->sourceL2Id,
                 &pc5s_header->destinationL2Id
-              );
+                     );
             }
-          }
+         }
 
           free (sl_pc5s_msg_recv);
           free (sl_pc5s_msg_send);
-        }
       }
+   }
 
-      while ((len > 0) && (rlc_data_req_flag !=0))  {
-        VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_FIFO_READ, 1 );
-        VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_FIFO_READ_BUFFER, 1 );
+   while ((len > 0) && (rlc_data_req_flag !=0))  {
+      VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_FIFO_READ, 1 );
+      VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_FIFO_READ_BUFFER, 1 );
         len = recvmsg(nas_sock_fd[0], &nas_msg_rx, 0);
-        VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_FIFO_READ_BUFFER, 0 );
+      VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_FIFO_READ_BUFFER, 0 );
 
-        if (len<=0) {
-          // nothing in pdcp NAS socket
-          //LOG_D(PDCP, "[PDCP][NETLINK] Nothing in socket, length %d \n", len);
-        } else {
-          msg_len = len;
+      if (len<=0) {
+         // nothing in pdcp NAS socket
+         //LOG_D(PDCP, "[PDCP][NETLINK] Nothing in socket, length %d \n", len);
+      } else {
+         msg_len = len;
 
-          for (nas_nlh_rx = (struct nlmsghdr *) nl_rx_buf;
+         for (nas_nlh_rx = (struct nlmsghdr *) nl_rx_buf;
                NLMSG_OK (nas_nlh_rx, msg_len);
                nas_nlh_rx = NLMSG_NEXT (nas_nlh_rx, msg_len)) {
             if (nas_nlh_rx->nlmsg_type == NLMSG_DONE) {
-              LOG_D(PDCP, "[PDCP][NETLINK] RX NLMSG_DONE\n");
-              //return;
+               LOG_D(PDCP, "[PDCP][NETLINK] RX NLMSG_DONE\n");
+               //return;
             }
 
             if (nas_nlh_rx->nlmsg_type == NLMSG_ERROR) {
-              LOG_D(PDCP, "[PDCP][NETLINK] RX NLMSG_ERROR\n");
+               LOG_D(PDCP, "[PDCP][NETLINK] RX NLMSG_ERROR\n");
             }
 
             if (pdcp_read_state_g == 0) {
-              if (nas_nlh_rx->nlmsg_len == sizeof (pdcp_data_req_header_t) + sizeof(struct nlmsghdr)) {
-                pdcp_read_state_g = 1;  //get
-                memcpy((void *)&pdcp_read_header_g, (void *)NLMSG_DATA(nas_nlh_rx), sizeof(pdcp_data_req_header_t));
-                LOG_D(PDCP, "[PDCP][NETLINK] RX pdcp_data_req_header_t inst %u, rb_id %u data_size %d, source L2Id 0x%08x, destination L2Id 0x%08x\n",
-                      pdcp_read_header_g.inst, pdcp_read_header_g.rb_id, pdcp_read_header_g.data_size,pdcp_read_header_g.sourceL2Id, pdcp_read_header_g.destinationL2Id );
-              } else {
-                LOG_E(PDCP, "[PDCP][NETLINK] WRONG size %d should be sizeof (pdcp_data_req_header_t) + sizeof(struct nlmsghdr)\n",
-                      nas_nlh_rx->nlmsg_len);
-              }
+               if (nas_nlh_rx->nlmsg_len == sizeof (pdcp_data_req_header_t) + sizeof(struct nlmsghdr)) {
+                  pdcp_read_state_g = 1;  //get
+                  memcpy((void *)&pdcp_read_header_g, (void *)NLMSG_DATA(nas_nlh_rx), sizeof(pdcp_data_req_header_t));
+                  LOG_D(PDCP, "[PDCP][NETLINK] RX pdcp_data_req_header_t inst %u, rb_id %u data_size %d, source L2Id 0x%08x, destination L2Id 0x%08x\n",
+                        pdcp_read_header_g.inst, pdcp_read_header_g.rb_id, pdcp_read_header_g.data_size,pdcp_read_header_g.sourceL2Id, pdcp_read_header_g.destinationL2Id );
+               } else {
+                  LOG_E(PDCP, "[PDCP][NETLINK] WRONG size %d should be sizeof (pdcp_data_req_header_t) + sizeof(struct nlmsghdr)\n",
+                        nas_nlh_rx->nlmsg_len);
+               }
             } else {
-              pdcp_read_state_g = 0;
-              // print_active_requests()
-              LOG_D(PDCP, "[PDCP][NETLINK] Something in socket, length %zu\n",
-                    nas_nlh_rx->nlmsg_len - sizeof(struct nlmsghdr));
+               pdcp_read_state_g = 0;
+               // print_active_requests()
+               LOG_D(PDCP, "[PDCP][NETLINK] Something in socket, length %zu\n",
+                     nas_nlh_rx->nlmsg_len - sizeof(struct nlmsghdr));
 #ifdef OAI_EMU
 
-              // overwrite function input parameters, because only one netlink socket for all instances
-              if (pdcp_read_header_g.inst < oai_emulation.info.nb_enb_local) {
-                ctxt.frame         = ctxt_cpy.frame;
-                ctxt.enb_flag      = ENB_FLAG_YES;
-                ctxt.module_id     = pdcp_read_header_g.inst  +  oai_emulation.info.first_enb_local;
-                ctxt.rnti          = oai_emulation.info.eNB_ue_module_id_to_rnti[ctxt.module_id ][pdcp_read_header_g.rb_id / LTE_maxDRB + oai_emulation.info.first_ue_local];
-                rab_id    = pdcp_read_header_g.rb_id % LTE_maxDRB;
-              } else {
-                ctxt.frame         = ctxt_cpy.frame;
-                ctxt.enb_flag      = ENB_FLAG_NO;
-                ctxt.module_id     = pdcp_read_header_g.inst - oai_emulation.info.nb_enb_local + oai_emulation.info.first_ue_local;
-                ctxt.rnti          = pdcp_UE_UE_module_id_to_rnti[ctxt.module_id];
-                rab_id    = pdcp_read_header_g.rb_id % LTE_maxDRB;
-              }
-
-              CHECK_CTXT_ARGS(&ctxt);
-              AssertFatal (rab_id    < LTE_maxDRB,                       "RB id is too high (%u/%d)!\n", rab_id, LTE_maxDRB);
+               // overwrite function input parameters, because only one netlink socket for all instances
+               if (pdcp_read_header_g.inst < oai_emulation.info.nb_enb_local) {
+                  ctxt.frame         = ctxt_cpy.frame;
+                  ctxt.enb_flag      = ENB_FLAG_YES;
+                  ctxt.module_id     = pdcp_read_header_g.inst  +  oai_emulation.info.first_enb_local;
+                  ctxt.rnti          = oai_emulation.info.eNB_ue_module_id_to_rnti[ctxt.module_id ][pdcp_read_header_g.rb_id / LTE_maxDRB + oai_emulation.info.first_ue_local];
+                  rab_id    = pdcp_read_header_g.rb_id % LTE_maxDRB;
+               } else {
+                  ctxt.frame         = ctxt_cpy.frame;
+                  ctxt.enb_flag      = ENB_FLAG_NO;
+                  ctxt.module_id     = pdcp_read_header_g.inst - oai_emulation.info.nb_enb_local + oai_emulation.info.first_ue_local;
+                  ctxt.rnti          = pdcp_UE_UE_module_id_to_rnti[ctxt.module_id];
+                  rab_id    = pdcp_read_header_g.rb_id % LTE_maxDRB;
+               }
+
+               CHECK_CTXT_ARGS(&ctxt);
+               AssertFatal (rab_id    < LTE_maxDRB,                       "RB id is too high (%u/%d)!\n", rab_id, LTE_maxDRB);
 #else // OAI_EMU
-              /* TODO: do we have to reset to 0 or not? not for a scenario with 1 UE at least */
-              //          pdcp_read_header_g.inst = 0;
-              //#warning "TO DO CORRCT VALUES FOR ue mod id, enb mod id"
-              ctxt.frame         = ctxt_cpy.frame;
-              ctxt.enb_flag      = ctxt_cpy.enb_flag;
+               /* TODO: do we have to reset to 0 or not? not for a scenario with 1 UE at least */
+               //          pdcp_read_header_g.inst = 0;
+               //#warning "TO DO CORRCT VALUES FOR ue mod id, enb mod id"
+               ctxt.frame         = ctxt_cpy.frame;
+               ctxt.enb_flag      = ctxt_cpy.enb_flag;
               LOG_D(PDCP, "[PDCP][NETLINK] pdcp_read_header_g.rb_id = %d, source L2Id = 0x%08x, destination L2Id = 0x%08x \n", pdcp_read_header_g.rb_id, pdcp_read_header_g.sourceL2Id,
                     pdcp_read_header_g.destinationL2Id);
 
-              if (ctxt_cpy.enb_flag) {
-                ctxt.module_id = 0;
-                rab_id      = pdcp_read_header_g.rb_id % LTE_maxDRB;
-                ctxt.rnti          = pdcp_eNB_UE_instance_to_rnti[pdcp_read_header_g.rb_id / LTE_maxDRB];
-              } else {
-                if (nfapi_mode == 3) {
+          if (ctxt_cpy.enb_flag) {
+            ctxt.module_id = 0;
+            rab_id      = pdcp_read_header_g.rb_id % LTE_maxDRB;
+            ctxt.rnti          = pdcp_eNB_UE_instance_to_rnti[pdcp_read_header_g.rb_id / LTE_maxDRB];
+          } else {
+            if (nfapi_mode == 3) {
 #ifdef UESIM_EXPANSION
-                  ctxt.module_id = inst_pdcp_list[pdcp_read_header_g.inst];
+              ctxt.module_id = inst_pdcp_list[pdcp_read_header_g.inst];
 #else
-                  ctxt.module_id = pdcp_read_header_g.inst;
+              ctxt.module_id = pdcp_read_header_g.inst;
 #endif
-                } else {
-                  ctxt.module_id = 0;
-                }
+            } else {
+              ctxt.module_id = 0;
+            }
 
-                rab_id      = pdcp_read_header_g.rb_id % LTE_maxDRB;
-                ctxt.rnti          = pdcp_UE_UE_module_id_to_rnti[ctxt.module_id];
-              }
+            rab_id      = pdcp_read_header_g.rb_id % LTE_maxDRB;
+            ctxt.rnti          = pdcp_UE_UE_module_id_to_rnti[ctxt.module_id];
+          }
 
 #endif
 
-              if (ctxt.enb_flag) {
-                if (rab_id != 0) {
-                  rab_id = rab_id % LTE_maxDRB;
-                  key = PDCP_COLL_KEY_VALUE(ctxt.module_id, ctxt.rnti, ctxt.enb_flag, rab_id, SRB_FLAG_NO);
+          if (ctxt.enb_flag) {
+            if (rab_id != 0) {
+              rab_id = rab_id % LTE_maxDRB;
+              key = PDCP_COLL_KEY_VALUE(ctxt.module_id, ctxt.rnti, ctxt.enb_flag, rab_id, SRB_FLAG_NO);
                   h_rc = hashtable_get(pdcp_coll_p, key, (void **)&pdcp_p);
 
-                  if (h_rc == HASH_TABLE_OK) {
-                    LOG_D(PDCP, "[FRAME %5u][eNB][NETLINK][IP->PDCP] INST %d: Received socket with length %d (nlmsg_len = %zu) on Rab %d \n",
-                          ctxt.frame,
-                          pdcp_read_header_g.inst,
-                          len,
-                          nas_nlh_rx->nlmsg_len-sizeof(struct nlmsghdr),
-                          pdcp_read_header_g.rb_id);
-                    MSC_LOG_RX_MESSAGE(
-                      (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_PDCP_ENB:MSC_PDCP_UE,
-                      (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_IP_ENB:MSC_IP_UE,
-                      NULL,
-                      0,
-                      MSC_AS_TIME_FMT" DATA-REQ inst %u rb %u rab %u size %u",
-                      MSC_AS_TIME_ARGS(ctxt_pP),
-                      pdcp_read_header_g.inst,
-                      pdcp_read_header_g.rb_id,
-                      rab_id,
-                      pdcp_read_header_g.data_size);
-                    LOG_D(PDCP, "[FRAME %5u][eNB][IP][INSTANCE %u][RB %u][--- PDCP_DATA_REQ / %d Bytes --->][PDCP][MOD %u]UE %u][RB %u]\n",
-                          ctxt_cpy.frame,
-                          pdcp_read_header_g.inst,
-                          pdcp_read_header_g.rb_id,
-                          pdcp_read_header_g.data_size,
-                          ctxt.module_id,
-                          ctxt.rnti,
-                          rab_id);
-                    pdcp_data_req(&ctxt,
-                                  SRB_FLAG_NO,
-                                  rab_id,
-                                  RLC_MUI_UNDEFINED,
-                                  RLC_SDU_CONFIRM_NO,
-                                  pdcp_read_header_g.data_size,
-                                  (unsigned char *)NLMSG_DATA(nas_nlh_rx),
-                                  PDCP_TRANSMISSION_MODE_DATA
-                                  ,NULL, NULL
-                                 );
-                  } else {
-                    LOG_D(PDCP, "[FRAME %5u][eNB][IP][INSTANCE %u][RB %u][--- PDCP_DATA_REQ / %d Bytes ---X][PDCP][MOD %u][UE %u][RB %u] NON INSTANCIATED INSTANCE, DROPPED\n",
-                          ctxt.frame,
-                          pdcp_read_header_g.inst,
-                          pdcp_read_header_g.rb_id,
-                          pdcp_read_header_g.data_size,
-                          ctxt.module_id,
-                          ctxt.rnti,
-                          rab_id);
+                     if (h_rc == HASH_TABLE_OK) {
+                        LOG_D(PDCP, "[FRAME %5u][eNB][NETLINK][IP->PDCP] INST %d: Received socket with length %d (nlmsg_len = %zu) on Rab %d \n",
+                              ctxt.frame,
+                              pdcp_read_header_g.inst,
+                              len,
+                              nas_nlh_rx->nlmsg_len-sizeof(struct nlmsghdr),
+                              pdcp_read_header_g.rb_id);
+                        MSC_LOG_RX_MESSAGE(
+                              (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_PDCP_ENB:MSC_PDCP_UE,
+                                    (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_IP_ENB:MSC_IP_UE,
+                                          NULL,
+                                          0,
+                                          MSC_AS_TIME_FMT" DATA-REQ inst %u rb %u rab %u size %u",
+                                          MSC_AS_TIME_ARGS(ctxt_pP),
+                                          pdcp_read_header_g.inst,
+                                          pdcp_read_header_g.rb_id,
+                                          rab_id,
+                                          pdcp_read_header_g.data_size);
+                        LOG_D(PDCP, "[FRAME %5u][eNB][IP][INSTANCE %u][RB %u][--- PDCP_DATA_REQ / %d Bytes --->][PDCP][MOD %u]UE %u][RB %u]\n",
+                              ctxt_cpy.frame,
+                              pdcp_read_header_g.inst,
+                              pdcp_read_header_g.rb_id,
+                              pdcp_read_header_g.data_size,
+                              ctxt.module_id,
+                              ctxt.rnti,
+                              rab_id);
+                        pdcp_data_req(&ctxt,
+                              SRB_FLAG_NO,
+                              rab_id,
+                              RLC_MUI_UNDEFINED,
+                              RLC_SDU_CONFIRM_NO,
+                              pdcp_read_header_g.data_size,
+                              (unsigned char *)NLMSG_DATA(nas_nlh_rx),
+                              PDCP_TRANSMISSION_MODE_DATA
+                              ,NULL, NULL
+                              );
+                     } else {
+                        LOG_D(PDCP, "[FRAME %5u][eNB][IP][INSTANCE %u][RB %u][--- PDCP_DATA_REQ / %d Bytes ---X][PDCP][MOD %u][UE %u][RB %u] NON INSTANCIATED INSTANCE, DROPPED\n",
+                              ctxt.frame,
+                              pdcp_read_header_g.inst,
+                              pdcp_read_header_g.rb_id,
+                              pdcp_read_header_g.data_size,
+                              ctxt.module_id,
+                              ctxt.rnti,
+                              rab_id);
+                     }
+                  } else  { // rb_id =0, thus interpreated as broadcast and transported as multiple unicast
+                     // is a broadcast packet, we have to send this packet on all default RABS of all connected UEs
+                     //#warning CODE TO BE REVIEWED, ONLY WORK FOR SIMPLE TOPOLOGY CASES
+                     for (ue_id = 0; ue_id < NB_UE_INST; ue_id++) {
+                        if (oai_emulation.info.eNB_ue_module_id_to_rnti[ctxt_cpy.module_id][ue_id] != NOT_A_RNTI) {
+                           ctxt.rnti = oai_emulation.info.eNB_ue_module_id_to_rnti[ctxt_cpy.module_id][ue_id];
+                           LOG_D(PDCP, "[FRAME %5u][eNB][IP][INSTANCE %u][RB %u][--- PDCP_DATA_REQ / %d Bytes --->][PDCP][MOD %u][UE %u][RB DEFAULT_RAB_ID %u]\n",
+                                 ctxt.frame,
+                                 pdcp_read_header_g.inst,
+                                 pdcp_read_header_g.rb_id,
+                                 pdcp_read_header_g.data_size,
+                                 ctxt.module_id,
+                                 ctxt.rnti,
+                                 DEFAULT_RAB_ID);
+                           pdcp_data_req (
+                                 &ctxt,
+                                 SRB_FLAG_NO,
+                                 DEFAULT_RAB_ID,
+                                 RLC_MUI_UNDEFINED,
+                                 RLC_SDU_CONFIRM_NO,
+                                 pdcp_read_header_g.data_size,
+                                 (unsigned char *)NLMSG_DATA(nas_nlh_rx),
+                                 PDCP_TRANSMISSION_MODE_DATA
+                                ,NULL, NULL
+                                );
+                        }
+                     }
                   }
-                } else  { // rb_id =0, thus interpreated as broadcast and transported as multiple unicast
-                  // is a broadcast packet, we have to send this packet on all default RABS of all connected UEs
-                  //#warning CODE TO BE REVIEWED, ONLY WORK FOR SIMPLE TOPOLOGY CASES
-                  for (ue_id = 0; ue_id < NB_UE_INST; ue_id++) {
-                    if (oai_emulation.info.eNB_ue_module_id_to_rnti[ctxt_cpy.module_id][ue_id] != NOT_A_RNTI) {
-                      ctxt.rnti = oai_emulation.info.eNB_ue_module_id_to_rnti[ctxt_cpy.module_id][ue_id];
-                      LOG_D(PDCP, "[FRAME %5u][eNB][IP][INSTANCE %u][RB %u][--- PDCP_DATA_REQ / %d Bytes --->][PDCP][MOD %u][UE %u][RB DEFAULT_RAB_ID %u]\n",
-                            ctxt.frame,
-                            pdcp_read_header_g.inst,
-                            pdcp_read_header_g.rb_id,
-                            pdcp_read_header_g.data_size,
-                            ctxt.module_id,
-                            ctxt.rnti,
-                            DEFAULT_RAB_ID);
-                      pdcp_data_req (
-                        &ctxt,
-                        SRB_FLAG_NO,
-                        DEFAULT_RAB_ID,
-                        RLC_MUI_UNDEFINED,
-                        RLC_SDU_CONFIRM_NO,
-                        pdcp_read_header_g.data_size,
-                        (unsigned char *)NLMSG_DATA(nas_nlh_rx),
-                        PDCP_TRANSMISSION_MODE_DATA
-                        ,NULL, NULL
-                      );
-                    }
-                  }
-                }
-              } else { // enb_flag
-                if (rab_id != 0) {
-                  if (rab_id == UE_IP_DEFAULT_RAB_ID) {
-                    LOG_D(PDCP, "PDCP_COLL_KEY_DEFAULT_DRB_VALUE(module_id=%d, rnti=%x, enb_flag=%d)\n",
-                          ctxt.module_id, ctxt.rnti, ctxt.enb_flag);
-                    key = PDCP_COLL_KEY_DEFAULT_DRB_VALUE(ctxt.module_id, ctxt.rnti, ctxt.enb_flag);
+               } else { // enb_flag
+                  if (rab_id != 0) {
+                     if (rab_id == UE_IP_DEFAULT_RAB_ID) {
+                        LOG_D(PDCP, "PDCP_COLL_KEY_DEFAULT_DRB_VALUE(module_id=%d, rnti=%x, enb_flag=%d)\n",
+                              ctxt.module_id, ctxt.rnti, ctxt.enb_flag);
+                        key = PDCP_COLL_KEY_DEFAULT_DRB_VALUE(ctxt.module_id, ctxt.rnti, ctxt.enb_flag);
                     h_rc = hashtable_get(pdcp_coll_p, key, (void **)&pdcp_p);
-                    LOG_D(PDCP,"request key %x : (%d,%x,%d,%d)\n",
-                          (uint8_t)key,ctxt.module_id, ctxt.rnti, ctxt.enb_flag, rab_id);
-                  } else {
-                    rab_id = rab_id % LTE_maxDRB;
-                    LOG_D(PDCP, "PDCP_COLL_KEY_VALUE(module_id=%d, rnti=%x, enb_flag=%d, rab_id=%d, SRB_FLAG=%d)\n",
-                          ctxt.module_id, ctxt.rnti, ctxt.enb_flag, rab_id, SRB_FLAG_NO);
-                    key = PDCP_COLL_KEY_VALUE(ctxt.module_id, ctxt.rnti, ctxt.enb_flag, rab_id, SRB_FLAG_NO);
+                        LOG_D(PDCP,"request key %x : (%d,%x,%d,%d)\n",
+                        		(uint8_t)key,ctxt.module_id, ctxt.rnti, ctxt.enb_flag, rab_id);
+                     } else {
+                        rab_id = rab_id % LTE_maxDRB;
+                        LOG_D(PDCP, "PDCP_COLL_KEY_VALUE(module_id=%d, rnti=%x, enb_flag=%d, rab_id=%d, SRB_FLAG=%d)\n",
+                              ctxt.module_id, ctxt.rnti, ctxt.enb_flag, rab_id, SRB_FLAG_NO);
+                        key = PDCP_COLL_KEY_VALUE(ctxt.module_id, ctxt.rnti, ctxt.enb_flag, rab_id, SRB_FLAG_NO);
                     h_rc = hashtable_get(pdcp_coll_p, key, (void **)&pdcp_p);
-                    LOG_D(PDCP,"request key %x : (%d,%x,%d,%d)\n",
-                          (uint8_t)key,ctxt.module_id, ctxt.rnti, ctxt.enb_flag, rab_id);
-                  }
-
-                  if (h_rc == HASH_TABLE_OK) {
-                    rab_id = pdcp_p->rb_id;
-                    LOG_D(PDCP, "[FRAME %5u][UE][NETLINK][IP->PDCP] INST %d: Received socket with length %d (nlmsg_len = %zu) on Rab %d \n",
-                          ctxt.frame,
-                          pdcp_read_header_g.inst,
-                          len,
-                          nas_nlh_rx->nlmsg_len-sizeof(struct nlmsghdr),
-                          pdcp_read_header_g.rb_id);
-                    LOG_D(PDCP, "[FRAME %5u][UE][IP][INSTANCE %u][RB %u][--- PDCP_DATA_REQ / %d Bytes --->][PDCP][MOD %u][UE %u][RB %u]\n",
-                          ctxt.frame,
-                          pdcp_read_header_g.inst,
-                          pdcp_read_header_g.rb_id,
-                          pdcp_read_header_g.data_size,
-                          ctxt.module_id,
-                          ctxt.rnti,
-                          rab_id);
-                    MSC_LOG_RX_MESSAGE(
-                      (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_PDCP_ENB:MSC_PDCP_UE,
-                      (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_IP_ENB:MSC_IP_UE,
-                      NULL,
-                      0,
-                      MSC_AS_TIME_FMT" DATA-REQ inst %u rb %u rab %u size %u",
-                      MSC_AS_TIME_ARGS(ctxt_pP),
-                      pdcp_read_header_g.inst,
-                      pdcp_read_header_g.rb_id,
-                      rab_id,
-                      pdcp_read_header_g.data_size);
+                        LOG_D(PDCP,"request key %x : (%d,%x,%d,%d)\n",
+                        		(uint8_t)key,ctxt.module_id, ctxt.rnti, ctxt.enb_flag, rab_id);
+                     }
+
+                     if (h_rc == HASH_TABLE_OK) {
+                        rab_id = pdcp_p->rb_id;
+                        LOG_D(PDCP, "[FRAME %5u][UE][NETLINK][IP->PDCP] INST %d: Received socket with length %d (nlmsg_len = %zu) on Rab %d \n",
+                              ctxt.frame,
+                              pdcp_read_header_g.inst,
+                              len,
+                              nas_nlh_rx->nlmsg_len-sizeof(struct nlmsghdr),
+                              pdcp_read_header_g.rb_id);
+                        LOG_D(PDCP, "[FRAME %5u][UE][IP][INSTANCE %u][RB %u][--- PDCP_DATA_REQ / %d Bytes --->][PDCP][MOD %u][UE %u][RB %u]\n",
+                              ctxt.frame,
+                              pdcp_read_header_g.inst,
+                              pdcp_read_header_g.rb_id,
+                              pdcp_read_header_g.data_size,
+                              ctxt.module_id,
+                              ctxt.rnti,
+                              rab_id);
+                        MSC_LOG_RX_MESSAGE(
+                              (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_PDCP_ENB:MSC_PDCP_UE,
+                                    (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_IP_ENB:MSC_IP_UE,
+                                          NULL,
+                                          0,
+                                          MSC_AS_TIME_FMT" DATA-REQ inst %u rb %u rab %u size %u",
+                                          MSC_AS_TIME_ARGS(ctxt_pP),
+                                          pdcp_read_header_g.inst,
+                                          pdcp_read_header_g.rb_id,
+                                          rab_id,
+                                          pdcp_read_header_g.data_size);
 
                     if(nfapi_mode == 3) {
-                      pdcp_data_req(
-                        &ctxt,
-                        SRB_FLAG_NO,
-                        rab_id,
-                        RLC_MUI_UNDEFINED,
-                        RLC_SDU_CONFIRM_NO,
-                        pdcp_read_header_g.data_size,
-                        (unsigned char *)NLMSG_DATA(nas_nlh_rx),
+                        pdcp_data_req(
+                              &ctxt,
+                              SRB_FLAG_NO,
+                              rab_id,
+                              RLC_MUI_UNDEFINED,
+                              RLC_SDU_CONFIRM_NO,
+                              pdcp_read_header_g.data_size,
+                              (unsigned char *)NLMSG_DATA(nas_nlh_rx),
                         PDCP_TRANSMISSION_MODE_DATA,
                         NULL,
                         NULL
-                      );
+                              );
                     } else {
-                      pdcp_data_req(
-                        &ctxt,
-                        SRB_FLAG_NO,
-                        rab_id,
-                        RLC_MUI_UNDEFINED,
-                        RLC_SDU_CONFIRM_NO,
-                        pdcp_read_header_g.data_size,
-                        (unsigned char *)NLMSG_DATA(nas_nlh_rx),
+                        pdcp_data_req(
+                              &ctxt,
+                              SRB_FLAG_NO,
+                              rab_id,
+                              RLC_MUI_UNDEFINED,
+                              RLC_SDU_CONFIRM_NO,
+                              pdcp_read_header_g.data_size,
+                              (unsigned char *)NLMSG_DATA(nas_nlh_rx),
                         PDCP_TRANSMISSION_MODE_DATA,
                         &pdcp_read_header_g.sourceL2Id,
                         &pdcp_read_header_g.destinationL2Id
-                      );
-                    }
-                  } else {
-                    MSC_LOG_RX_DISCARDED_MESSAGE(
-                      (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_PDCP_ENB:MSC_PDCP_UE,
-                      (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_IP_ENB:MSC_IP_UE,
-                      NULL,
-                      0,
-                      MSC_AS_TIME_FMT" DATA-REQ inst %u rb %u rab %u size %u",
-                      MSC_AS_TIME_ARGS(ctxt_pP),
-                      pdcp_read_header_g.inst,
-                      pdcp_read_header_g.rb_id,
-                      rab_id,
-                      pdcp_read_header_g.data_size);
-                    LOG_D(PDCP,
-                          "[FRAME %5u][UE][IP][INSTANCE %u][RB %u][--- PDCP_DATA_REQ / %d Bytes ---X][PDCP][MOD %u][UE %u][RB %u] NON INSTANCIATED INSTANCE key 0x%"PRIx64", DROPPED\n",
-                          ctxt.frame,
-                          pdcp_read_header_g.inst,
-                          pdcp_read_header_g.rb_id,
-                          pdcp_read_header_g.data_size,
-                          ctxt.module_id,
-                          ctxt.rnti,
-                          rab_id,
-                          key);
-                  }
-                }  else {
-                  LOG_D(PDCP, "Forcing send on DEFAULT_RAB_ID\n");
-                  LOG_D(PDCP, "[FRAME %5u][eNB][IP][INSTANCE %u][RB %u][--- PDCP_DATA_REQ / %d Bytes --->][PDCP][MOD %u][UE %u][RB DEFAULT_RAB_ID %u]\n",
-                        ctxt.frame,
-                        pdcp_read_header_g.inst,
-                        pdcp_read_header_g.rb_id,
-                        pdcp_read_header_g.data_size,
-                        ctxt.module_id,
-                        ctxt.rnti,
-                        DEFAULT_RAB_ID);
-                  MSC_LOG_RX_MESSAGE(
-                    (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_PDCP_ENB:MSC_PDCP_UE,
-                    (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_IP_ENB:MSC_IP_UE,
-                    NULL,0,
-                    MSC_AS_TIME_FMT" DATA-REQ inst %u rb %u default rab %u size %u",
-                    MSC_AS_TIME_ARGS(ctxt_pP),
-                    pdcp_read_header_g.inst,
-                    pdcp_read_header_g.rb_id,
-                    DEFAULT_RAB_ID,
-                    pdcp_read_header_g.data_size);
+                              );
+                        }
+                     } else {
+                        MSC_LOG_RX_DISCARDED_MESSAGE(
+                              (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_PDCP_ENB:MSC_PDCP_UE,
+                                    (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_IP_ENB:MSC_IP_UE,
+                                          NULL,
+                                          0,
+                                          MSC_AS_TIME_FMT" DATA-REQ inst %u rb %u rab %u size %u",
+                                          MSC_AS_TIME_ARGS(ctxt_pP),
+                                          pdcp_read_header_g.inst,
+                                          pdcp_read_header_g.rb_id,
+                                          rab_id,
+                                          pdcp_read_header_g.data_size);
+                        LOG_D(PDCP,
+                              "[FRAME %5u][UE][IP][INSTANCE %u][RB %u][--- PDCP_DATA_REQ / %d Bytes ---X][PDCP][MOD %u][UE %u][RB %u] NON INSTANCIATED INSTANCE key 0x%"PRIx64", DROPPED\n",
+                              ctxt.frame,
+                              pdcp_read_header_g.inst,
+                              pdcp_read_header_g.rb_id,
+                              pdcp_read_header_g.data_size,
+                              ctxt.module_id,
+                              ctxt.rnti,
+                              rab_id,
+                              key);
+                     }
+                  }  else {
+                     LOG_D(PDCP, "Forcing send on DEFAULT_RAB_ID\n");
+                     LOG_D(PDCP, "[FRAME %5u][eNB][IP][INSTANCE %u][RB %u][--- PDCP_DATA_REQ / %d Bytes --->][PDCP][MOD %u][UE %u][RB DEFAULT_RAB_ID %u]\n",
+                           ctxt.frame,
+                           pdcp_read_header_g.inst,
+                           pdcp_read_header_g.rb_id,
+                           pdcp_read_header_g.data_size,
+                           ctxt.module_id,
+                           ctxt.rnti,
+                           DEFAULT_RAB_ID);
+                     MSC_LOG_RX_MESSAGE(
+                           (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_PDCP_ENB:MSC_PDCP_UE,
+                                 (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_IP_ENB:MSC_IP_UE,
+                                       NULL,0,
+                                       MSC_AS_TIME_FMT" DATA-REQ inst %u rb %u default rab %u size %u",
+                                       MSC_AS_TIME_ARGS(ctxt_pP),
+                                       pdcp_read_header_g.inst,
+                                       pdcp_read_header_g.rb_id,
+                                       DEFAULT_RAB_ID,
+                                       pdcp_read_header_g.data_size);
 
                   if(nfapi_mode == 3) {
-                    pdcp_data_req (
-                      &ctxt,
-                      SRB_FLAG_NO,
-                      DEFAULT_RAB_ID,
-                      RLC_MUI_UNDEFINED,
-                      RLC_SDU_CONFIRM_NO,
-                      pdcp_read_header_g.data_size,
-                      (unsigned char *)NLMSG_DATA(nas_nlh_rx),
+                     pdcp_data_req (
+                           &ctxt,
+                           SRB_FLAG_NO,
+                           DEFAULT_RAB_ID,
+                           RLC_MUI_UNDEFINED,
+                           RLC_SDU_CONFIRM_NO,
+                           pdcp_read_header_g.data_size,
+                           (unsigned char *)NLMSG_DATA(nas_nlh_rx),
                       PDCP_TRANSMISSION_MODE_DATA,
                       NULL,
                       NULL
-                    );
+                               );
                   } else {
-                    pdcp_data_req (
-                      &ctxt,
-                      SRB_FLAG_NO,
-                      DEFAULT_RAB_ID,
-                      RLC_MUI_UNDEFINED,
-                      RLC_SDU_CONFIRM_NO,
-                      pdcp_read_header_g.data_size,
-                      (unsigned char *)NLMSG_DATA(nas_nlh_rx),
+                     pdcp_data_req (
+                           &ctxt,
+                           SRB_FLAG_NO,
+                           DEFAULT_RAB_ID,
+                           RLC_MUI_UNDEFINED,
+                           RLC_SDU_CONFIRM_NO,
+                           pdcp_read_header_g.data_size,
+                           (unsigned char *)NLMSG_DATA(nas_nlh_rx),
                       PDCP_TRANSMISSION_MODE_DATA,
                       &pdcp_read_header_g.sourceL2Id,
                       &pdcp_read_header_g.destinationL2Id
-                    );
+                           );
+                     }
                   }
-                }
-              }
+               }
             }
-          }
-        }
-
-        VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_FIFO_READ, 0 );
+         }
       }
 
-      return len;
+      VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_FIFO_READ, 0 );
+   }
+
+   return len;
     } else { /* PDCP_USE_NETLINK */
-      return 0;
+   return 0;
     } // else PDCP_USE_NETLINK
   } /* #else UE_NAS_USE_TUN */
 }
@@ -790,36 +790,37 @@ void pdcp_fifo_read_input_sdus_from_otg (const protocol_ctxt_t *const  ctxt_pP)
   }
 }
 
+
 //TTN for D2D (PC5S)
 
 void
 pdcp_pc5_socket_init() {
-  //pthread_attr_t     attr;
-  //struct sched_param sched_param;
-  int optval; // flag value for setsockopt
-  //int n; // message byte size
-  //create PDCP socket
-  pdcp_pc5_sockfd = socket(AF_INET, SOCK_DGRAM, 0);
+	//pthread_attr_t     attr;
+   //struct sched_param sched_param;
+   int optval; // flag value for setsockopt
+   //int n; // message byte size
+   //create PDCP socket
+   pdcp_pc5_sockfd = socket(AF_INET, SOCK_DGRAM, 0);
 
   if (pdcp_pc5_sockfd < 0) {
-    LOG_E(PDCP,"[pdcp_pc5_socket_init] Error opening socket %d (%d:%s)\n",pdcp_pc5_sockfd,errno, strerror(errno));
-    exit(EXIT_FAILURE);
-  }
+      LOG_E(PDCP,"[pdcp_pc5_socket_init] Error opening socket %d (%d:%s)\n",pdcp_pc5_sockfd,errno, strerror(errno));
+      exit(EXIT_FAILURE);
+   }
 
-  optval = 1;
-  setsockopt(pdcp_pc5_sockfd, SOL_SOCKET, SO_REUSEADDR,
+   optval = 1;
+   setsockopt(pdcp_pc5_sockfd, SOL_SOCKET, SO_REUSEADDR,
              (const void *)&optval, sizeof(int));
-  fcntl(pdcp_pc5_sockfd,F_SETFL,O_NONBLOCK);
-  bzero((char *) &pdcp_sin, sizeof(pdcp_sin));
-  pdcp_sin.sin_family = AF_INET;
-  pdcp_sin.sin_addr.s_addr = htonl(INADDR_ANY);
-  pdcp_sin.sin_port = htons(PDCP_SOCKET_PORT_NO);
-
-  // associate the parent socket with a port
-  if (bind(pdcp_pc5_sockfd, (struct sockaddr *) &pdcp_sin,
-           sizeof(pdcp_sin)) < 0) {
-    LOG_E(PDCP,"[pdcp_pc5_socket_init] ERROR: Failed on binding the socket\n");
-    exit(1);
-  }
+   fcntl(pdcp_pc5_sockfd,F_SETFL,O_NONBLOCK);
+   bzero((char *) &pdcp_sin, sizeof(pdcp_sin));
+   pdcp_sin.sin_family = AF_INET;
+   pdcp_sin.sin_addr.s_addr = htonl(INADDR_ANY);
+   pdcp_sin.sin_port = htons(PDCP_SOCKET_PORT_NO);
+
+   // associate the parent socket with a port
+   if (bind(pdcp_pc5_sockfd, (struct sockaddr *) &pdcp_sin,
+         sizeof(pdcp_sin)) < 0) {
+      LOG_E(PDCP,"[pdcp_pc5_socket_init] ERROR: Failed on binding the socket\n");
+      exit(1);
+   }
 }
 
diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp_security.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp_security.c
index 1528373e9883f9bab3e8faee3e605576b58df036..a18713fbb67a32c94a91a922e47f7e7f67657310 100644
--- a/openair2/LAYER2/PDCP_v10.1.0/pdcp_security.c
+++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp_security.c
@@ -228,8 +228,8 @@ pdcp_validate_security(
     	  " Security: failed MAC-I Algo %X UE %"PRIx16" ",
     	  pdcp_pP->integrityProtAlgorithm,
     	  ctxt_pP->rnti);
-      LOG_E(PDCP, "[OSA][RB %d] %s failed to validate MAC-I of incoming PDU\n",
-            rb_id, (pdcp_pP->is_ue != 0) ? "UE" : "eNB");
+      LOG_E(PDCP, "[OSA][RB %d] %s failed to validate MAC-I (key %llx) of incoming PDU\n",
+            rb_id, (pdcp_pP->is_ue != 0) ? "UE" : "eNB",((long long unsigned int*)decrypt_params.key)[0]);
       VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_VALIDATE_SECURITY, VCD_FUNCTION_OUT);
       return -1;
     }
diff --git a/openair2/LAYER2/PROTO_AGENT/cu_test.c b/openair2/LAYER2/PROTO_AGENT/cu_test.c
new file mode 100644
index 0000000000000000000000000000000000000000..78467d68f0a88b38c7d9d4f0df247931146b2ecb
--- /dev/null
+++ b/openair2/LAYER2/PROTO_AGENT/cu_test.c
@@ -0,0 +1,177 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/time.h>
+
+#include "ENB_APP/enb_paramdef.h"
+#include "LAYER2/PROTO_AGENT/proto_agent.h"
+#define BUF_MAX 1400
+
+int recv_client = 0;
+FILE *output;
+
+void usage(char *prg_name)
+{
+  fprintf(stderr, "usage: %s <file or ->\n", prg_name);
+  fprintf(stderr, " - is stdin\n");
+  fprintf(stderr, " received packets are written to stdout\n");
+}
+
+long uelapsed(struct timeval *s, struct timeval *e)
+{
+  return e->tv_sec * 1000000 + e->tv_usec - (s->tv_sec * 1000000 + s->tv_usec);
+}
+
+boolean_t
+pdcp_data_ind(
+  const protocol_ctxt_t* const ctxt_pP,
+  const srb_flag_t   srb_flagP,
+  const MBMS_flag_t  MBMS_flagP,
+  const rb_id_t      rb_idP,
+  const sdu_size_t   sdu_buffer_sizeP,
+  mem_block_t* const sdu_buffer_pP
+)
+{
+  fwrite(sdu_buffer_pP->data, sdu_buffer_sizeP, 1, stdout);
+  fflush(stdout);
+  free_mem_block(sdu_buffer_pP, __func__);
+  /* cannot free because of const */
+  //free(ctxt_pP);
+  recv_client = 1;
+  return 0;
+}
+
+void close_proto_agent(void)
+{
+  proto_agent_stop(0);
+}
+
+int main(int argc, char *argv[])
+{
+  const cudu_params_t params = {
+    .local_ipv4_address = "192.168.12.45",
+    .local_port = 6464,
+    .remote_ipv4_address = "192.168.12.45",
+    .remote_port = 6465
+  };
+
+  protocol_ctxt_t p;
+  memset(&p, 0, sizeof p);
+  mem_block_t mem;
+  char s[BUF_MAX];
+  size_t size, totsize = 0;
+  struct timeval t_start, t_end;
+  FILE *f;
+
+  if (argc != 2) {
+    usage(argv[0]);
+    return 1;
+  }
+
+  if (strcmp(argv[1], "-") == 0) {
+    f = stdin;
+  } else {
+    f = fopen(argv[1], "r");
+  }
+  if (!f) {
+    fprintf(stderr, "cannot open %s: %s\n", argv[1], strerror(errno));
+    return 2;
+  }
+
+  pool_buffer_init();
+  if (proto_agent_start(0, &params) != 0) {
+    fprintf(stderr, "error on proto_agent_start()\n");
+    fclose(f);
+    return 3;
+  }
+  atexit(close_proto_agent);
+
+  /* wait for first packet of client */
+  while (!recv_client) sleep(1);
+  fprintf(stderr, "reading file\n");
+
+  /* now send back at the same time */
+  gettimeofday(&t_start, NULL);
+  while ((size = fread(s, 1, BUF_MAX, f)) > 0) {
+    usleep(10);
+    totsize += size;
+    mem.data = &s[0];
+    proto_agent_send_rlc_data_req(&p, 0, 0, 0, 0, 0, size, &mem);
+  }
+  gettimeofday(&t_end, NULL);
+  fclose(f);
+  long us = uelapsed(&t_start, &t_end);
+  fprintf(stderr, "read %zu bytes in %ld ms -> %.3fMB/s, %.3fMbps\n",
+          totsize, us / 1000, ((float) totsize ) / us,
+          ((float) totsize) / us * 8);
+  fprintf(stderr, "check files using 'diff afile bfile'\n");
+
+  /* give some time in case the other direction is slower */
+  sleep(5);
+  return 0;
+}
+
+/*
+ *********************************************************
+ * arbitrary functions, needed for linking (used or not) *
+ *********************************************************
+ */
+
+rlc_op_status_t rlc_data_req     (const protocol_ctxt_t* const ctxt_pP,
+                                  const srb_flag_t   srb_flagP,
+                                  const MBMS_flag_t  MBMS_flagP,
+                                  const rb_id_t      rb_idP,
+                                  const mui_t        muiP,
+                                  confirm_t    confirmP,
+                                  sdu_size_t   sdu_sizeP,
+                                  mem_block_t *sdu_pP
+#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
+                                  ,const uint32_t * const sourceL2Id
+                                  ,const uint32_t * const destinationL2Id
+#endif
+                                  )
+{
+  fprintf(stderr, "This should never be called on the CU\n");
+  exit(1);
+}
+
+pthread_t new_thread(void *(*f)(void *), void *b) {
+  pthread_t t;
+  pthread_attr_t att;
+
+  if (pthread_attr_init(&att)){
+    fprintf(stderr, "pthread_attr_init err\n");
+    exit(1);
+  }
+  if (pthread_attr_setdetachstate(&att, PTHREAD_CREATE_DETACHED)) {
+    fprintf(stderr, "pthread_attr_setdetachstate err\n");
+    exit(1);
+  }
+  if (pthread_create(&t, &att, f, b)) {
+    fprintf(stderr, "pthread_create err\n");
+    exit(1);
+  }
+  if (pthread_attr_destroy(&att)) {
+    fprintf(stderr, "pthread_attr_destroy err\n");
+    exit(1);
+  }
+
+  return t;
+}
+
+int log_header(char *log_buffer, int buffsize, int comp, int level,const char *format)
+{
+  return 0;
+}
+
+int config_get(paramdef_t *params,int numparams, char *prefix)
+{
+  return 0;
+}
+
+int config_process_cmdline(paramdef_t *cfgoptions,int numoptions, char *prefix)
+{
+  return 0;
+}
diff --git a/openair2/LAYER2/PROTO_AGENT/du_test.c b/openair2/LAYER2/PROTO_AGENT/du_test.c
new file mode 100644
index 0000000000000000000000000000000000000000..9ff7662ab1884c8df1f8266cf3304a3877da7c8f
--- /dev/null
+++ b/openair2/LAYER2/PROTO_AGENT/du_test.c
@@ -0,0 +1,169 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/time.h>
+
+#include "ENB_APP/enb_paramdef.h"
+#include "LAYER2/PROTO_AGENT/proto_agent.h"
+
+#define BUF_MAX 1400
+
+void usage(char *prg_name)
+{
+  fprintf(stderr, "usage: %s <file or ->\n", prg_name);
+  fprintf(stderr, " - is stdin\n");
+  fprintf(stderr, " received packets are written to stdout\n");
+}
+
+long uelapsed(struct timeval *s, struct timeval *e)
+{
+  return e->tv_sec * 1000000 + e->tv_usec - (s->tv_sec * 1000000 + s->tv_usec);
+}
+
+
+rlc_op_status_t rlc_data_req     (const protocol_ctxt_t* const ctxt_pP,
+                                  const srb_flag_t   srb_flagP,
+                                  const MBMS_flag_t  MBMS_flagP,
+                                  const rb_id_t      rb_idP,
+                                  const mui_t        muiP,
+                                  confirm_t    confirmP,
+                                  sdu_size_t   sdu_sizeP,
+                                  mem_block_t *sdu_pP
+#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
+                                  ,const uint32_t * const sourceL2Id
+                                  ,const uint32_t * const destinationL2Id
+#endif
+                                  )
+{
+  fwrite(sdu_pP->data, sdu_sizeP, 1, stdout);
+  fflush(stdout);
+  free_mem_block(sdu_pP, __func__);
+  //free(ctxt_pP);
+  return 0;
+}
+
+void close_proto_agent(void)
+{
+  proto_agent_stop(0);
+}
+
+int main(int argc, char *argv[])
+{
+  const cudu_params_t params = {
+    .local_ipv4_address = "192.168.12.45",
+    .local_port = 6465,
+    .remote_ipv4_address = "192.168.12.45",
+    .remote_port = 6464
+  };
+
+  protocol_ctxt_t p;
+  memset(&p, 0, sizeof p);
+  mem_block_t mem;
+  char s[BUF_MAX];
+  size_t size, totsize = 0;
+  struct timeval t_start, t_end;
+  FILE *f;
+
+  if (argc != 2) {
+    usage(argv[0]);
+    return 1;
+  }
+
+  if (strcmp(argv[1], "-") == 0) {
+    f = stdin;
+  } else {
+    f = fopen(argv[1], "r");
+  }
+  if (!f) {
+    fprintf(stderr, "cannot open %s: %s\n", argv[1], strerror(errno));
+    return 2;
+  }
+
+  pool_buffer_init();
+  if (proto_agent_start(0, &params) != 0) {
+    fprintf(stderr, "error on proto_agent_start()\n");
+    fclose(f);
+    return 3;
+  }
+  atexit(close_proto_agent);
+
+  gettimeofday(&t_start, NULL);
+  while ((size = fread(s, 1, BUF_MAX, f)) > 0) {
+    usleep(10);
+    totsize += size;
+    mem.data = &s[0];
+    proto_agent_send_pdcp_data_ind(&p, 0, 0, 0, size, &mem);
+  }
+  gettimeofday(&t_end, NULL);
+  fclose(f);
+  long us = uelapsed(&t_start, &t_end);
+  fprintf(stderr, "read %zu bytes in %ld ms -> %.3fMB/s, %.3fMbps\n",
+          totsize, us / 1000, ((float) totsize ) / us,
+          ((float) totsize) / us * 8);
+  fprintf(stderr, "check files using 'diff afile bfile'\n");
+
+  /* wait, we are possibly receiving data */
+  sleep(5);
+  return 0;
+}
+
+/*
+ *********************************************************
+ * arbitrary functions, needed for linking (used or not) *
+ *********************************************************
+ */
+
+boolean_t
+pdcp_data_ind(
+  const protocol_ctxt_t* const ctxt_pP,
+  const srb_flag_t   srb_flagP,
+  const MBMS_flag_t  MBMS_flagP,
+  const rb_id_t      rb_idP,
+  const sdu_size_t   sdu_buffer_sizeP,
+  mem_block_t* const sdu_buffer_pP
+)
+{
+  fprintf(stderr, "This should never be called on the DU\n");
+  exit(1);
+}
+
+pthread_t new_thread(void *(*f)(void *), void *b) {
+  pthread_t t;
+  pthread_attr_t att;
+
+  if (pthread_attr_init(&att)){
+    fprintf(stderr, "pthread_attr_init err\n");
+    exit(1);
+  }
+  if (pthread_attr_setdetachstate(&att, PTHREAD_CREATE_DETACHED)) {
+    fprintf(stderr, "pthread_attr_setdetachstate err\n");
+    exit(1);
+  }
+  if (pthread_create(&t, &att, f, b)) {
+    fprintf(stderr, "pthread_create err\n");
+    exit(1);
+  }
+  if (pthread_attr_destroy(&att)) {
+    fprintf(stderr, "pthread_attr_destroy err\n");
+    exit(1);
+  }
+
+  return t;
+}
+
+int log_header(char *log_buffer, int buffsize, int comp, int level,const char *format)
+{
+  return 0;
+}
+
+int config_get(paramdef_t *params,int numparams, char *prefix)
+{
+  return 0;
+}
+
+int config_process_cmdline(paramdef_t *cfgoptions,int numoptions, char *prefix)
+{
+  return 0;
+}
diff --git a/openair2/LAYER2/PROTO_AGENT/proto_agent.c b/openair2/LAYER2/PROTO_AGENT/proto_agent.c
new file mode 100644
index 0000000000000000000000000000000000000000..4b2c0218ead90f205d23cb3482ad57588e64997e
--- /dev/null
+++ b/openair2/LAYER2/PROTO_AGENT/proto_agent.c
@@ -0,0 +1,307 @@
+/*******************************************************************************
+    OpenAirInterface
+    Copyright(c) 1999 - 2014 Eurecom
+
+    OpenAirInterface is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+
+    OpenAirInterface 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 OpenAirInterface.The full GNU General Public License is
+   included in this distribution in the file called "COPYING". If not,
+   see <http://www.gnu.org/licenses/>.
+
+  Contact Information
+  OpenAirInterface Admin: openair_admin@eurecom.fr
+  OpenAirInterface Tech : openair_tech@eurecom.fr
+  OpenAirInterface Dev  : openair4g-devel@lists.eurecom.fr
+
+  Address      : Eurecom, Compus SophiaTech 450, route des chappes, 06451 Biot, France.
+
+ *******************************************************************************/
+
+/*! \file enb_agent.h
+ * \brief top level enb agent receive thread and itti task
+ * \author Navid Nikaein and Xenofon Foukas
+ * \date 2016
+ * \version 0.1
+ */
+#define _GNU_SOURCE
+#include "proto_agent_common.h"
+#include "common/utils/LOG/log.h"
+#include "proto_agent.h"
+#include "assertions.h"
+#include "proto_agent_net_comm.h"
+#include "proto_agent_async.h" 
+
+#include <pthread.h>
+
+#define  ENB_AGENT_MAX 9
+
+proto_agent_instance_t proto_agent[MAX_DU];
+
+pthread_t new_thread(void *(*f)(void *), void *b);
+
+Protocol__FlexsplitMessage *proto_agent_timeout_fsp(void* args);
+
+#define TEST_MOD 0
+
+#define ECHO
+
+/*  Server side function; upon a new connection 
+    reception, sends the hello packets
+*/
+int proto_agent_start(mod_id_t mod_id, const cudu_params_t *p)
+{
+  int channel_id;
+
+  // RS: CUDU does not work!
+  //DevAssert(p->local_interface);
+  //DevAssert(p->local_ipv4_address);
+  //DevAssert(p->local_port > 1024); // "unprivileged" port
+  //DevAssert(p->remote_ipv4_address);
+  //DevAssert(p->remote_port > 1024); // "unprivileged" port
+  
+  proto_agent[mod_id].mod_id = mod_id;
+  proto_agent[mod_id].exit = 0;
+
+  /* Initialize the channel container */
+
+  /* TODO only initialize the first time */
+  proto_agent_init_channel_container();
+
+  /*Create the async channel info*/
+  proto_agent_async_channel_t *channel_info;
+  channel_info = proto_agent_async_channel_info(mod_id, p->local_ipv4_address, p->local_port,
+                                                 p->remote_ipv4_address, p->remote_port);
+  if (!channel_info) goto error;
+  
+  /* Create a channel using the async channel info */
+  channel_id = proto_agent_create_channel((void *) channel_info,
+					proto_agent_async_msg_send,
+					proto_agent_async_msg_recv,
+					proto_agent_async_release);
+  if (channel_id <= 0) goto error;
+
+  proto_agent_channel_t *channel = proto_agent_get_channel(channel_id);
+  if (!channel) goto error;
+  proto_agent[mod_id].channel = channel;
+
+  /* Register the channel for all underlying agents (use ENB_AGENT_MAX) */
+  proto_agent_register_channel(mod_id, channel, ENB_AGENT_MAX);
+
+  // Code for sending the HELLO/ECHO_REQ message once a connection is established
+  //uint8_t *msg = NULL;
+  //Protocol__FlexsplitMessage *init_msg=NULL;
+
+  //if (udp == 0)
+  //{
+  //  // If the comm is not UDP, allow the server to send the first packet over the channel
+  //  //printf( "Proto agent Server: Calling the echo_request packet constructor\n");
+  //  msg_flag = proto_agent_echo_request(mod_id, NULL, &init_msg);
+  //  if (msg_flag != 0)
+  //  goto error;
+  //
+  //  int msgsize = 0;
+  //  if (init_msg != NULL)
+  //    msg = proto_agent_pack_message(init_msg, &msgsize);
+
+  //  if (msg!= NULL)
+  //  {
+  //    LOG_D(PROTO_AGENT, "Server sending the message over the async channel\n");
+  //    proto_agent_async_msg_send((void *)msg, (int) msgsize, 1, (void *) channel_info);
+  //  }
+  //  /* After sending the message, wait for any replies;
+  //    the server thread blocks until it reads any data
+  //    over the channel
+  //  */
+
+  //}
+
+  proto_agent[mod_id].recv_thread = new_thread(proto_agent_receive, &proto_agent[mod_id]);
+
+  fprintf(stderr, "[PROTO_AGENT] server started at port %s:%d\n", p->local_ipv4_address, p->local_port);
+  return 0;
+
+error:
+  LOG_E(PROTO_AGENT, "there was an error\n");
+  return 1;
+
+}
+
+void proto_agent_stop(mod_id_t mod_id)
+{
+  if (!proto_agent[mod_id].channel) return;
+  /* unlock the independent read thread proto_agent_receive() */
+  proto_agent[mod_id].exit = 1;
+  proto_agent_async_msg_recv_unlock(proto_agent[mod_id].channel->channel_info);
+  proto_agent_async_release(proto_agent[mod_id].channel);
+  proto_agent_destroy_channel(proto_agent[mod_id].channel->channel_id);
+  free(proto_agent[mod_id].channel);
+  proto_agent[mod_id].channel = NULL;
+  LOG_W(PROTO_AGENT, "server stopped\n");
+}
+
+//void
+//proto_agent_send_hello(void)
+//{
+//  uint8_t *msg = NULL;
+//  Protocol__FlexsplitMessage *init_msg=NULL;
+//  int msg_flag = 0;
+//
+//
+//  //printf( "PDCP agent: Calling the HELLO packet constructor\n");
+//  msg_flag = proto_agent_hello(proto_agent[TEST_MOD].mod_id, NULL, &init_msg);
+//
+//  int msgsize = 0;
+//  if (msg_flag == 0)
+//  {
+//    proto_agent_serialize_message(init_msg, &msg, &msgsize);
+//  }
+//
+//  LOG_D(PROTO_AGENT, "Agent sending the message over the async channel\n");
+//  proto_agent_async_msg_send((void *)msg, (int) msgsize, 1, (void *) client_channel[TEST_MOD]);
+//}
+
+
+void
+proto_agent_send_rlc_data_req(const protocol_ctxt_t* const ctxt_pP,
+        const srb_flag_t srb_flagP, const MBMS_flag_t MBMS_flagP,
+        const rb_id_t rb_idP, const mui_t muiP,
+        confirm_t confirmP, sdu_size_t sdu_sizeP, mem_block_t *sdu_pP)
+{
+  uint8_t *msg = NULL;
+  Protocol__FlexsplitMessage *init_msg=NULL;
+  int msg_flag = 0;
+  int msgsize = 0;
+  mod_id_t mod_id = ctxt_pP->module_id;
+  data_req_args args;
+  
+  DevAssert(proto_agent[mod_id].channel);
+  DevAssert(proto_agent[mod_id].channel->channel_info);
+ 
+  args.ctxt = ctxt_pP;
+  args.srb_flag = srb_flagP;
+  args.MBMS_flag = MBMS_flagP;
+  args.rb_id = rb_idP;
+  args.mui = muiP;
+  args.confirm = confirmP;
+  args.sdu_size = sdu_sizeP;
+  args.sdu_p = sdu_pP;
+
+  msg_flag = proto_agent_pdcp_data_req(mod_id, (void *) &args, &init_msg);
+  if (msg_flag != 0 || !init_msg) goto error;
+  
+  msg = proto_agent_pack_message(init_msg, &msgsize);
+  if (!msg) goto error;
+    
+  proto_agent_async_msg_send((void *)msg, (int) msgsize, 1, proto_agent[mod_id].channel->channel_info);
+
+  free_mem_block(sdu_pP, __func__);
+  
+  return;
+error:
+  LOG_E(PROTO_AGENT, "PROTO_AGENT there was an error\n");
+  return;
+  
+}
+
+  
+void
+proto_agent_send_pdcp_data_ind(const protocol_ctxt_t* const ctxt_pP, const srb_flag_t srb_flagP,
+			       const MBMS_flag_t MBMS_flagP, const rb_id_t rb_idP, sdu_size_t sdu_sizeP, mem_block_t *sdu_pP)
+{
+  uint8_t *msg = NULL;
+  Protocol__FlexsplitMessage *init_msg = NULL;
+  int msg_flag = 0;
+  int msgsize = 0;
+  mod_id_t mod_id = ctxt_pP->module_id;
+  data_req_args args;
+  
+  DevAssert(proto_agent[mod_id].channel);
+  DevAssert(proto_agent[mod_id].channel->channel_info);
+ 
+  args.ctxt = ctxt_pP;
+  args.srb_flag = srb_flagP;
+  args.MBMS_flag = MBMS_flagP;
+  args.rb_id = rb_idP;
+  args.sdu_size = sdu_sizeP;
+  args.sdu_p = sdu_pP;
+
+  msg_flag = proto_agent_pdcp_data_ind(mod_id, (void *) &args, &init_msg);
+  if (msg_flag != 0 || !init_msg) goto error;
+
+  msg = proto_agent_pack_message(init_msg, &msgsize);
+  if (!msg) goto error;
+
+  proto_agent_async_msg_send((void *)msg, (int) msgsize, 1, proto_agent[mod_id].channel->channel_info);
+
+  free_mem_block(sdu_pP, __func__);
+
+  return;
+
+error:
+  LOG_E(PROTO_AGENT, "there was an error in %s\n", __func__);
+  return;
+  
+}
+
+void *
+proto_agent_receive(void *args)
+{
+  proto_agent_instance_t *inst = args;
+  void                  *data = NULL;
+  int                   size;
+  int                   priority;
+  err_code_t             err_code;
+
+  pthread_setname_np(pthread_self(), "proto_rx");
+  Protocol__FlexsplitMessage *msg;
+  uint8_t *ser_msg;
+  
+  while (1) {
+   
+    msg = NULL;
+    ser_msg = NULL;
+    
+    if ((size = proto_agent_async_msg_recv(&data, &priority, inst->channel->channel_info)) < 0){
+      err_code = PROTOCOL__FLEXSPLIT_ERR__MSG_ENQUEUING;
+      goto error;
+    }
+    if (inst->exit) break;
+
+    LOG_D(PROTO_AGENT, "Server side Received message with size %d and priority %d, calling message handle\n", size, priority);
+
+    msg = proto_agent_handle_message(inst->mod_id, data, size);
+    if (!msg) {
+      LOG_D(PROTO_AGENT, "msg to send back is NULL\n");
+      continue;
+    }
+
+    ser_msg = proto_agent_pack_message(msg, &size);
+    if (!ser_msg) {
+      continue;
+    }
+  
+    LOG_D(PROTO_AGENT, "Server sending the reply message over the async channel\n");
+    if (proto_agent_async_msg_send((void *)ser_msg, (int) size, 1, inst->channel->channel_info)){
+      err_code = PROTOCOL__FLEXSPLIT_ERR__MSG_ENQUEUING;
+      goto error;
+    }
+    LOG_D(PROTO_AGENT, "sent message with size %d\n", size);
+
+  }
+  
+  return NULL;
+
+error:
+  LOG_E(PROTO_AGENT, "proto_agent_receive(): error %d occured\n",err_code);
+  return NULL;
+}
diff --git a/openair2/LAYER2/PROTO_AGENT/proto_agent.h b/openair2/LAYER2/PROTO_AGENT/proto_agent.h
new file mode 100644
index 0000000000000000000000000000000000000000..0c5cd3fa8d2245ca9db9c5651a6e30f26f6b2edd
--- /dev/null
+++ b/openair2/LAYER2/PROTO_AGENT/proto_agent.h
@@ -0,0 +1,58 @@
+
+/*******************************************************************************
+    OpenAirInterface
+    Copyright(c) 1999 - 2014 Eurecom
+
+    OpenAirInterface is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+
+    OpenAirInterface 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 OpenAirInterface.The full GNU General Public License is
+   included in this distribution in the file called "COPYING". If not,
+   see <http://www.gnu.org/licenses/>.
+
+  Contact Information
+  OpenAirInterface Admin: openair_admin@eurecom.fr
+  OpenAirInterface Tech : openair_tech@eurecom.fr
+  OpenAirInterface Dev  : openair4g-devel@lists.eurecom.fr
+
+  Address      : Eurecom, Compus SophiaTech 450, route des chappes, 06451 Biot, France.
+
+ *******************************************************************************/
+
+/*! \file proto_agent.h
+ * \brief top level protocol agent  
+ * \author Navid Nikaein and Xenofon Foukas
+ * \date 2016
+ * \version 0.1
+ */
+
+#ifndef PROTO_AGENT_H_
+#define PROTO_AGENT_H_
+#include "ENB_APP/enb_config.h" // for enb properties
+#include "proto_agent_common.h"
+
+
+void * proto_agent_receive(void *args);
+
+int proto_agent_start(mod_id_t mod_id, const cudu_params_t *p);
+void proto_agent_stop(mod_id_t mod_id);
+
+void proto_agent_send_rlc_data_req( const protocol_ctxt_t* const ctxt_pP,
+    const srb_flag_t srb_flagP, const MBMS_flag_t MBMS_flagP,
+    const rb_id_t rb_idP, const mui_t muiP, confirm_t confirmP,
+    sdu_size_t sdu_sizeP, mem_block_t *sdu_pP);
+
+void proto_agent_send_pdcp_data_ind(const protocol_ctxt_t* const ctxt_pP,
+    const srb_flag_t srb_flagP, const MBMS_flag_t MBMS_flagP,
+    const rb_id_t rb_idP, sdu_size_t sdu_sizeP, mem_block_t *sdu_pP);
+
+#endif
diff --git a/openair2/LAYER2/PROTO_AGENT/proto_agent_async.c b/openair2/LAYER2/PROTO_AGENT/proto_agent_async.c
new file mode 100644
index 0000000000000000000000000000000000000000..eef697c5bbe05c4e5e34875493a52fa0005a48d8
--- /dev/null
+++ b/openair2/LAYER2/PROTO_AGENT/proto_agent_async.c
@@ -0,0 +1,102 @@
+/*******************************************************************************
+    OpenAirInterface
+    Copyright(c) 1999 - 2014 Eurecom
+
+    OpenAirInterface is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+
+    OpenAirInterface 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 OpenAirInterface.The full GNU General Public License is
+   included in this distribution in the file called "COPYING". If not,
+   see <http://www.gnu.org/licenses/>.
+
+  Contact Information
+  OpenAirInterface Admin: openair_admin@eurecom.fr
+  OpenAirInterface Tech : openair_tech@eurecom.fr
+  OpenAirInterface Dev  : openair4g-devel@lists.eurecom.fr
+
+  Address      : Eurecom, Compus SophiaTech 450, route des chappes, 06451 Biot, France.
+
+ *******************************************************************************/
+
+
+#include "proto_agent_async.h"
+#include "proto_agent_defs.h"
+
+
+#include "common/utils/LOG/log.h"
+
+proto_agent_async_channel_t *
+proto_agent_async_channel_info(mod_id_t mod_id, const char *bind_ip, uint16_t bind_port,
+                               const char* peer_ip, uint16_t peer_port)
+{
+  proto_agent_async_channel_t *channel;
+  channel = malloc(sizeof(proto_agent_async_channel_t));
+  
+  if (channel == NULL)
+    goto error;
+
+  channel->enb_id = mod_id;
+  channel->link = new_link_udp_server(bind_ip, bind_port);
+  
+  if (channel->link == NULL) goto error;
+  
+  channel->send_queue = new_message_queue();
+  if (channel->send_queue == NULL) goto error;
+  channel->receive_queue = new_message_queue();
+  if (channel->receive_queue == NULL) goto error;
+
+  channel->manager = create_link_manager(channel->send_queue,
+                                         channel->receive_queue,
+                                         channel->link);
+  /* manually set remote IP&port for UDP server remote end */
+  channel->manager->peer_port = peer_port;
+  channel->manager->peer_addr = peer_ip;
+
+  if (channel->manager == NULL) goto error;
+  
+  return channel;
+
+ error:
+  if (channel)
+    free(channel);
+  LOG_E(PROTO_AGENT, "error creating proto_agent_async_channel_t\n");
+  return NULL;
+}
+
+int proto_agent_async_msg_send(void *data, int size, int priority, void *channel_info)
+{
+  proto_agent_async_channel_t *channel = channel_info;
+  return message_put(channel->send_queue, data, size, priority);
+}
+
+int proto_agent_async_msg_recv(void **data, int *priority, void *channel_info)
+{
+  proto_agent_async_channel_t *channel = channel_info;
+  return message_get(channel->receive_queue, data, priority);
+}
+
+void proto_agent_async_msg_recv_unlock(proto_agent_async_channel_t *channel) {
+  message_get_unlock(channel->receive_queue);
+}
+
+void proto_agent_async_release(proto_agent_channel_t *channel)
+{
+  proto_agent_async_channel_t *channel_info = channel->channel_info;
+
+  destroy_link_manager(channel_info->manager);
+  
+  destroy_message_queue(channel_info->send_queue);
+  destroy_message_queue(channel_info->receive_queue);
+  
+  close_link(channel_info->link);
+  free(channel_info);
+}
diff --git a/openair2/LAYER2/PROTO_AGENT/proto_agent_async.h b/openair2/LAYER2/PROTO_AGENT/proto_agent_async.h
new file mode 100644
index 0000000000000000000000000000000000000000..27030924cdff888a221d42646db970c7b085b5b2
--- /dev/null
+++ b/openair2/LAYER2/PROTO_AGENT/proto_agent_async.h
@@ -0,0 +1,64 @@
+/*******************************************************************************
+    OpenAirInterface
+    Copyright(c) 1999 - 2014 Eurecom
+
+    OpenAirInterface is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+
+    OpenAirInterface 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 OpenAirInterface.The full GNU General Public License is
+   included in this distribution in the file called "COPYING". If not,
+   see <http://www.gnu.org/licenses/>.
+
+  Contact Information
+  OpenAirInterface Admin: openair_admin@eurecom.fr
+  OpenAirInterface Tech : openair_tech@eurecom.fr
+  OpenAirInterface Dev  : openair4g-devel@lists.eurecom.fr
+
+  Address      : Eurecom, Compus SophiaTech 450, route des chappes, 06451 Biot, France.
+
+ *******************************************************************************/
+
+/*! \file enb_agent_async.h
+ * \brief channel implementation for async interface
+ * \author Xenofon Foukas
+ * \date 2016
+ * \version 0.1
+ */
+
+#ifndef PROTO_AGENT_ASYNC_H_
+#define PROTO_AGENT_ASYNC_H_
+
+#include "proto_agent_net_comm.h"
+
+typedef struct proto_agent_async_channel_s {
+  mod_id_t         enb_id;
+  socket_link_t   *link;
+  message_queue_t *send_queue;
+  message_queue_t *receive_queue;
+  link_manager_t  *manager;
+} proto_agent_async_channel_t;
+
+proto_agent_async_channel_t *
+proto_agent_async_channel_info(mod_id_t mod_id, const char *bind_ip, uint16_t bind_port,
+                               const char *peer_ip, uint16_t peer_port);
+
+int proto_agent_async_msg_send(void *data, int size, int priority, void *channel_info);
+
+int proto_agent_async_msg_recv(void **data, int *priority, void *channel_info);
+
+/* unlocks a running proto_agent_async_msg_recv() */
+void proto_agent_async_msg_recv_unlock(proto_agent_async_channel_t *channel);
+
+void proto_agent_async_release(proto_agent_channel_t *channel);
+
+
+#endif /*PROTO_AGENT_ASYNC_H_*/
diff --git a/openair2/LAYER2/PROTO_AGENT/proto_agent_common.c b/openair2/LAYER2/PROTO_AGENT/proto_agent_common.c
new file mode 100644
index 0000000000000000000000000000000000000000..1eca32b162d27bf98238dbde8d9d37dc63b0508b
--- /dev/null
+++ b/openair2/LAYER2/PROTO_AGENT/proto_agent_common.c
@@ -0,0 +1,792 @@
+/*******************************************************************************
+    OpenAirInterface
+    Copyright(c) 1999 - 2014 Eurecom
+
+    OpenAirInterface is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+
+    OpenAirInterface 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 OpenAirInterface.The full GNU General Public License is
+   included in this distribution in the file called "COPYING". If not,
+   see <http://www.gnu.org/licenses/>.
+
+  Contact Information
+  OpenAirInterface Admin: openair_admin@eurecom.fr
+  OpenAirInterface Tech : openair_tech@eurecom.fr
+  OpenAirInterface Dev  : openair4g-devel@lists.eurecom.fr
+
+  Address      : Eurecom, Compus SophiaTech 450, route des chappes, 06451 Biot, France.
+
+ *******************************************************************************/
+
+/*! \file proto_agent_common.c
+ * \brief common primitives for all agents
+ * \author Navid Nikaein and Xenofon Foukas
+ * \date 2016
+ * \version 0.1
+ */
+
+#include<stdio.h>
+#include <dlfcn.h>
+#include <time.h>
+
+#include "PHY/phy_extern.h"
+#include "proto_agent_common.h"
+#include "common/utils/LOG/log.h"
+
+#include "RRC/LTE/rrc_extern.h"
+#include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h"
+#include "rrc_eNB_UE_context.h"
+
+/*
+ * message primitives
+ */
+
+// Function to fill in the dl_data header (32bits) with the appropriate fields (doing bitwise operations)
+void fill_dl_data_header(int pdu_type, int spare, int seq_no, uint32_t *header)
+{
+  uint32_t type = pdu_type;
+  uint32_t spare_ = spare;
+  uint32_t seq = seq_no;
+  type = type << 28;
+  spare_ = spare_ << 24;
+  *header = (type | spare_);
+  *header = (*header | seq);
+  return;
+}
+
+
+// Function to retrieve data from the dl_data header (32bits) (doing bitwise operations)
+void read_dl_data_header(int *pdu_type, int *spare, int *seqno, uint32_t header)
+{
+  *pdu_type = header;
+  *spare = header;
+  *seqno = header;
+  *pdu_type = *pdu_type >> 28;
+  *spare = *spare << 4;
+  *spare = *spare >> 28;
+  *seqno = *seqno << 8;
+  *seqno = *seqno >> 8;
+  return;
+}
+
+int f1u_serialize_message(Protocol__F1uMessage *msg, void **buf,int *size)
+{
+  *size = protocol__f1u_message__get_packed_size(msg);
+
+  *buf = malloc(*size);
+  if (!(*buf))
+    goto error;
+
+  protocol__f1u_message__pack(msg, *buf);
+
+  return 0;
+
+ error:
+  LOG_E(F1U, "an error occured\n");
+  return -1;
+
+}
+
+int f1u_deserialize_message(void *data, int size, Protocol__F1uMessage **msg)
+{
+  *msg = protocol__f1u_message__unpack(NULL, size, data);
+  if (*msg == NULL)
+    goto error;
+
+  return 0;
+
+ error:
+  LOG_E(F1U, "%s: an error occured\n", __FUNCTION__);
+  return -1;
+}
+
+int f1u_dl_data_create_header(uint32_t pdu_type, uint32_t f1u_sn, Protocol__DlDataHeader **header)
+{
+  *header = malloc(sizeof(Protocol__DlDataHeader));
+  if(*header == NULL)
+    goto error;
+
+  protocol__dl_data_header__init(*header);
+  LOG_D(F1U, "Initialized the DL Data User header\n");
+
+  fill_dl_data_header(pdu_type, 0, f1u_sn, &(*header)->fields);
+  return 0;
+
+ error:
+  LOG_E(F1U, "%s: an error occured\n", __FUNCTION__);
+  return -1;
+}
+
+int f1u_dl_data(const void *params, Protocol__F1uMessage **msg)
+{
+  // Initialize the PDCP params
+  dl_data_args *args = (dl_data_args *)params;
+
+  Protocol__DlDataHeader *header;
+
+  if (f1u_dl_data_create_header(args->pdu_type, args->sn, &header) != 0)
+     goto error;
+
+
+  Protocol__DlUserData *dl_data = NULL;
+
+  *msg = malloc(sizeof(Protocol__DlUserData));
+
+  if(*msg == NULL)
+    goto error;
+
+
+  // FIXME: Is the following used? It seems to be overwritten by the function
+  // protocol__dl_user_data__init() anyway
+  //dl_data = *msg;
+
+  protocol__dl_user_data__init(dl_data);
+
+
+  // Copy data to the bytes structure
+  dl_data->pdu.data = malloc(args->sdu_size);
+  dl_data->pdu.len = args->sdu_size;
+  memcpy(dl_data->pdu.data, args->sdu_p, args->sdu_size);
+
+  dl_data->frame = args->frame;
+  dl_data->subframe = args->subframe;
+  dl_data->rnti = args->rnti;
+
+  dl_data->header = header;
+
+  return 0;
+
+  error:
+    if(header != NULL)
+      free(header);
+    if(*msg != NULL)
+      free(*msg);
+    LOG_E(F1U, "%s: an error occured\n", __FUNCTION__);
+    return -1;
+}
+
+int proto_agent_serialize_message(Protocol__FlexsplitMessage *msg, uint8_t **buf, int *size)
+{
+  *size = protocol__flexsplit_message__get_packed_size(msg);
+
+  *buf = malloc(*size);
+  if (!(*buf))
+    goto error;
+
+  protocol__flexsplit_message__pack(msg, *buf);
+
+  return 0;
+
+ error:
+  LOG_E(MAC, "an error occured\n");
+  return -1;
+}
+
+/* We assume that the buffer size is equal to the message size.
+   Should be chekced durint Tx/Rx */
+int proto_agent_deserialize_message(void *data, int size, Protocol__FlexsplitMessage **msg)
+{
+  *msg = protocol__flexsplit_message__unpack(NULL, size, data);
+  if (*msg == NULL)
+    goto error;
+
+  return 0;
+
+ error:
+  LOG_E(MAC, "%s: an error occured\n", __FUNCTION__);
+  return -1;
+}
+
+int fsp_create_header(xid_t xid, Protocol__FspType type,  Protocol__FspHeader **header)
+{
+  *header = malloc(sizeof(Protocol__FspHeader));
+  if(*header == NULL)
+    goto error;
+
+  protocol__fsp_header__init(*header);
+  LOG_D(PROTO_AGENT, "Initialized the PROTOBUF message header\n");
+  (*header)->version = FLEXSPLIT_VERSION;
+  LOG_D(PROTO_AGENT, "Set the vversion to FLEXSPLIT_VERSION\n");
+
+  (*header)->has_version = 1;
+  (*header)->type = type;
+  (*header)->has_type = 1;
+  (*header)->xid = xid;
+  (*header)->has_xid = 1;
+  return 0;
+
+ error:
+  LOG_E(MAC, "%s: an error occured\n", __FUNCTION__);
+  return -1;
+}
+
+int just_print(mod_id_t mod_id, const void *params, Protocol__FlexsplitMessage **msg)
+{
+    return 1;
+}
+
+int proto_agent_pdcp_data_req(mod_id_t mod_id, const void *params, Protocol__FlexsplitMessage **msg)
+{
+  Protocol__FspCtxt *ctxt = NULL;
+  Protocol__FspRlcPdu *pdu = NULL;
+  Protocol__FspRlcData *rlc_data = NULL;
+  Protocol__FspRlcDataReq *data_req = NULL;
+
+  // Initialize the PDCP params
+  data_req_args *args = (data_req_args *)params;
+
+  // Create the protobuf header
+  Protocol__FspHeader *header;
+  xid_t xid = mod_id;
+  LOG_D(PROTO_AGENT, "creating the data_req message\n");
+
+  if (fsp_create_header(xid, PROTOCOL__FSP_TYPE__FSPT_RLC_DATA_REQ, &header) != 0)
+     goto error;
+
+  /* Begin constructing the messages. They are defined as follows:
+  *  1) fspRlcPdu is storing the bytes of the packet
+  *  2) Message fspRlcData is packing the packet + the context of the PDCP (separate message)
+  *  3) Messge fspRlcDataReq is packing the header, enb_id and fspRlcData
+  */
+
+  ctxt = malloc(sizeof(Protocol__FspCtxt));
+  pdu = malloc(sizeof(Protocol__FspRlcPdu));
+  rlc_data = malloc(sizeof(Protocol__FspRlcData));
+  data_req = malloc(sizeof(Protocol__FspRlcDataReq));
+
+  protocol__fsp_ctxt__init(ctxt);
+  protocol__fsp_rlc_pdu__init(pdu);
+  protocol__fsp_rlc_data__init(rlc_data);
+  protocol__fsp_rlc_data_req__init(data_req);
+
+  // Copy data to the RlcPdu structure
+  pdu->fsp_pdu_data.data =  malloc(args->sdu_size);
+  pdu->fsp_pdu_data.len = args->sdu_size;
+
+  memcpy(pdu->fsp_pdu_data.data, args->sdu_p->data, args->sdu_size);
+  pdu->has_fsp_pdu_data = 1;
+
+  // Copy data to the ctxt structure
+  ctxt->fsp_mod_id = args->ctxt->module_id;
+  ctxt->fsp_enb_flag = args->ctxt->enb_flag;
+  ctxt->fsp_instance = args->ctxt->instance;
+  ctxt->fsp_rnti = args->ctxt->rnti;
+  ctxt->fsp_frame = args->ctxt->frame;
+  ctxt->fsp_subframe = args->ctxt->subframe;
+  ctxt->fsp_enb_index = args->ctxt->eNB_index;
+
+  ctxt->has_fsp_mod_id = 1;
+  ctxt->has_fsp_enb_flag = 1;
+  ctxt->has_fsp_instance = 1;
+  ctxt->has_fsp_rnti = 1;
+  ctxt->has_fsp_frame = 1;
+  ctxt->has_fsp_subframe = 1;
+  ctxt->has_fsp_enb_index = 1;
+
+  rlc_data->fsp_ctxt = ctxt;
+  rlc_data->fsp_srb_flag = args->srb_flag;
+  rlc_data->fsp_mbms_flag = args->MBMS_flag;
+  rlc_data->fsp_rb_id = args->rb_id;
+  rlc_data->fsp_muip = args->mui;
+  rlc_data->fsp_confirm = args->confirm;
+  rlc_data->fsp_sdu_buffer_size = args->sdu_size;
+  rlc_data->fsp_pdu = pdu;
+
+  rlc_data->has_fsp_srb_flag = 1;
+  rlc_data->has_fsp_mbms_flag = 1;
+  rlc_data->has_fsp_rb_id = 1;
+  rlc_data->has_fsp_muip = 1;
+  rlc_data->has_fsp_confirm = 1;
+  rlc_data->has_fsp_sdu_buffer_size = 1;
+
+  // Up to here, everything is a signle message that is packed inside another. The final data_req
+  // will be created later, after the setting of all variables
+
+  data_req->header = header;
+  data_req->enb_id = mod_id;
+  data_req->has_enb_id = 1;
+  data_req->pdcp_data = rlc_data;
+
+  *msg = malloc(sizeof(Protocol__FlexsplitMessage));
+
+  if(*msg == NULL)
+    goto error;
+
+  protocol__flexsplit_message__init(*msg);
+
+  (*msg)->msg_case = PROTOCOL__FLEXSPLIT_MESSAGE__MSG_DATA_REQ_MSG;
+  (*msg)->msg_dir = PROTOCOL__FLEXSPLIT_DIRECTION__INITIATING_MESSAGE; //we will be waiting for the ACK
+  (*msg)->has_msg_dir = 1;
+  (*msg)->data_req_msg = data_req;
+
+  return 0;
+
+  error:
+    if(header != NULL)
+      free(header);
+    if(pdu!=NULL)
+      free(pdu);
+    if(rlc_data!=NULL)
+      free(rlc_data);
+    if(data_req!= NULL)
+      free(data_req);
+    if(*msg != NULL)
+      free(*msg);
+    LOG_E(MAC, "%s: an error occured\n", __FUNCTION__);
+    return -1;
+}
+
+int proto_agent_destroy_pdcp_data_req(Protocol__FlexsplitMessage *msg) {
+  if(msg->msg_case != PROTOCOL__FLEXSPLIT_MESSAGE__MSG_DATA_REQ_MSG)
+    goto error;
+
+  free(msg->data_req_msg->header);
+  free(msg->data_req_msg->pdcp_data->fsp_pdu->fsp_pdu_data.data);
+  free(msg->data_req_msg->pdcp_data->fsp_pdu);
+  free(msg->data_req_msg->pdcp_data->fsp_ctxt);
+  free(msg->data_req_msg->pdcp_data);
+  free(msg->data_req_msg);
+  free(msg);
+  return 0;
+
+  error:
+    LOG_E(MAC, "%s: an error occured\n", __FUNCTION__);
+    return -1;
+}
+
+int proto_agent_get_ack_result(mod_id_t mod_id, const void *params, Protocol__FlexsplitMessage **msg)
+{
+  rlc_op_status_t result = 0;
+  //printf("PROTO_AGENT: handling the data_req_ack message\n");
+  Protocol__FlexsplitMessage *input = (Protocol__FlexsplitMessage *)params;
+  Protocol__FspRlcDataReqAck *data_ack = input->data_req_ack;
+  result = data_ack->result;
+  //printf("PROTO_AGENT: ACK RESULT IS %u\n", result);
+  ack_result = result;
+  return 0;
+
+}
+
+
+int proto_agent_pdcp_data_req_process(mod_id_t mod_id, const void *params, Protocol__FlexsplitMessage **msg)
+{
+  rlc_op_status_t result = 0;
+
+  Protocol__FlexsplitMessage *input = (Protocol__FlexsplitMessage *)params;
+  Protocol__FspRlcDataReq *data_req = input->data_req_msg;
+
+  Protocol__FspCtxt *ctxt = NULL;
+  Protocol__FspRlcData *rlc_data = NULL;
+
+  rlc_data = data_req->pdcp_data;
+  ctxt = rlc_data->fsp_ctxt;
+
+  protocol_ctxt_t  ctxt_pP;
+  srb_flag_t       srb_flagP = 0;
+  rb_id_t          rb_idP = 0;
+  mui_t            muiP = 0;
+  confirm_t        confirmP = 0;
+  MBMS_flag_t      flag_MBMS = 0;
+  sdu_size_t       pdcp_pdu_size = 0;
+  mem_block_t     *pdcp_pdu_p = NULL;
+
+  // Create a new protocol context for handling the packet
+  ctxt_pP.module_id = ctxt->fsp_mod_id;
+  ctxt_pP.enb_flag = ctxt->fsp_enb_flag;
+  ctxt_pP.instance = ctxt->fsp_instance;
+  ctxt_pP.rnti = ctxt->fsp_rnti;
+  ctxt_pP.frame = ctxt->fsp_frame;
+  ctxt_pP.subframe = ctxt->fsp_subframe;
+  ctxt_pP.eNB_index = ctxt->fsp_enb_index;
+
+  srb_flagP = rlc_data->fsp_srb_flag;
+  flag_MBMS = rlc_data->fsp_mbms_flag;
+  rb_idP = rlc_data->fsp_rb_id;
+  muiP = rlc_data->fsp_muip;
+  confirmP = rlc_data->fsp_confirm;
+  pdcp_pdu_size = rlc_data->fsp_pdu->fsp_pdu_data.len;
+  pdcp_pdu_p = get_free_mem_block(pdcp_pdu_size, __func__);
+  if (!pdcp_pdu_p) goto error;
+  memcpy(pdcp_pdu_p->data, rlc_data->fsp_pdu->fsp_pdu_data.data, pdcp_pdu_size);
+
+  result = rlc_data_req(&ctxt_pP
+                        ,srb_flagP
+                        ,flag_MBMS
+                        ,rb_idP
+                        ,muiP
+                        ,confirmP
+                        ,pdcp_pdu_size
+                        ,pdcp_pdu_p
+  #ifdef Rel14
+                        ,NULL
+                        ,NULL
+  #endif
+                        );
+
+  return result;
+
+  error:
+    if (pdcp_pdu_p)
+      free_mem_block(pdcp_pdu_p, __func__);
+    LOG_E(PROTO_AGENT, "%s: an error occured\n", __FUNCTION__);
+    return -1;
+
+}
+
+int proto_agent_destroy_pdcp_data_ind(Protocol__FlexsplitMessage *msg)
+{
+  if(msg->msg_case != PROTOCOL__FLEXSPLIT_MESSAGE__MSG_DATA_IND_MSG)
+    goto error;
+
+  free(msg->data_ind_msg->header);
+  free(msg->data_ind_msg->rlc_data->fsp_pdu->fsp_pdu_data.data);
+  free(msg->data_ind_msg->rlc_data->fsp_pdu);
+  free(msg->data_ind_msg->rlc_data->fsp_ctxt);
+  free(msg->data_ind_msg->rlc_data);
+  free(msg->data_ind_msg);
+  free(msg);
+  return 0;
+
+  error:
+    LOG_E(MAC, "%s: an error occured\n", __FUNCTION__);
+    return -1;
+}
+
+int proto_agent_pdcp_data_ind(mod_id_t mod_id, const void *params, Protocol__FlexsplitMessage **msg)
+{
+  Protocol__FspCtxt *ctxt = NULL;
+  Protocol__FspRlcPdu *pdu = NULL;
+  Protocol__FspRlcData *rlc_data = NULL;
+  Protocol__FspPdcpDataInd *data_ind = NULL;
+
+  // Initialize the PDCP params
+  data_req_args *args = (data_req_args *)params;
+
+  // Create the protobuf header
+  Protocol__FspHeader *header;
+  xid_t xid = mod_id;
+  LOG_D(PROTO_AGENT, "creating the data_ind message\n");
+
+  if (fsp_create_header(xid, PROTOCOL__FSP_TYPE__FSPT_PDCP_DATA_IND, &header) != 0)
+     goto error;
+
+  /* Begin constructing the messages. They are defined as follows:
+  *  1) fspRlcPdu is storing the bytes of the packet
+  *  2) Message fspRlcData is packing the packet + the context of the PDCP (separate message)
+  *  3) Messge fspRlcDataReq is packing the header, enb_id and fspRlcData
+  */
+
+  ctxt = malloc(sizeof(Protocol__FspCtxt));
+  pdu = malloc(sizeof(Protocol__FspRlcPdu));
+  rlc_data = malloc(sizeof(Protocol__FspRlcData));
+  data_ind = malloc(sizeof(Protocol__FspPdcpDataInd));
+
+  protocol__fsp_ctxt__init(ctxt);
+  protocol__fsp_rlc_pdu__init(pdu);
+  protocol__fsp_rlc_data__init(rlc_data);
+  protocol__fsp_pdcp_data_ind__init(data_ind);
+
+  // Copy data to the RlcPdu structure
+  pdu->fsp_pdu_data.data =  malloc(args->sdu_size);
+  pdu->fsp_pdu_data.len = args->sdu_size;
+
+  memcpy(pdu->fsp_pdu_data.data, args->sdu_p->data, args->sdu_size);
+  pdu->has_fsp_pdu_data = 1;
+
+  // Copy data to the ctxt structure
+  ctxt->fsp_mod_id = args->ctxt->module_id;
+  ctxt->fsp_enb_flag = args->ctxt->enb_flag;
+  ctxt->fsp_instance = args->ctxt->instance;
+  ctxt->fsp_rnti = args->ctxt->rnti;
+  ctxt->fsp_frame = args->ctxt->frame;
+  ctxt->fsp_subframe = args->ctxt->subframe;
+  ctxt->fsp_enb_index = args->ctxt->eNB_index;
+
+  ctxt->has_fsp_mod_id = 1;
+  ctxt->has_fsp_enb_flag = 1;
+  ctxt->has_fsp_instance = 1;
+  ctxt->has_fsp_rnti = 1;
+  ctxt->has_fsp_frame = 1;
+  ctxt->has_fsp_subframe = 1;
+  ctxt->has_fsp_enb_index = 1;
+
+  rlc_data->fsp_ctxt = ctxt;
+  rlc_data->fsp_srb_flag = args->srb_flag;
+  rlc_data->fsp_mbms_flag = args->MBMS_flag;
+  rlc_data->fsp_rb_id = args->rb_id;
+
+  rlc_data->fsp_sdu_buffer_size = args->sdu_size;
+  rlc_data->fsp_pdu = pdu;
+  rlc_data->has_fsp_srb_flag = 1;
+  rlc_data->has_fsp_mbms_flag = 1;
+  rlc_data->has_fsp_rb_id = 1;
+  rlc_data->has_fsp_sdu_buffer_size = 1;
+
+  // Up to here, everything is a signle message that is packed inside another. The final data_req
+  // will be created later, after the setting of all variables
+
+  data_ind->header = header;
+  data_ind->enb_id = mod_id;
+  data_ind->has_enb_id = 1;
+  data_ind->rlc_data = rlc_data;
+
+
+  *msg = malloc(sizeof(Protocol__FlexsplitMessage));
+
+  if(*msg == NULL)
+    goto error;
+
+  protocol__flexsplit_message__init(*msg);
+  LOG_D(PROTO_AGENT,"setting the message case to %d\n", PROTOCOL__FLEXSPLIT_MESSAGE__MSG_DATA_IND_MSG);
+
+  (*msg)->msg_case = PROTOCOL__FLEXSPLIT_MESSAGE__MSG_DATA_IND_MSG;
+  (*msg)->msg_dir = PROTOCOL__FLEXSPLIT_DIRECTION__INITIATING_MESSAGE; //we will be waiting for the ACK
+  (*msg)->has_msg_dir = 1;
+  (*msg)->data_ind_msg = data_ind; //data_req;
+
+  return 0;
+
+  error:
+    if(header != NULL)
+      free(header);
+    if(pdu!=NULL)
+      free(pdu);
+    if(rlc_data!=NULL)
+      free(rlc_data);
+    if(data_ind!= NULL)
+      free(data_ind);
+    if(*msg != NULL)
+      free(*msg);
+    LOG_E(MAC, "%s: an error occured\n", __FUNCTION__);
+    return -1;
+}
+
+
+int proto_agent_pdcp_data_ind_process(mod_id_t mod_id, const void *params, Protocol__FlexsplitMessage **msg)
+{
+  boolean_t result = 0;
+
+  Protocol__FlexsplitMessage *input = (Protocol__FlexsplitMessage *)params;
+  Protocol__FspPdcpDataInd *data_ind = input->data_ind_msg;
+  Protocol__FspCtxt *ctxt = NULL;
+  Protocol__FspRlcData *rlc_data = NULL;
+
+  rlc_data = data_ind->rlc_data;
+  ctxt = rlc_data->fsp_ctxt;
+
+  protocol_ctxt_t  ctxt_pP;
+  srb_flag_t       srb_flagP = 0;
+  rb_id_t          rb_idP = 0;
+  sdu_size_t       pdcp_pdu_size = 0;
+  MBMS_flag_t      flag_MBMS = 0;
+  mem_block_t     *pdcp_pdu_p = NULL;
+
+  // Create a new protocol context for handling the packet
+  ctxt_pP.module_id = ctxt->fsp_mod_id;
+  ctxt_pP.enb_flag = ctxt->fsp_enb_flag;
+  ctxt_pP.instance = ctxt->fsp_instance;
+  ctxt_pP.rnti = ctxt->fsp_rnti;
+  ctxt_pP.frame = ctxt->fsp_frame;
+  ctxt_pP.subframe = ctxt->fsp_subframe;
+  ctxt_pP.eNB_index = ctxt->fsp_enb_index;
+
+  srb_flagP = rlc_data->fsp_srb_flag;
+  flag_MBMS = rlc_data->fsp_mbms_flag;
+  rb_idP = rlc_data->fsp_rb_id;
+  pdcp_pdu_size = rlc_data->fsp_pdu->fsp_pdu_data.len;
+  pdcp_pdu_p = get_free_mem_block(pdcp_pdu_size, __func__);
+  if (!pdcp_pdu_p) goto error;
+
+  memcpy(pdcp_pdu_p->data, rlc_data->fsp_pdu->fsp_pdu_data.data, pdcp_pdu_size);
+
+//   if (xid == 1)
+//     pdcp_data_ind_wifi((const protocol_ctxt_t*) ctxt_pP, (const srb_flag_t) srb_flagP, (const MBMS_flag_t) flag_MBMS, (const rb_id_t) rb_idP, pdcp_pdu_size, pdcp_pdu_p);
+//   else if (xid == 0)   // FIXME: USE a preprocessed definition
+  LOG_D(PROTO_AGENT, "[inst %d] Received PDCP PDU with size %d for UE RNTI %x RB %d, Calling pdcp_data_ind\n", ctxt_pP.instance, pdcp_pdu_size,ctxt_pP.rnti,rb_idP);
+  result = pdcp_data_ind(&ctxt_pP,
+                         srb_flagP,
+                         flag_MBMS,
+                         rb_idP,
+                         pdcp_pdu_size,
+                         pdcp_pdu_p);
+
+  return result;
+
+  error:
+    if (pdcp_pdu_p)
+      free_mem_block(pdcp_pdu_p, __func__);
+    LOG_E(MAC, "%s: an error occured\n", __FUNCTION__);
+    return -1;
+}
+
+int proto_agent_hello(mod_id_t mod_id, const void *params, Protocol__FlexsplitMessage **msg)
+{
+  Protocol__FspHeader *header;
+  Protocol__FspHello *hello_msg = NULL;
+
+  /*TODO: Need to set random xid or xid from received hello message*/
+  xid_t xid = mod_id;
+  if (fsp_create_header(xid, PROTOCOL__FSP_TYPE__FSPT_HELLO, &header) != 0)
+    goto error;
+
+  LOG_D(PROTO_AGENT, "creating the HELLO message\n");
+  hello_msg = malloc(sizeof(Protocol__FspHello));
+  if(hello_msg == NULL)
+    goto error;
+  protocol__fsp_hello__init(hello_msg);
+  hello_msg->header = header;
+
+  *msg = malloc(sizeof(Protocol__FlexsplitMessage));
+  if(*msg == NULL)
+    goto error;
+
+  protocol__flexsplit_message__init(*msg);
+  (*msg)->msg_case = PROTOCOL__FLEXSPLIT_MESSAGE__MSG_HELLO_MSG;
+  (*msg)->msg_dir = PROTOCOL__FLEXSPLIT_DIRECTION__SUCCESSFUL_OUTCOME;
+  (*msg)->has_msg_dir = 1;
+  (*msg)->hello_msg = hello_msg;
+  return 0;
+
+ error:
+  if(header != NULL)
+    free(header);
+  if(hello_msg!=NULL)
+    free(hello_msg);
+  if(*msg != NULL)
+    free(*msg);
+  LOG_E(MAC, "%s: an error occured\n", __FUNCTION__);
+  return -1;
+}
+
+
+int proto_agent_destroy_hello(Protocol__FlexsplitMessage *msg)
+{
+  if(msg->msg_case != PROTOCOL__FLEXSPLIT_MESSAGE__MSG_HELLO_MSG)
+    goto error;
+
+  free(msg->hello_msg->header);
+  free(msg->hello_msg);
+  free(msg);
+  return 0;
+
+ error:
+  LOG_E(MAC, "%s: an error occured\n", __FUNCTION__);
+  return -1;
+}
+
+int proto_agent_echo_request(mod_id_t mod_id, const void* params, Protocol__FlexsplitMessage **msg)
+{
+  Protocol__FspHeader *header;
+  Protocol__FspEchoRequest *echo_request_msg = NULL;
+
+  xid_t xid = mod_id;
+  if (fsp_create_header(xid, PROTOCOL__FSP_TYPE__FSPT_ECHO_REQUEST, &header) != 0)
+    goto error;
+  LOG_D(PROTO_AGENT, "creating the echo request message\n");
+
+  echo_request_msg = malloc(sizeof(Protocol__FspEchoRequest));
+  if(echo_request_msg == NULL)
+    goto error;
+
+  protocol__fsp_echo_request__init(echo_request_msg);
+  echo_request_msg->header = header;
+
+  *msg = malloc(sizeof(Protocol__FlexsplitMessage));
+  if(*msg == NULL)
+    goto error;
+  protocol__flexsplit_message__init(*msg);
+
+  LOG_D(PROTO_AGENT,"setting the message direction to %d\n", PROTOCOL__FLEXSPLIT_MESSAGE__MSG_ECHO_REQUEST_MSG);
+  (*msg)->msg_case = PROTOCOL__FLEXSPLIT_MESSAGE__MSG_ECHO_REQUEST_MSG;
+  (*msg)->msg_dir = PROTOCOL__FLEXSPLIT_DIRECTION__INITIATING_MESSAGE;
+  (*msg)->has_msg_dir = 1;
+  (*msg)->echo_request_msg = echo_request_msg;
+  return 0;
+
+ error:
+  if(header != NULL)
+    free(header);
+  if(echo_request_msg != NULL)
+    free(echo_request_msg);
+  if(*msg != NULL)
+    free(*msg);
+  return -1;
+}
+
+int proto_agent_destroy_echo_request(Protocol__FlexsplitMessage *msg)
+{
+  if(msg->msg_case != PROTOCOL__FLEXSPLIT_MESSAGE__MSG_ECHO_REQUEST_MSG)
+    goto error;
+
+  free(msg->echo_request_msg->header);
+  free(msg->echo_request_msg);
+  free(msg);
+  return 0;
+
+ error:
+  LOG_E(MAC, "%s: an error occured\n", __FUNCTION__);
+  return -1;
+}
+
+int proto_agent_echo_reply(mod_id_t mod_id, const void *params, Protocol__FlexsplitMessage **msg)
+{
+  xid_t xid;
+  Protocol__FlexsplitMessage *input = (Protocol__FlexsplitMessage *)params;
+  Protocol__FspEchoRequest *echo_req = input->echo_request_msg;
+  Protocol__FspEchoReply *echo_reply_msg = NULL;
+  xid = (echo_req->header)->xid;
+
+  LOG_D(PROTO_AGENT, "creating the echo reply message\n");
+  Protocol__FspHeader *header;
+  if (fsp_create_header(xid, PROTOCOL__FSP_TYPE__FSPT_ECHO_REPLY, &header) != 0)
+    goto error;
+
+  echo_reply_msg = malloc(sizeof(Protocol__FspEchoReply));
+  if(echo_reply_msg == NULL)
+    goto error;
+  protocol__fsp_echo_reply__init(echo_reply_msg);
+  echo_reply_msg->header = header;
+
+  *msg = malloc(sizeof(Protocol__FlexsplitMessage));
+  if(*msg == NULL)
+    goto error;
+  protocol__flexsplit_message__init(*msg);
+  (*msg)->msg_case = PROTOCOL__FLEXSPLIT_MESSAGE__MSG_ECHO_REPLY_MSG;
+  (*msg)->msg_dir = PROTOCOL__FLEXSPLIT_DIRECTION__SUCCESSFUL_OUTCOME;
+  (*msg)->has_msg_dir = 1;
+  (*msg)->echo_reply_msg = echo_reply_msg;
+  return 0;
+
+ error:
+  if(header != NULL)
+    free(header);
+  if(echo_reply_msg != NULL)
+    free(echo_reply_msg);
+  if(*msg != NULL)
+    free(*msg);
+  LOG_E(MAC, "%s: an error occured\n", __FUNCTION__);
+  return -1;
+}
+
+int proto_agent_destroy_echo_reply(Protocol__FlexsplitMessage *msg) {
+  if(msg->msg_case != PROTOCOL__FLEXSPLIT_MESSAGE__MSG_ECHO_REPLY_MSG)
+    goto error;
+
+  free(msg->echo_reply_msg->header);
+  free(msg->echo_reply_msg);
+  free(msg);
+  return 0;
+
+ error:
+  LOG_E(MAC, "%s: an error occured\n", __FUNCTION__);
+  return -1;
+}
diff --git a/openair2/LAYER2/PROTO_AGENT/proto_agent_common.h b/openair2/LAYER2/PROTO_AGENT/proto_agent_common.h
new file mode 100644
index 0000000000000000000000000000000000000000..70e6b2a84ec4b09f1ea2221bf10482bd26bc6f0a
--- /dev/null
+++ b/openair2/LAYER2/PROTO_AGENT/proto_agent_common.h
@@ -0,0 +1,147 @@
+/*******************************************************************************
+    OpenAirInterface
+    Copyright(c) 1999 - 2014 Eurecom
+
+    OpenAirInterface is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+
+    OpenAirInterface 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 OpenAirInterface.The full GNU General Public License is
+   included in this distribution in the file called "COPYING". If not,
+   see <http://www.gnu.org/licenses/>.
+
+  Contact Information
+  OpenAirInterface Admin: openair_admin@eurecom.fr
+  OpenAirInterface Tech : openair_tech@eurecom.fr
+  OpenAirInterface Dev  : openair4g-devel@lists.eurecom.fr
+
+  Address      : Eurecom, Compus SophiaTech 450, route des chappes, 06451 Biot, France.
+
+ *******************************************************************************/
+
+/*! \file enb_agent_common.h
+ * \brief common message primitves and utilities 
+ * \author Navid Nikaein and Xenofon Foukas
+ * \date 2016
+ * \version 0.1
+ */
+
+
+
+#ifndef PROTO_AGENT_COMMON_H_
+#define PROTO_AGENT_COMMON_H_
+
+#include <time.h>
+
+#include "flexsplit.pb-c.h"
+
+// Do not need these
+//#include "stats_messages.pb-c.h"
+//#include "stats_common.pb-c.h"
+
+#include "proto_agent_defs.h"
+//#include "ENB_APP/enb_config.h"
+#include "UTIL/MEM/mem_block.h"
+
+//#include "LAYER2/MAC/extern.h"
+//#include "LAYER2/RLC/rlc.h"
+
+# include "tree.h"
+# include "intertask_interface.h"
+
+#define FLEXSPLIT_VERSION 0
+
+typedef int (*proto_agent_message_decoded_callback)(
+	mod_id_t mod_id,
+       	const void *params,
+	Protocol__FlexsplitMessage **msg
+);
+
+typedef int (*proto_agent_message_destruction_callback)(
+	Protocol__FlexsplitMessage *msg
+);
+
+
+uint32_t ack_result;
+
+/**********************************
+ * progRAN protocol messages helper 
+ * functions and generic handlers
+ **********************************/
+
+int proto_agent_serialize_message(Protocol__FlexsplitMessage *msg, uint8_t **buf, int *size);
+int proto_agent_deserialize_message(void *data, int size, Protocol__FlexsplitMessage **msg);
+
+uint8_t *proto_agent_pack_message(Protocol__FlexsplitMessage *msg, int *size);
+
+err_code_t proto_agent_destroy_flexsplit_message(Protocol__FlexsplitMessage *msg);
+
+int fsp_create_header(xid_t xid, Protocol__FspType type, Protocol__FspHeader **header);
+
+int proto_agent_hello(mod_id_t mod_id, const void *params, Protocol__FlexsplitMessage **msg);
+int proto_agent_destroy_hello(Protocol__FlexsplitMessage *msg);
+int proto_agent_echo_request(mod_id_t mod_id, const void *params, Protocol__FlexsplitMessage **msg);
+int proto_agent_destroy_echo_request(Protocol__FlexsplitMessage *msg);
+int proto_agent_echo_reply(mod_id_t mod_id, const void *params, Protocol__FlexsplitMessage **msg);
+int proto_agent_destroy_echo_reply(Protocol__FlexsplitMessage *msg);
+
+int proto_agent_pdcp_data_req(mod_id_t mod_id, const void *params, Protocol__FlexsplitMessage **msg);
+int proto_agent_pdcp_data_req_process(mod_id_t mod_id, const void *params, Protocol__FlexsplitMessage **msg);
+int proto_agent_destroy_pdcp_data_req(Protocol__FlexsplitMessage *msg);
+int proto_agent_pdcp_data_ind(mod_id_t mod_id, const void *params, Protocol__FlexsplitMessage **msg);
+int proto_agent_destroy_pdcp_data_ind(Protocol__FlexsplitMessage *msg);
+int proto_agent_pdcp_data_ind_process(mod_id_t mod_id, const void *params, Protocol__FlexsplitMessage **msg);
+
+int just_print(mod_id_t mod_id, const void *params, Protocol__FlexsplitMessage **msg);
+
+
+int proto_agent_get_ack_result(mod_id_t mod_id, const void *params, Protocol__FlexsplitMessage **msg);
+
+
+Protocol__FlexsplitMessage* proto_agent_handle_message (mod_id_t mod_id, 
+						    uint8_t *data, 
+						    int size);
+
+Protocol__FlexsplitMessage *proto_agent_handle_timed_task(void *args);
+
+typedef struct _data_req_args data_req_args;
+typedef struct _dl_data_args dl_data_args;
+
+struct _data_req_args{
+  const protocol_ctxt_t* ctxt;
+  srb_flag_t srb_flag;
+  MBMS_flag_t MBMS_flag;
+  rb_id_t rb_id; 
+  mui_t mui;
+  confirm_t confirm;
+  sdu_size_t sdu_size;
+  mem_block_t *sdu_p;
+};
+
+struct _dl_data_args{
+  uint8_t pdu_type;
+  uint32_t sn;
+  frame_t frame;
+  sub_frame_t subframe;
+  rnti_t rnti;
+  sdu_size_t sdu_size;
+  mem_block_t *sdu_p;
+};
+
+
+#endif
+
+
+
+
+
+
+
diff --git a/openair2/LAYER2/PROTO_AGENT/proto_agent_defs.h b/openair2/LAYER2/PROTO_AGENT/proto_agent_defs.h
new file mode 100644
index 0000000000000000000000000000000000000000..08c91e70850cf87d189bf01bdd0d67057d3a3b76
--- /dev/null
+++ b/openair2/LAYER2/PROTO_AGENT/proto_agent_defs.h
@@ -0,0 +1,126 @@
+/*******************************************************************************
+    OpenAirInterface
+    Copyright(c) 1999 - 2016 Eurecom
+
+    OpenAirInterface is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+
+    OpenAirInterface 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 OpenAirInterface.The full GNU General Public License is
+   included in this distribution in the file called "COPYING". If not,
+   see <http://www.gnu.org/licenses/>.
+
+  Contact Information
+  OpenAirInterface Admin: openair_admin@eurecom.fr
+  OpenAirInterface Tech : openair_tech@eurecom.fr
+  OpenAirInterface Dev  : openair4g-devel@lists.eurecom.fr
+
+  Address      : Eurecom, Compus SophiaTech 450, route des chappes, 06451 Biot, France.
+
+ *******************************************************************************/
+
+/*! \file enb_agent_defs.h
+ * \brief enb agent common definitions 
+ * \author Navid Nikaein and Xenofon Foukas
+ * \date 2016
+ * \version 0.1
+ */
+#ifndef PROTO_AGENT_DEFS_H_
+#define PROTO_AGENT_DEFS_H_
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <pthread.h>
+#include <string.h>
+
+#include "openairinterface5g_limits.h"
+#include "UTIL/ASYNC_IF/link_manager.h"
+
+#define DEFAULT_PROTO_AGENT_IPv4_ADDRESS "127.0.0.1"
+#define DEFAULT_PROTO_AGENT_PORT          2210
+#define DEFAULT_PROTO_AGENT_CACHE        "/mnt/oai_agent_cache"
+
+typedef enum {
+  
+  PROTO_AGENT_DEFAULT=0,
+  
+  ENB_AGENT_PHY=1,
+  ENB_AGENT_MAC=2,
+  ENB_AGENT_RLC=3,
+  ENB_AGENT_PDCP=4,
+  ENB_AGENT_RRC=5,
+  ENB_AGENT_S1AP=6,
+  ENB_AGENT_GTP=7,
+  ENB_AGENT_X2AP=8,
+
+  ENB_AGENT_MAX=9,
+    
+} proto_agent_id_t;
+
+/*
+typedef enum {
+  ENB_AGENT_ACTION_NONE = 0x0,
+
+  ENB_AGENT_ACTION_SEND = 0x1,
+
+  ENB_AGENT_ACTION_APPLY = 0x2,
+
+  ENB_AGENT_ACTION_CLEAR = 0x4,
+
+  ENB_AGENT_ACTION_WRITE = 0x8,
+
+  ENB_AGENT_ACTION_FILTER = 0x10,
+
+  ENB_AGENT_ACTION_PREPROCESS = 0x20,
+
+  ENB_AGENT_ACTION_METER = 0x40,
+  
+  ENB_AGENT_ACTION_MAX = 0x7f,
+} agent_action_t;
+*/
+/*
+typedef enum {
+  
+  RAN_LTE_OAI= 0,
+  
+ RAN_NAME_MAX = 0x7f,
+} ran_name_t;
+*/
+typedef uint8_t xid_t;  
+typedef uint8_t mod_id_t;  // module or enb id 
+typedef uint8_t lcid_t;
+typedef int32_t err_code_t;
+
+typedef struct {
+  /* general info */ 
+ 
+  /* stats */
+
+  uint32_t total_rx_msg;
+  uint32_t total_tx_msg;
+   
+  uint32_t rx_msg[NUMBER_OF_eNB_MAX];
+  uint32_t tx_msg[NUMBER_OF_eNB_MAX];
+
+} proto_agent_info_t;
+
+/* forward declaration */
+struct proto_agent_channel_s;
+
+typedef struct proto_agent_instance_s {
+  mod_id_t    mod_id;
+  proto_agent_info_t agent_info;
+  struct proto_agent_channel_s *channel;
+  pthread_t   recv_thread;
+  uint8_t     exit;
+} proto_agent_instance_t;
+
+#endif 
diff --git a/openair2/LAYER2/PROTO_AGENT/proto_agent_handler.c b/openair2/LAYER2/PROTO_AGENT/proto_agent_handler.c
new file mode 100644
index 0000000000000000000000000000000000000000..cb65da28039c5012ade0ed08d7f8bcfee1223104
--- /dev/null
+++ b/openair2/LAYER2/PROTO_AGENT/proto_agent_handler.c
@@ -0,0 +1,146 @@
+/*******************************************************************************
+    OpenAirInterface
+    Copyright(c) 1999 - 2014 Eurecom
+
+    OpenAirInterface is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+
+    OpenAirInterface 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 OpenAirInterface.The full GNU General Public License is
+   included in this distribution in the file called "COPYING". If not,
+   see <http://www.gnu.org/licenses/>.
+
+  Contact Information
+  OpenAirInterface Admin: openair_admin@eurecom.fr
+  OpenAirInterface Tech : openair_tech@eurecom.fr
+  OpenAirInterface Dev  : openair4g-devel@lists.eurecom.fr
+
+  Address      : Eurecom, Compus SophiaTech 450, route des chappes, 06451 Biot, France.
+
+ *******************************************************************************/
+
+/*! \file enb_agent_handler.c
+ * \brief enb agent tx and rx message handler 
+ * \author Navid Nikaein and Xenofon Foukas 
+ * \date 2016
+ * \version 0.1
+ */
+
+
+#include "proto_agent_common.h"
+#include "common/utils/LOG/log.h"
+#include "assertions.h"
+
+proto_agent_message_decoded_callback proto_agent_messages_callback[][3] = {
+  {proto_agent_hello, 0, 0},                 /* agent hello */
+  {proto_agent_echo_reply, 0, 0},            /* echo */
+  {0, just_print, 0},                        /* just print */
+  {proto_agent_pdcp_data_req_process, proto_agent_pdcp_data_req_process, 0}, /* PDCP data REQ */
+  {0, proto_agent_get_ack_result, 0},        /* get ACK result */
+  {proto_agent_pdcp_data_ind_process, proto_agent_pdcp_data_ind_process, 0}, /* PDCP data IND */
+  {0, just_print, 0},                        /* just print */
+};
+
+proto_agent_message_destruction_callback proto_message_destruction_callback[] = {
+  proto_agent_destroy_hello,
+  proto_agent_destroy_echo_request,
+  proto_agent_destroy_echo_reply,
+  proto_agent_destroy_pdcp_data_req,
+  0,
+  proto_agent_destroy_pdcp_data_ind,
+  0,
+};
+
+//static const char *proto_agent_direction2String[] = {
+//  "", /* not_set  */
+//  "originating message", /* originating message */
+//  "successfull outcome", /* successfull outcome */
+//  "unsuccessfull outcome", /* unsuccessfull outcome */
+//};
+
+
+Protocol__FlexsplitMessage* proto_agent_handle_message (mod_id_t mod_id,
+						    uint8_t *data, 
+						    int size){
+  
+  Protocol__FlexsplitMessage *decoded_message = NULL;
+  Protocol__FlexsplitMessage *reply_message = NULL;
+  err_code_t err_code;
+  DevAssert(data != NULL);
+
+  LOG_D(PROTO_AGENT, "Deserializing message with size %u \n", size);
+  if (proto_agent_deserialize_message(data, (int) size, &decoded_message) < 0) {
+    err_code= PROTOCOL__FLEXSPLIT_ERR__MSG_DECODING;
+    goto error; 
+  }
+  /* after deserialization, we don't need the original data memory anymore */
+  free(data);
+  Protocol__FspHeader *header = (Protocol__FspHeader*) decoded_message;
+  if (header->has_type)
+   {
+    LOG_D(PROTO_AGENT, "Deserialized MSG type is %d and %u\n", decoded_message->msg_case, decoded_message->msg_dir);
+   }
+
+  if ((decoded_message->msg_case > sizeof(proto_agent_messages_callback) / (3*sizeof(proto_agent_message_decoded_callback))) || 
+      (decoded_message->msg_dir > PROTOCOL__FLEXSPLIT_DIRECTION__UNSUCCESSFUL_OUTCOME))
+  {
+      err_code= PROTOCOL__FLEXSPLIT_ERR__MSG_NOT_HANDLED;
+      LOG_D(PROTO_AGENT,"Handling message: MSG NOT handled, going to error\n");
+      goto error;
+  }
+
+  
+  err_code = ((*proto_agent_messages_callback[decoded_message->msg_case-1][decoded_message->msg_dir-1])(mod_id, (void *) decoded_message, &reply_message));
+
+  if ( err_code < 0 )
+  {
+    LOG_I(PROTO_AGENT, "decoded_message case : %d, direction : %d \n", decoded_message->msg_case-1, decoded_message->msg_dir-1);
+    goto error;
+  }
+
+  protocol__flexsplit_message__free_unpacked(decoded_message, NULL);
+  LOG_D(PROTO_AGENT,"Returning REPLY message after the callback\n");
+  return reply_message;
+  
+ error:
+  LOG_E(PROTO_AGENT,"errno %d occured\n",err_code);
+  return NULL;
+}
+
+
+
+uint8_t *proto_agent_pack_message(Protocol__FlexsplitMessage *msg, int *size)
+{
+  uint8_t *buffer;
+  err_code_t err_code = PROTOCOL__FLEXSPLIT_ERR__NO_ERR;
+  
+  if (proto_agent_serialize_message(msg, &buffer, size) < 0 ) {
+    err_code = PROTOCOL__FLEXSPLIT_ERR__MSG_ENCODING;
+    goto error;
+  }
+  
+  if (proto_message_destruction_callback[msg->msg_case-1])
+    err_code = ((*proto_message_destruction_callback[msg->msg_case-1])(msg));
+  
+  DevAssert(buffer !=NULL);
+  
+  LOG_D(PROTO_AGENT,"Serialized the enb mac stats reply (size %d)\n", *size);
+  return buffer;
+  
+ error : 
+  LOG_E(PROTO_AGENT,"errno %d occured\n",err_code);
+  
+  return NULL;   
+}
+
+err_code_t proto_agent_destroy_flexsplit_message(Protocol__FlexsplitMessage *msg) {
+  return ((*proto_message_destruction_callback[msg->msg_case-1])(msg));
+}
diff --git a/openair2/LAYER2/PROTO_AGENT/proto_agent_net_comm.c b/openair2/LAYER2/PROTO_AGENT/proto_agent_net_comm.c
new file mode 100644
index 0000000000000000000000000000000000000000..f64a58f8e1584580bcc25180f7edd8fca0e282ce
--- /dev/null
+++ b/openair2/LAYER2/PROTO_AGENT/proto_agent_net_comm.c
@@ -0,0 +1,160 @@
+/*******************************************************************************
+    OpenAirInterface
+    Copyright(c) 1999 - 2016 Eurecom
+
+    OpenAirInterface is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+
+    OpenAirInterface 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 OpenAirInterface.The full GNU General Public License is
+   included in this distribution in the file called "COPYING". If not,
+   see <http://www.gnu.org/licenses/>.
+
+  Contact Information
+  OpenAirInterface Admin: openair_admin@eurecom.fr
+  OpenAirInterface Tech : openair_tech@eurecom.fr
+  OpenAirInterface Dev  : openair4g-devel@lists.eurecom.fr
+
+  Address      : Eurecom, Compus SophiaTech 450, route des chappes, 06451 Biot, France.
+
+ *******************************************************************************/
+
+/*! \file enb_agent_net_comm.c
+ * \brief enb agent network interface abstraction 
+ * \author Xenofon Foukas
+ * \date 2016
+ * \version 0.1
+ */
+
+#include "proto_agent_net_comm.h"
+#include "common/utils/LOG/log.h"
+
+proto_agent_channel_t *proto_channel[NUMBER_OF_eNB_MAX][ENB_AGENT_MAX];
+proto_agent_channel_instance_t channel_instance;
+int proto_agent_channel_id = 0;
+
+int proto_agent_register_channel(mod_id_t mod_id, proto_agent_channel_t *channel, proto_agent_id_t agent_id) {
+  int i;
+
+  if (channel == NULL) {
+    return -1;
+  }
+
+  if (agent_id == ENB_AGENT_MAX) {
+    for (i = 0; i < ENB_AGENT_MAX; i++) {
+      proto_channel[mod_id][i] = channel;
+    }
+  } else {
+    proto_channel[mod_id][agent_id] = channel;
+  }
+  return 0;
+}
+
+void proto_agent_unregister_channel(mod_id_t mod_id, proto_agent_id_t agent_id) {
+  int i;
+
+  if (agent_id == ENB_AGENT_MAX) {
+    for (i = 0; i < ENB_AGENT_MAX; i++) {
+      proto_channel[mod_id][i] = NULL;
+    }
+  } else {
+    proto_channel[mod_id][agent_id] = NULL;
+  }
+}
+
+int proto_agent_create_channel(void *channel_info,
+			       int (*msg_send)(void *data, int size, int priority, void *channel_info),
+			       int (*msg_recv)(void **data, int *priority, void *channel_info),
+			     void (*release)(proto_agent_channel_t *channel)) {
+  
+  int channel_id = ++proto_agent_channel_id;
+  proto_agent_channel_t *channel = (proto_agent_channel_t *) malloc(sizeof(proto_agent_channel_t));
+  channel->channel_id = channel_id;
+  channel->channel_info = channel_info;
+  channel->msg_send = msg_send;
+  channel->msg_recv = msg_recv;
+  channel->release = release;
+  
+  /*element should be a real pointer*/
+  RB_INSERT(proto_agent_channel_map, &channel_instance.proto_agent_head, channel); 
+  
+  LOG_D(PROTO_AGENT, "Created a new channel with id 0x%x\n", channel->channel_id);
+ 
+  return channel_id; 
+}
+
+int proto_agent_destroy_channel(int channel_id) {
+  int i, j;
+
+  /*Check to see if channel exists*/
+  struct proto_agent_channel_s *e = NULL;
+  struct proto_agent_channel_s search;
+  memset(&search, 0, sizeof(struct proto_agent_channel_s));
+
+  e = RB_FIND(proto_agent_channel_map, &channel_instance.proto_agent_head, &search);
+
+  if (e == NULL) {
+    return -1;
+  }
+
+  /*Unregister the channel from all agents*/
+  for (i = 0; i < NUMBER_OF_eNB_MAX; i++) {
+    for (j = 0; j < ENB_AGENT_MAX; j++) {
+      if (proto_channel[i][j] != NULL) {
+	if (proto_channel[i][j]->channel_id == e->channel_id) {
+	  proto_channel[i][j] = NULL;
+	}
+      }
+    }
+  }
+
+  /*Remove the channel from the tree and free memory*/
+  RB_REMOVE(proto_agent_channel_map, &channel_instance.proto_agent_head, e);
+  e->release(e);
+  free(e);
+
+  return 0;
+}
+
+err_code_t proto_agent_init_channel_container(void) {
+  int i, j;
+  LOG_D(PROTO_AGENT, "init RB tree for channel container\n");
+
+  RB_INIT(&channel_instance.proto_agent_head);
+
+  for (i = 0; i < NUMBER_OF_eNB_MAX; i++) {
+    for (j = 0; j < ENB_AGENT_MAX; j++) {
+    proto_channel[i][j] = NULL;
+    }
+  }
+
+  return 0;
+}
+
+RB_GENERATE(proto_agent_channel_map,proto_agent_channel_s, entry, proto_agent_compare_channel);
+
+int proto_agent_compare_channel(struct proto_agent_channel_s *a, struct proto_agent_channel_s *b) {
+  if (a->channel_id < b->channel_id) return -1;
+  if (a->channel_id > b->channel_id) return 1;
+
+  // equal timers
+  return 0;
+}
+
+proto_agent_channel_t * proto_agent_get_channel(int channel_id) {
+  
+  struct proto_agent_channel_s search;
+  memset(&search, 0, sizeof(struct proto_agent_channel_s));
+  search.channel_id = channel_id;
+  
+  return  RB_FIND(proto_agent_channel_map, &channel_instance.proto_agent_head, &search);
+  
+}
diff --git a/openair2/LAYER2/PROTO_AGENT/proto_agent_net_comm.h b/openair2/LAYER2/PROTO_AGENT/proto_agent_net_comm.h
new file mode 100644
index 0000000000000000000000000000000000000000..c956bf48b1daf93e435c7e15a800d196151f214e
--- /dev/null
+++ b/openair2/LAYER2/PROTO_AGENT/proto_agent_net_comm.h
@@ -0,0 +1,90 @@
+/*******************************************************************************
+    OpenAirInterface
+    Copyright(c) 1999 - 2016 Eurecom
+
+    OpenAirInterface is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+
+    OpenAirInterface 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 OpenAirInterface.The full GNU General Public License is
+   included in this distribution in the file called "COPYING". If not,
+   see <http://www.gnu.org/licenses/>.
+
+  Contact Information
+  OpenAirInterface Admin: openair_admin@eurecom.fr
+  OpenAirInterface Tech : openair_tech@eurecom.fr
+  OpenAirInterface Dev  : openair4g-devel@lists.eurecom.fr
+
+  Address      : Eurecom, Compus SophiaTech 450, route des chappes, 06451 Biot, France.
+
+ *******************************************************************************/
+
+/*! \file enb_agent_net_comm.h
+ * \brief enb agent network interface abstraction 
+ * \autho Xenofon Foukas
+ * \date 2016
+ * \version 0.1
+ */
+#ifndef PROTO_AGENT_NET_COMM_H_
+#define PROTO_AGENT_NET_COMM_H_
+
+#include "proto_agent_defs.h"
+
+#include "tree.h"
+#define ENB_AGENT_MAX 9
+
+/* forward declaration */
+struct proto_agent_async_channel_s;
+
+/*Channel related information used for Tx/Rx of protocol messages*/
+typedef struct proto_agent_channel_s {
+  RB_ENTRY(proto_agent_channel_s) entry;
+  int channel_id;
+  struct proto_agent_async_channel_s *channel_info;
+  /*Callbacks for channel message Tx and Rx*/
+  int (*msg_send)(void *data, int size, int priority, void *channel_info);
+  int (*msg_recv)(void **data, int *priority, void *channel_info);
+  void (*release)(struct proto_agent_channel_s *channel);
+} proto_agent_channel_t;
+
+typedef struct proto_agent_channel_instance_s{
+  RB_HEAD(proto_agent_channel_map, proto_agent_channel_s) proto_agent_head;
+} proto_agent_channel_instance_t;
+
+
+/*Register a channel to an agent. Use ENB_AGENT_MAX to register the
+ *same channel to all agents*/
+int proto_agent_register_channel(mod_id_t mod_id, proto_agent_channel_t *channel, proto_agent_id_t agent_id);
+
+/*Unregister the current channel of an agent. Use ENB_AGENT_MAX to unregister all channels*/
+void proto_agent_unregister_channel(mod_id_t mod_id, proto_agent_id_t agent_id);
+
+/*Create a new channel. Returns the id of the new channel or negative number otherwise*/
+int proto_agent_create_channel(void *channel_info,
+			       int (*msg_send)(void *data, int size, int priority, void *channel_info),
+			       int (*msg_recv)(void **data, int *priority, void *channel_info),
+			     void (*release)(proto_agent_channel_t *channel));
+
+/*Unregister a channel from all agents and destroy it. Returns 0 in case of success*/
+int proto_agent_destroy_channel(int channel_id);
+
+/*Return an agent communication channel based on its id*/
+proto_agent_channel_t * proto_agent_get_channel(int channel_id);
+
+/*Should be called before performing any channel operations*/
+err_code_t proto_agent_init_channel_container(void);
+
+int proto_agent_compare_channel(struct proto_agent_channel_s *a, struct proto_agent_channel_s *b);
+
+/* RB_PROTOTYPE is for .h files */
+RB_PROTOTYPE(proto_agent_channel_map, proto_agent_channel_s, entry, proto_agent_compare_channel);
+
+#endif /*ENB_AGENT_COMM_H_*/
diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.c
index 33ab7965e514ea878d7fcf648e0c11f3185c0fd7..30173b62ffacf81ebead5d3edca31e941a5b54e9 100644
--- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.c
+++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.c
@@ -40,7 +40,6 @@
 #include "LTE_UL-AM-RLC.h"
 #include "LTE_DL-AM-RLC.h"
 
-
 //-----------------------------------------------------------------------------
 uint32_t
 rlc_am_get_status_pdu_buffer_occupancy(
diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.h b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.h
index 75213116a7d04deef939aa86d742249f57efa5e0..c6a5ca721320915ccda6dbd98c5dbfca4e65a742 100644
--- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.h
+++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.h
@@ -65,7 +65,7 @@
           (rLC_Pp->is_data_plane) ? "DRB AM" : "SRB AM",\
           rLC_Pp->rb_id
 
-#define PROTOCOL_RLC_AM_MSC_FMT "[RNTI %"PRIx16" %s %02u]"
+#define PROTOCOL_RLC_AM_MSC_FMT "[RNTI %" PRIx16 " %s %02u]"
 #define PROTOCOL_RLC_AM_MSC_ARGS(CTXT_Pp, rLC_Pp) \
         CTXT_Pp->rnti,\
           (rLC_Pp->is_data_plane) ? "DRB AM" : "SRB AM",\
@@ -79,13 +79,13 @@
 	  if (pmtl_rc != 0){\
         if (pmtl_rc == EBUSY) {\
           MSC_LOG_EVENT((cTXT->enb_flag == ENB_FLAG_YES) ? MSC_RLC_ENB:MSC_RLC_UE,\
-                       "0 "PROTOCOL_RLC_AM_MSC_FMT" Warning try lock %s busy",\
+                       "0 " PROTOCOL_RLC_AM_MSC_FMT " Warning try lock %s busy",\
                        PROTOCOL_RLC_AM_MSC_ARGS(cTXT,rLC),\
                        #mUTEX);\
           pthread_mutex_lock(mUTEX);\
         } else {\
             MSC_LOG_EVENT((cTXT->enb_flag == ENB_FLAG_YES) ? MSC_RLC_ENB:MSC_RLC_UE,\
-            		"0 "PROTOCOL_RLC_AM_MSC_FMT" Error try lock %s %d",\
+                    "0 " PROTOCOL_RLC_AM_MSC_FMT " Error try lock %s %d",\
                     PROTOCOL_RLC_AM_MSC_ARGS(cTXT,rLC),\
                     #mUTEX, pmtl_rc);\
         }\
diff --git a/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um.h b/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um.h
index f2f91ff68e66ec6db1155950eda21d91afc5f430..fc6e449acf7b7e38dfd1d8dd229c24af58181e90 100644
--- a/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um.h
+++ b/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um.h
@@ -56,7 +56,7 @@
           rLC_Pp->rb_id,\
           __FUNCTION__
 
-#define PROTOCOL_RLC_UM_MSC_FMT "[RNTI %"PRIx16" %s %02u]"
+#define PROTOCOL_RLC_UM_MSC_FMT "[RNTI %" PRIx16 " %s %02u]"
 #define PROTOCOL_RLC_UM_MSC_ARGS(CTXT_Pp, rLC_Pp) \
         CTXT_Pp->rnti,\
           (rLC_Pp->is_data_plane) ? "DRB UM" : "SRB UM",\
@@ -69,13 +69,13 @@
 	  if (pmtl_rc != 0){\
         if (pmtl_rc == EBUSY) {\
           MSC_LOG_EVENT((cTXT->enb_flag == ENB_FLAG_YES) ? MSC_RLC_ENB:MSC_RLC_UE,\
-                       "0 "PROTOCOL_RLC_UM_MSC_FMT" Warning try lock %s busy",\
+                       "0 " PROTOCOL_RLC_UM_MSC_FMT " Warning try lock %s busy",\
                        PROTOCOL_RLC_UM_MSC_ARGS(cTXT,rLC),\
                        #mUTEX);\
           pthread_mutex_lock(mUTEX);\
         } else {\
             MSC_LOG_EVENT((cTXT->enb_flag == ENB_FLAG_YES) ? MSC_RLC_ENB:MSC_RLC_UE,\
-                       "0 "PROTOCOL_RLC_UM_MSC_FMT" Error try lock %s %d",\
+                       "0 " PROTOCOL_RLC_UM_MSC_FMT " Error try lock %s %d",\
                        PROTOCOL_RLC_UM_MSC_ARGS(cTXT,rLC),\
                        #mUTEX, pmtl_rc);\
         }\
diff --git a/openair2/LAYER2/RLC/rlc.c b/openair2/LAYER2/RLC/rlc.c
index 38d78f18fd86acc12d49a912518ecfa16810bf3d..96803652e806aa1dc58114e65bbd2038d6f325d5 100644
--- a/openair2/LAYER2/RLC/rlc.c
+++ b/openair2/LAYER2/RLC/rlc.c
@@ -37,6 +37,9 @@
 #include "targets/COMMON/openairinterface5g_limits.h"
 #include "assertions.h"
 
+#include "common/ran_context.h"
+extern RAN_CONTEXT_t RC;
+
 extern boolean_t pdcp_data_ind(
   const protocol_ctxt_t *const ctxt_pP,
   const srb_flag_t srb_flagP,
@@ -49,6 +52,10 @@ extern boolean_t pdcp_data_ind(
 //#define TRACE_RLC_PAYLOAD 1
 #define DEBUG_RLC_DATA_REQ 1
 
+
+
+#include "proto_agent.h"
+
 //-----------------------------------------------------------------------------
 void rlc_util_print_hex_octets(comp_name_t componentP, unsigned char *dataP, const signed long sizeP)
 //-----------------------------------------------------------------------------
@@ -323,6 +330,8 @@ rlc_op_status_t rlc_data_req     (const protocol_ctxt_t *const ctxt_pP,
 #endif
                                  ) {
   //-----------------------------------------------------------------------------
+  
+ 
   mem_block_t           *new_sdu_p    = NULL;
   rlc_mode_t             rlc_mode     = RLC_MODE_NONE;
   rlc_union_t           *rlc_union_p = NULL;
@@ -596,13 +605,28 @@ void rlc_data_ind     (
     T(T_ENB_RLC_UL, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->rnti), T_INT(rb_idP), T_INT(sdu_sizeP));
 
 #endif
-  pdcp_data_ind (
-    ctxt_pP,
-    srb_flagP,
-    MBMS_flagP,
-    rb_idP,
-    sdu_sizeP,
-    sdu_pP);
+
+#ifndef UETARGET
+  const ngran_node_t type = RC.rrc[ctxt_pP->module_id]->node_type;
+  AssertFatal(type != ngran_eNB_CU && type != ngran_ng_eNB_CU && type != ngran_gNB_CU,
+              "Can't be CU, bad node type %d\n", type);
+
+  if (NODE_IS_DU(type)) {
+     if (srb_flagP == 1) {
+       MessageDef *msg = itti_alloc_new_message(TASK_RLC_ENB, F1AP_UL_RRC_MESSAGE);
+       F1AP_UL_RRC_MESSAGE(msg).rnti = ctxt_pP->rnti;
+       F1AP_UL_RRC_MESSAGE(msg).srb_id = rb_idP;
+       F1AP_UL_RRC_MESSAGE(msg).rrc_container = sdu_pP->data;
+       F1AP_UL_RRC_MESSAGE(msg).rrc_container_length = sdu_sizeP;
+       itti_send_msg_to_task(TASK_DU_F1, ENB_MODULE_ID_TO_INSTANCE(ctxt_pP->module_id), msg);
+     } else {
+       proto_agent_send_pdcp_data_ind (ctxt_pP, srb_flagP, MBMS_flagP, rb_idP, sdu_sizeP, sdu_pP);
+     }
+  } else
+#endif
+  { // case monolithic eNodeB or UE
+    pdcp_data_ind(ctxt_pP, srb_flagP, MBMS_flagP, rb_idP, sdu_sizeP, sdu_pP);
+  }
 }
 //-----------------------------------------------------------------------------
 void rlc_data_conf     (const protocol_ctxt_t *const ctxt_pP,
@@ -647,12 +671,12 @@ rlc_module_init (void) {
     }
   }
 
-  for (k=0; k < RLC_MAX_MBMS_LC; k++) {
+    for (k=0; k < RLC_MAX_MBMS_LC; k++) {
     rlc_mbms_lcid2service_session_id_eNB[0][k].service_id = 0;
     rlc_mbms_lcid2service_session_id_eNB[0][k].session_id = 0;
-  }
+    }
 
-  for (k=0; k < NB_RB_MBMS_MAX; k++) {
+    for (k=0; k < NB_RB_MBMS_MAX; k++) {
     rlc_mbms_rbid2lcid_eNB[0][k] = RLC_LC_UNALLOCATED;
   }
 
diff --git a/openair2/LAYER2/RLC/rlc_mac.c b/openair2/LAYER2/RLC/rlc_mac.c
index d4ec487c853e9e270fcbb1c518bae6a5d8e79486..b539970704c3f89ba280f1c44202ea8abea369b4 100644
--- a/openair2/LAYER2/RLC/rlc_mac.c
+++ b/openair2/LAYER2/RLC/rlc_mac.c
@@ -261,12 +261,12 @@ void mac_rlc_data_ind     (
 #ifdef DEBUG_MAC_INTERFACE
 
   if (num_tbP) {
-    LOG_D(RLC, PROTOCOL_CTXT_FMT" MAC_RLC_DATA_IND on channel %d (%d), rb max %d, Num_tb %d\n",
+    LOG_D(RLC, PROTOCOL_CTXT_FMT" MAC_RLC_DATA_IND on channel %d (%d), rb max %d, tb_sizeP %d\n",
           PROTOCOL_CTXT_ARGS(&ctxt),
           channel_idP,
           RLC_MAX_LC,
           NB_RB_MAX,
-          num_tbP);
+          tb_sizeP);
   }
 
 #endif // DEBUG_MAC_INTERFACE
@@ -293,7 +293,7 @@ void mac_rlc_data_ind     (
     rlc_mode = rlc_union_p->mode;
   } else {
     rlc_mode = RLC_MODE_NONE;
-    //AssertFatal (0 , "%s RLC not configured rb id %u lcid %u module %u!\n", __FUNCTION__, rb_id, channel_idP, ue_module_idP);
+    //AssertFatal (0 , "%s RLC not configured lcid %u ! (h_rc %d)\n", __FUNCTION__,channel_idP,h_rc);
   }
 
   struct mac_data_ind data_ind = mac_rlc_deserialize_tb(buffer_pP, tb_sizeP, num_tbP, crcs_pP);
diff --git a/openair2/LAYER2/RLC/rlc_primitives.h b/openair2/LAYER2/RLC/rlc_primitives.h
index eb7b9ae0053b925a3d52132c99e3240b1658181d..bb83852775a581618757c7e9ef7be5c72caed146 100644
--- a/openair2/LAYER2/RLC/rlc_primitives.h
+++ b/openair2/LAYER2/RLC/rlc_primitives.h
@@ -202,4 +202,5 @@ struct crlc_primitive {
     struct crlc_status_ind c_status_ind;
   } primitive;
 };
+
 #endif
diff --git a/openair2/LAYER2/RLC/rlc_proto_agent_primitives.h b/openair2/LAYER2/RLC/rlc_proto_agent_primitives.h
new file mode 100644
index 0000000000000000000000000000000000000000..75ccc9fcdd001cd20a8a83a26b10a7755d517be5
--- /dev/null
+++ b/openair2/LAYER2/RLC/rlc_proto_agent_primitives.h
@@ -0,0 +1,16 @@
+
+#ifndef __PROTO_AGENT_RLC_PRIMITIVES_H__
+#define __PROTO_AGENT_RLC_PRIMITIVES_H__
+
+#include "RRC/LTE/rrc_defs.h"
+#include "LAYER2/PROTO_AGENT/proto_agent.h"
+// PROTO AGENT
+pthread_t async_server_thread;
+int async_server_thread_finalize (void);
+void async_server_thread_init (void);
+
+pthread_mutex_t async_server_lock;
+pthread_cond_t async_server_notify;
+int async_server_shutdown;
+
+#endif
diff --git a/openair2/LAYER2/openair2_proc.c b/openair2/LAYER2/openair2_proc.c
index 50c8ac58b430881edf33360a2c9e8b5591d4b881..2251344c47f1c6714bfdcf9b6c3a3ea613c0248f 100644
--- a/openair2/LAYER2/openair2_proc.c
+++ b/openair2/LAYER2/openair2_proc.c
@@ -622,3 +622,4 @@ int openair2_stats_read(char *buffer, char **my_buffer, off_t off, int length) {
 }
 
 #endif
+
diff --git a/openair2/NETWORK_DRIVER/UE_IP/netlink.c b/openair2/NETWORK_DRIVER/UE_IP/netlink.c
index 5089a28d94b6dfe3da4e80b78ad9cec8fa927758..658ae19aba91cc2718710f59f691ca58ba327a28 100644
--- a/openair2/NETWORK_DRIVER/UE_IP/netlink.c
+++ b/openair2/NETWORK_DRIVER/UE_IP/netlink.c
@@ -120,7 +120,7 @@ int ue_ip_netlink_init(void)
                 &nasmesh_mutex, // NULL
                 THIS_MODULE);
 #endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0) */
-             
+
 
 
   if (nas_nl_sk == NULL) {
diff --git a/openair2/PHY_INTERFACE/IF_Module.c b/openair2/PHY_INTERFACE/IF_Module.c
index 28055bfc2d52334acff100ba00a7d0e953d300e0..8d08b956cf2df5da90f6d5f32e774a2618aa0803 100644
--- a/openair2/PHY_INTERFACE/IF_Module.c
+++ b/openair2/PHY_INTERFACE/IF_Module.c
@@ -39,7 +39,7 @@ void handle_rach(UL_IND_t *UL_info) {
 		     );
   }
 
-#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) 
+#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
   if (UL_info->rach_ind_br.rach_indication_body.number_of_preambles>0) {
 
     AssertFatal(UL_info->rach_ind_br.rach_indication_body.number_of_preambles<5,"More than 4 preambles not supported\n");
diff --git a/openair2/PHY_INTERFACE/phy_stub_UE.c b/openair2/PHY_INTERFACE/phy_stub_UE.c
index 0c961d9fbbb99a4f6b938c88137f0e7533887f0e..8d625fbdc59337c86d4609e9a386314e411243c5 100644
--- a/openair2/PHY_INTERFACE/phy_stub_UE.c
+++ b/openair2/PHY_INTERFACE/phy_stub_UE.c
@@ -72,7 +72,7 @@ void fill_rx_indication_UE_MAC(module_id_t Mod_id,int frame,int subframe, UL_IND
 	  pdu->rx_indication_rel8.length         = buflen;
 	  pdu->rx_indication_rel8.offset         = 1;   // DJP - I dont understand - but broken unless 1 ????  0;  // filled in at the end of the UL_INFO formation
 
-	  // ulsch_buffer is necessary to keep its value. 
+	  // ulsch_buffer is necessary to keep its value.
 	  //pdu->data                              = ulsch_buffer;
 	  pdu->data = malloc(buflen);
 	  memcpy(pdu->data,ulsch_buffer,buflen);
@@ -181,7 +181,7 @@ void fill_rach_indication_UE_MAC(int Mod_id,int frame,int subframe, UL_IND_t *UL
 	// change for mutiple UE's simulation.
 	// pthread_mutex_lock(&UE_mac_inst[Mod_id].UL_INFO_mutex);
 	pthread_mutex_lock(&fill_ul_mutex.rach_mutex);
-	
+
 	// memory allocation and free memory of UL_INFO are done in UE_phy_stub_single_thread_rxn_txnp4.
 	// UL_INFO = (UL_IND_t*)malloc(sizeof(UL_IND_t));
 
diff --git a/openair2/RRC/L2_INTERFACE/openair_rrc_L2_interface.h b/openair2/RRC/L2_INTERFACE/openair_rrc_L2_interface.h
index 2e1d05038778f6d698e0323b68a019ecc5676172..270436b029d3b673a9aef9f11d6fa811097061aa 100644
--- a/openair2/RRC/L2_INTERFACE/openair_rrc_L2_interface.h
+++ b/openair2/RRC/L2_INTERFACE/openair_rrc_L2_interface.h
@@ -39,6 +39,7 @@ mac_rrc_data_req(
   const int             CC_idP,
   const frame_t         frameP,
   const rb_id_t         srb_idP,
+  const rnti_t          rntiP,
   const uint8_t         nb_tbP,
   uint8_t* const        buffer_pP,
   const uint8_t         mbsfn_sync_areaP
@@ -47,14 +48,15 @@ mac_rrc_data_req(
 /*int8_t
 mac_rrc_data_ind(
   const module_id_t     module_idP,
-  const int             CC_idP,
+  const int             CC_id,
   const frame_t         frameP,
   const sub_frame_t     sub_frameP,
+  const int             UE_id,
   const rnti_t          rntiP,
   const rb_id_t         srb_idP,
-  const uint8_t        *sduP,
+  const uint8_t*        sduP,
   const sdu_size_t      sdu_lenP,
-  const uint8_t         mbsfn_sync_area
+  const uint8_t         mbsfn_sync_areaP
 );
 
 int8_t
diff --git a/openair2/RRC/LITE/rrc_common.c b/openair2/RRC/LITE/rrc_common.c
index 736b16422b212da7834abd1e2be2bd2e27899a8d..027a6299927abdb01014c431914c0e0fdfcefe50 100644
--- a/openair2/RRC/LITE/rrc_common.c
+++ b/openair2/RRC/LITE/rrc_common.c
@@ -282,7 +282,7 @@ rrc_rx_tx(
         UE_rrc_inst[ctxt_pP->module_id].Info[enb_indexP].T310_active = 0;
         rrc_t310_expiration (ctxt_pP, enb_indexP);
         VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_RX_TX,VCD_FUNCTION_OUT);
-	LOG_I(RRC,"Returning RRC_PHY_RESYNCH: T310 expired\n"); 
+	LOG_I(RRC,"Returning RRC_PHY_RESYNCH: T310 expired\n");
         return RRC_PHY_RESYNCH;
       }
 
@@ -358,7 +358,7 @@ rrc_rx_tx(
       }
       if (ue_context_p->ue_context.ue_release_timer>0) {
 	ue_context_p->ue_context.ue_release_timer++;
-	if (ue_context_p->ue_context.ue_release_timer >= 
+	if (ue_context_p->ue_context.ue_release_timer >=
 	    ue_context_p->ue_context.ue_release_timer_thres) {
 	  LOG_I(RRC,"Removing UE %x instance (release timer %d)\n",ue_context_p->ue_context.rnti,ue_context_p->ue_context.ue_release_timer);
 	  ue_to_be_removed = ue_context_p;
@@ -493,4 +493,3 @@ binary_search_float(
 
   return first;
 }
-
diff --git a/openair2/RRC/LTE/L2_interface.c b/openair2/RRC/LTE/L2_interface.c
index 5929ac6689a6e19710370ce97b9a0a2efbe1a8b5..7bfeb43b53d333249b812a88f6ea4801423a34e2 100644
--- a/openair2/RRC/LTE/L2_interface.c
+++ b/openair2/RRC/LTE/L2_interface.c
@@ -42,7 +42,8 @@
 #endif
 
 #include "flexran_agent_extern.h"
-
+#undef C_RNTI // C_RNTI is used in F1AP generated code, prevent preprocessor replace
+#include "f1ap_du_rrc_message_transfer.h"
 
 extern RAN_CONTEXT_t RC;
 
@@ -53,6 +54,7 @@ mac_rrc_data_req(
   const int         CC_id,
   const frame_t     frameP,
   const rb_id_t     Srb_id,
+  const rnti_t      rnti,
   const uint8_t     Nb_tb,
   uint8_t    *const buffer_pP,
   const uint8_t     mbsfn_sync_area
@@ -139,14 +141,14 @@ mac_rrc_data_req(
   }
 
   if( (Srb_id & RAB_OFFSET ) == CCCH) {
-    LOG_T(RRC,"[eNB %d] Frame %d CCCH request (Srb_id %d)\n",Mod_idP,frameP, Srb_id);
 
-    if(RC.rrc[Mod_idP]->carrier[CC_id].Srb0.Active==0) {
-      LOG_E(RRC,"[eNB %d] CCCH Not active\n",Mod_idP);
-      return -1;
-    }
+    struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[Mod_idP],rnti);
+
+    if (ue_context_p == NULL) return(0);
+    eNB_RRC_UE_t *ue_p = &ue_context_p->ue_context;
+    LOG_T(RRC,"[eNB %d] Frame %d CCCH request (Srb_id %d, rnti %x)\n",Mod_idP,frameP, Srb_id,rnti);
 
-    Srb_info=&RC.rrc[Mod_idP]->carrier[CC_id].Srb0;
+    Srb_info=&ue_p->Srb0;
 
     // check if data is there for MAC
     if(Srb_info->Tx_buffer.payload_size>0) { //Fill buffer
@@ -219,6 +221,7 @@ mac_rrc_data_req(
   return(0);
 }
 
+
 //------------------------------------------------------------------------------
 int8_t
 mac_rrc_data_ind(
@@ -226,6 +229,7 @@ mac_rrc_data_ind(
   const int             CC_id,
   const frame_t         frameP,
   const sub_frame_t     sub_frameP,
+  const int             UE_id,
   const rnti_t          rntiP,
   const rb_id_t         srb_idP,
   const uint8_t        *sduP,
@@ -238,7 +242,25 @@ mac_rrc_data_ind(
 )
 //--------------------------------------------------------------------------
 {
-  SRB_INFO *Srb_info;
+
+
+  if (NODE_IS_DU(RC.rrc[module_idP]->node_type)) {
+    LOG_W(RRC,"[DU %d][RAPROC] Received SDU for CCCH on SRB %d length %d for UE id %d RNTI %x \n",
+            module_idP, srb_idP, sdu_lenP, UE_id, rntiP);
+  
+    /* do ITTI message */
+    DU_send_INITIAL_UL_RRC_MESSAGE_TRANSFER(
+      module_idP,
+      CC_id,
+      UE_id,
+      rntiP,  
+      sduP,
+      sdu_lenP
+    );
+    return(0);
+  } 
+
+  //SRB_INFO *Srb_info;
   protocol_ctxt_t ctxt;
   sdu_size_t      sdu_size = 0;
   /* for no gcc warnings */
@@ -249,16 +271,17 @@ mac_rrc_data_ind(
   PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, module_idP, ENB_FLAG_YES, rntiP, frameP, sub_frameP,0);
 
   if((srb_idP & RAB_OFFSET) == CCCH) {
-    Srb_info = &RC.rrc[module_idP]->carrier[CC_id].Srb0;
-    LOG_D(RRC,"[eNB %d] Received SDU for CCCH on SRB %d\n",module_idP,Srb_info->Srb_id);
+    LOG_D(RRC, "[eNB %d] Received SDU for CCCH on SRB %d\n", module_idP, srb_idP);
 #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
     ctxt.brOption = brOption;
-#endif    
+#endif
+    /*Srb_info = &RC.rrc[module_idP]->carrier[CC_id].Srb0;
     if (sdu_lenP > 0) {
       memcpy(Srb_info->Rx_buffer.Payload,sduP,sdu_lenP);
       Srb_info->Rx_buffer.payload_size = sdu_lenP;
       rrc_eNB_decode_ccch(&ctxt, Srb_info, CC_id);
-    }
+    }*/
+    if (sdu_lenP > 0)  rrc_eNB_decode_ccch(&ctxt, sduP, sdu_lenP, CC_id);
   }
 
   if((srb_idP & RAB_OFFSET) == DCCH) {
@@ -315,11 +338,9 @@ void mac_eNB_rrc_ul_failure(const module_id_t Mod_instP,
   } else {
     LOG_W(RRC,"Frame %d, Subframe %d: UL failure: UE %x unknown \n",frameP,subframeP,rntiP);
   }
-
-  if (rrc_agent_registered[Mod_instP]) {
-    agent_rrc_xface[Mod_instP]->flexran_agent_notify_ue_state_change(Mod_instP,
-        rntiP,
-        PROTOCOL__FLEX_UE_STATE_CHANGE_TYPE__FLUESC_DEACTIVATED);
+  if (flexran_agent_get_rrc_xface(Mod_instP)) {
+    flexran_agent_get_rrc_xface(Mod_instP)->flexran_agent_notify_ue_state_change(Mod_instP,
+								     rntiP, PROTOCOL__FLEX_UE_STATE_CHANGE_TYPE__FLUESC_DEACTIVATED);
   }
 
   rrc_mac_remove_ue(Mod_instP,rntiP);
diff --git a/openair2/RRC/LTE/L2_interface_common.c b/openair2/RRC/LTE/L2_interface_common.c
index c8553b59701e2331f5e42ccb7a895e09b1aced48..c17318d6018098c7e7e9b624c490b2bc8b99380c 100644
--- a/openair2/RRC/LTE/L2_interface_common.c
+++ b/openair2/RRC/LTE/L2_interface_common.c
@@ -44,6 +44,8 @@
 //#define RRC_DATA_REQ_DEBUG
 //#define DEBUG_RRC 1
 
+extern RAN_CONTEXT_t RC;
+
 //------------------------------------------------------------------------------
 uint8_t
 rrc_data_req(
@@ -94,6 +96,8 @@ rrc_data_req(
     RRC_DCCH_DATA_REQ (message_p).confirmp  = confirmP;
     RRC_DCCH_DATA_REQ (message_p).sdu_size  = sdu_sizeP;
     RRC_DCCH_DATA_REQ (message_p).sdu_p     = message_buffer;
+    //memcpy (RRC_DCCH_DATA_REQ (message_p).sdu_p, buffer_pP, sdu_sizeP);
+
     RRC_DCCH_DATA_REQ (message_p).mode      = modeP;
     RRC_DCCH_DATA_REQ (message_p).module_id = ctxt_pP->module_id;
     RRC_DCCH_DATA_REQ (message_p).rnti      = ctxt_pP->rnti;
@@ -103,6 +107,15 @@ rrc_data_req(
       ctxt_pP->enb_flag ? TASK_PDCP_ENB : TASK_PDCP_UE,
       ctxt_pP->instance,
       message_p);
+    LOG_I(RRC,"sent RRC_DCCH_DATA_REQ to TASK_PDCP_ENB\n");
+#ifndef UETARGET
+    /* Hack: only trigger PDCP if in CU, otherwise it is triggered by RU threads
+     * Ideally, PDCP would not neet to be triggered like this but react to ITTI
+     * messages automatically */
+    if (NODE_IS_CU(RC.rrc[ctxt_pP->module_id]->node_type))
+      pdcp_run(ctxt_pP);
+#endif
+
     return TRUE; // TODO should be changed to a CNF message later, currently RRC lite does not used the returned value anyway.
 
   }
diff --git a/openair2/RRC/LTE/rrc_defs.h b/openair2/RRC/LTE/rrc_defs.h
index b576a7e9339eeae767b6e2715c06c168dbb496b2..9cbef536fcab7f70a15a963bf35a3c583f41fa27 100644
--- a/openair2/RRC/LTE/rrc_defs.h
+++ b/openair2/RRC/LTE/rrc_defs.h
@@ -16,7 +16,7 @@
  * limitations under the License.
  *-------------------------------------------------------------------------------
  * For more information about the OpenAirInterface (OAI) Software Alliance:
- *      contact@openairinterface.org
+ *      conmnc_digit_lengtht@openairinterface.org
  */
 
 /*! \file RRC/LTE/defs.h
@@ -36,6 +36,7 @@
 #include <string.h>
 
 #include "collection/tree.h"
+#include "common/ngran_types.h"
 #include "rrc_types.h"
 //#include "PHY/phy_defs.h"
 #include "LAYER2/RLC/rlc.h"
@@ -663,8 +664,10 @@ typedef struct {
   uint32_t                              N_RB_DL;
   uint32_t                              pbch_repetition;
   LTE_BCCH_BCH_Message_t                mib;
+  LTE_BCCH_BCH_Message_t                *mib_DU;
   LTE_BCCH_DL_SCH_Message_t             siblock1;
   LTE_BCCH_DL_SCH_Message_t             siblock1_BR;
+  LTE_BCCH_DL_SCH_Message_t             *siblock1_DU;
   LTE_BCCH_DL_SCH_Message_t             systemInformation;
   LTE_BCCH_DL_SCH_Message_t             systemInformation_BR;
   //  SystemInformation_t               systemInformation;
@@ -691,14 +694,17 @@ typedef struct {
   LTE_SystemInformationBlockType21_r14_t *sib21;
   // End - TTN
   SRB_INFO                          SI;
-  SRB_INFO                          Srb0;
   uint8_t                           *paging[MAX_MOBILES_PER_ENB];
   uint32_t                           sizeof_paging[MAX_MOBILES_PER_ENB];
 } rrc_eNB_carrier_data_t;
 
+  
 typedef struct eNB_RRC_INST_s {
   /// southbound midhaul configuration
+  ngran_node_t                    node_type;
   eth_params_t                    eth_params_s;
+  char                            *node_name;
+  uint32_t                        node_id;
   rrc_eNB_carrier_data_t          carrier[MAX_NUM_CCs];
   uid_allocator_t                    uid_allocator; // for rrc_ue_head
   RB_HEAD(rrc_ue_tree_s, rrc_eNB_ue_context_s)     rrc_ue_head; // ue_context tree key search by rnti
@@ -720,6 +726,10 @@ typedef struct eNB_RRC_INST_s {
 
   //RRC configuration
   RrcConfigurationReq configuration;
+
+  /// NR cell id
+  uint64_t nr_cellid;
+
   // other RAN parameters
   int srb1_timer_poll_retransmit;
   int srb1_poll_pdu;
@@ -728,6 +738,11 @@ typedef struct eNB_RRC_INST_s {
   int srb1_timer_reordering;
   int srb1_timer_status_prohibit;
   int srs_enable[MAX_NUM_CCs];
+  int cell_info_configured;
+  pthread_mutex_t cell_info_mutex;
+  uint16_t sctp_in_streams;
+  uint16_t sctp_out_streams;
+
 } eNB_RRC_INST;
 
 #define MAX_UE_CAPABILITY_SIZE 255
diff --git a/openair2/RRC/LTE/rrc_eNB.c b/openair2/RRC/LTE/rrc_eNB.c
index fbc5d8f2564ff45a70a46ab0919f5ab002eeca0c..f330399901b4c604e56bde68928fd92a6f4a6d13 100644
--- a/openair2/RRC/LTE/rrc_eNB.c
+++ b/openair2/RRC/LTE/rrc_eNB.c
@@ -123,8 +123,6 @@ openair_rrc_on(
   for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
     rrc_config_buffer (&RC.rrc[ctxt_pP->module_id]->carrier[CC_id].SI, BCCH, 1);
     RC.rrc[ctxt_pP->module_id]->carrier[CC_id].SI.Active = 1;
-    rrc_config_buffer (&RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0, CCCH, 1);
-    RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Active = 1;
   }
 }
 
@@ -144,301 +142,368 @@ init_SI(
   LTE_SystemInformationBlockType1_v1310_IEs_t *sib1_v13ext=(LTE_SystemInformationBlockType1_v1310_IEs_t *)NULL;
 #endif
   LOG_D(RRC,"%s()\n\n\n\n",__FUNCTION__);
-  RC.rrc[ctxt_pP->module_id]->carrier[CC_id].MIB = (uint8_t *) malloc16(4);
-  // copy basic parameters
-  RC.rrc[ctxt_pP->module_id]->carrier[CC_id].physCellId      = configuration->Nid_cell[CC_id];
-  RC.rrc[ctxt_pP->module_id]->carrier[CC_id].p_eNB           = configuration->nb_antenna_ports[CC_id];
-  RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Ncp             = configuration->prefix_type[CC_id];
-  RC.rrc[ctxt_pP->module_id]->carrier[CC_id].dl_CarrierFreq  = configuration->downlink_frequency[CC_id];
-  RC.rrc[ctxt_pP->module_id]->carrier[CC_id].ul_CarrierFreq  = configuration->downlink_frequency[CC_id]+ configuration->uplink_frequency_offset[CC_id];
-  RC.rrc[ctxt_pP->module_id]->carrier[CC_id].eutra_band      = configuration->eutra_band[CC_id];
-  RC.rrc[ctxt_pP->module_id]->carrier[CC_id].N_RB_DL         = configuration->N_RB_DL[CC_id];
+  eNB_RRC_INST *rrc = RC.rrc[ctxt_pP->module_id];
+  rrc_eNB_carrier_data_t *carrier=&rrc->carrier[CC_id];
+
+  carrier->MIB = (uint8_t*) malloc16(4);
+  carrier->sizeof_SIB1 = 0;
+  carrier->sizeof_SIB23 = 0;
+  carrier->SIB1 = (uint8_t*) malloc16(32);
+  
+  AssertFatal(carrier->SIB1!=NULL,PROTOCOL_RRC_CTXT_FMT" init_SI: FATAL, no memory for SIB1 allocated\n",
+	      PROTOCOL_RRC_CTXT_ARGS(ctxt_pP));
+
+  LOG_I(RRC,"[eNB %d] Node type %d \n ", ctxt_pP->module_id, rrc->node_type);
+  if (NODE_IS_DU(rrc->node_type) || NODE_IS_MONOLITHIC(rrc->node_type)) {
+    // copy basic Cell parameters
+    carrier->physCellId      = configuration->Nid_cell[CC_id];
+    carrier->p_eNB           = configuration->nb_antenna_ports[CC_id];
+    carrier->Ncp             = configuration->prefix_type[CC_id];
+    carrier->dl_CarrierFreq  = configuration->downlink_frequency[CC_id];
+    carrier->ul_CarrierFreq  = configuration->downlink_frequency[CC_id]+ configuration->uplink_frequency_offset[CC_id];
+    carrier->eutra_band      = configuration->eutra_band[CC_id];
+    carrier->N_RB_DL         = configuration->N_RB_DL[CC_id];
 #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
-  RC.rrc[ctxt_pP->module_id]->carrier[CC_id].pbch_repetition = configuration->pbch_repetition[CC_id];
+    carrier->pbch_repetition = configuration->pbch_repetition[CC_id];
+    LOG_I(RRC, "configuration->schedulingInfoSIB1_BR_r13[CC_id] %d\n",(int)configuration->schedulingInfoSIB1_BR_r13[CC_id]);
 #endif
-  LOG_I(RRC, "Configuring MIB (N_RB_DL %d,phich_Resource %d,phich_Duration %d)\n",
-        configuration->N_RB_DL[CC_id],
-        (int)configuration->radioresourceconfig[CC_id].phich_resource,
-        (int)configuration->radioresourceconfig[CC_id].phich_duration);
+
+    LOG_I(RRC, "Configuring MIB (N_RB_DL %d,phich_Resource %d,phich_Duration %d)\n", 
+	  (int)configuration->N_RB_DL[CC_id],
+	  (int)configuration->radioresourceconfig[CC_id].phich_resource,
+	  (int)configuration->radioresourceconfig[CC_id].phich_duration);
+
+    carrier->sizeof_MIB = do_MIB(&rrc->carrier[CC_id],
+                                 configuration->N_RB_DL[CC_id],
+                                 configuration->radioresourceconfig[CC_id].phich_resource,
+                                 configuration->radioresourceconfig[CC_id].phich_duration,
+                                 0
 #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
-  LOG_I(RRC, "configuration->schedulingInfoSIB1_BR_r13[CC_id] %d\n",(int)configuration->schedulingInfoSIB1_BR_r13[CC_id]);
+                                 ,configuration->schedulingInfoSIB1_BR_r13[CC_id]
 #endif
-  do_MIB(&RC.rrc[ctxt_pP->module_id]->carrier[CC_id],
-         configuration->N_RB_DL[CC_id],
-         (int)configuration->radioresourceconfig[CC_id].phich_resource,
-         (int)configuration->radioresourceconfig[CC_id].phich_duration,
-         0
+   );
+    
+    
+    carrier->sizeof_SIB1 = do_SIB1(&rrc->carrier[CC_id],
+                                   ctxt_pP->module_id,
+                                   CC_id
 #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
-         ,configuration->schedulingInfoSIB1_BR_r13[CC_id]
+                                   ,FALSE
 #endif
-        );
-  RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sizeof_SIB1 = 0;
-  RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sizeof_SIB23 = 0;
-  RC.rrc[ctxt_pP->module_id]->carrier[CC_id].SIB1 = (uint8_t *) malloc16(32);
-  AssertFatal(RC.rrc[ctxt_pP->module_id]->carrier[CC_id].SIB1!=NULL,PROTOCOL_RRC_CTXT_FMT" init_SI: FATAL, no memory for SIB1 allocated\n",
-              PROTOCOL_RRC_CTXT_ARGS(ctxt_pP));
-  RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sizeof_SIB1 = do_SIB1(&RC.rrc[ctxt_pP->module_id]->carrier[CC_id],ctxt_pP->module_id,CC_id
+                                   , configuration
+				   );
+    
+    AssertFatal(carrier->sizeof_SIB1 != 255,"FATAL, RC.rrc[enb_mod_idP].carrier[CC_id].sizeof_SIB1 == 255");
+
 #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
-      ,FALSE
+    RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sizeof_SIB1_BR = 0;
+
+    if (configuration->schedulingInfoSIB1_BR_r13[CC_id] > 0) {
+      RC.rrc[ctxt_pP->module_id]->carrier[CC_id].SIB1_BR = (uint8_t *) malloc16(32);
+      RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sizeof_SIB1_BR = do_SIB1(&RC.rrc[ctxt_pP->module_id]->carrier[CC_id],
+                                                                          ctxt_pP->module_id,
+                                                                          CC_id, TRUE, configuration);
+    }
 #endif
-      , configuration
-                                                                  );
-  AssertFatal(RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sizeof_SIB1 != 255,"FATAL, RC.rrc[enb_mod_idP].carrier[CC_id].sizeof_SIB1 == 255");
-#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
-  RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sizeof_SIB1_BR = 0;
 
-  if (configuration->schedulingInfoSIB1_BR_r13[CC_id]>0) {
-    RC.rrc[ctxt_pP->module_id]->carrier[CC_id].SIB1_BR = (uint8_t *) malloc16(32);
-    RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sizeof_SIB1_BR = do_SIB1(&RC.rrc[ctxt_pP->module_id]->carrier[CC_id],ctxt_pP->module_id,CC_id
-        ,TRUE
-        , configuration
-                                                                       );
   }
-
-#endif
-  RC.rrc[ctxt_pP->module_id]->carrier[CC_id].SIB23 = (uint8_t *) malloc16(64);
-  AssertFatal(RC.rrc[ctxt_pP->module_id]->carrier[CC_id].SIB23!=NULL,"cannot allocate memory for SIB");
-  RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sizeof_SIB23 = do_SIB23(
-        ctxt_pP->module_id,
-        CC_id
+  if (!NODE_IS_DU(rrc->node_type)) {
+    carrier->SIB23 = (uint8_t*) malloc16(64);
+    AssertFatal(carrier->SIB23!=NULL,"cannot allocate memory for SIB");
+    carrier->sizeof_SIB23 = do_SIB23(ctxt_pP->module_id,
+                                     CC_id
 #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
-        ,FALSE
+                                     ,FALSE
 #endif
-        , configuration
-      );
-  AssertFatal(RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sizeof_SIB23 != 255,"FATAL, RC.rrc[mod].carrier[CC_id].sizeof_SIB23 == 255");
+                                     , configuration
+                                     );
+    
+    LOG_I(RRC,"do_SIB23, size %d \n ", carrier->sizeof_SIB23);
+    
+    AssertFatal(carrier->sizeof_SIB23 != 255,"FATAL, RC.rrc[mod].carrier[CC_id].sizeof_SIB23 == 255");
+    
 #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
-  RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sizeof_SIB23_BR = 0;
-
+  carrier->sizeof_SIB23_BR = 0;
   if (configuration->schedulingInfoSIB1_BR_r13[CC_id]>0) {
-    RC.rrc[ctxt_pP->module_id]->carrier[CC_id].SIB23_BR = (uint8_t *) malloc16(64);
-    AssertFatal(RC.rrc[ctxt_pP->module_id]->carrier[CC_id].SIB23_BR!=NULL,"cannot allocate memory for SIB");
-    RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sizeof_SIB23_BR = do_SIB23(
-          ctxt_pP->module_id,
-          CC_id,
-          TRUE,
-          configuration
-        );
+    carrier->SIB23_BR = (uint8_t*) malloc16(64);
+    AssertFatal(carrier->SIB23_BR!=NULL,"cannot allocate memory for SIB");
+    carrier->sizeof_SIB23_BR = do_SIB23(ctxt_pP->module_id, CC_id, TRUE, configuration);
   }
-
+    
 #endif
-  LOG_T(RRC, PROTOCOL_RRC_CTXT_FMT" SIB2/3 Contents (partial)\n",
-        PROTOCOL_RRC_CTXT_ARGS(ctxt_pP));
-  LOG_T(RRC, PROTOCOL_RRC_CTXT_FMT" pusch_config_common.n_SB = %ld\n",
-        PROTOCOL_RRC_CTXT_ARGS(ctxt_pP),
-        RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib2->radioResourceConfigCommon.pusch_ConfigCommon.
-        pusch_ConfigBasic.n_SB);
-  LOG_T(RRC, PROTOCOL_RRC_CTXT_FMT" pusch_config_common.hoppingMode = %ld\n",
-        PROTOCOL_RRC_CTXT_ARGS(ctxt_pP),
-        RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib2->radioResourceConfigCommon.pusch_ConfigCommon.
-        pusch_ConfigBasic.hoppingMode);
-  LOG_T(RRC, PROTOCOL_RRC_CTXT_FMT" pusch_config_common.pusch_HoppingOffset = %ld\n",
-        PROTOCOL_RRC_CTXT_ARGS(ctxt_pP),
-        RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib2->radioResourceConfigCommon.pusch_ConfigCommon.
-        pusch_ConfigBasic.pusch_HoppingOffset);
-  LOG_T(RRC, PROTOCOL_RRC_CTXT_FMT" pusch_config_common.enable64QAM = %d\n",
-        PROTOCOL_RRC_CTXT_ARGS(ctxt_pP),
-        (int)RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib2->radioResourceConfigCommon.pusch_ConfigCommon.
-        pusch_ConfigBasic.enable64QAM);
-  LOG_T(RRC, PROTOCOL_RRC_CTXT_FMT" pusch_config_common.groupHoppingEnabled = %d\n",
-        PROTOCOL_RRC_CTXT_ARGS(ctxt_pP),
-        (int)RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib2->radioResourceConfigCommon.pusch_ConfigCommon.
-        ul_ReferenceSignalsPUSCH.groupHoppingEnabled);
-  LOG_T(RRC, PROTOCOL_RRC_CTXT_FMT" pusch_config_common.groupAssignmentPUSCH = %ld\n",
-        PROTOCOL_RRC_CTXT_ARGS(ctxt_pP),
-        RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib2->radioResourceConfigCommon.pusch_ConfigCommon.
-        ul_ReferenceSignalsPUSCH.groupAssignmentPUSCH);
-  LOG_T(RRC, PROTOCOL_RRC_CTXT_FMT" pusch_config_common.sequenceHoppingEnabled = %d\n",
-        PROTOCOL_RRC_CTXT_ARGS(ctxt_pP),
-        (int)RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib2->radioResourceConfigCommon.pusch_ConfigCommon.
-        ul_ReferenceSignalsPUSCH.sequenceHoppingEnabled);
-  LOG_T(RRC, PROTOCOL_RRC_CTXT_FMT" pusch_config_common.cyclicShift  = %ld\n",
-        PROTOCOL_RRC_CTXT_ARGS(ctxt_pP),
-        RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib2->radioResourceConfigCommon.pusch_ConfigCommon.
-        ul_ReferenceSignalsPUSCH.cyclicShift);
+    LOG_T(RRC, PROTOCOL_RRC_CTXT_FMT" SIB2/3 Contents (partial)\n",
+          PROTOCOL_RRC_CTXT_ARGS(ctxt_pP));
+    LOG_T(RRC, PROTOCOL_RRC_CTXT_FMT" pusch_config_common.n_SB = %ld\n",
+          PROTOCOL_RRC_CTXT_ARGS(ctxt_pP),
+          carrier->sib2->radioResourceConfigCommon.pusch_ConfigCommon.pusch_ConfigBasic.n_SB);
+    LOG_T(RRC, PROTOCOL_RRC_CTXT_FMT" pusch_config_common.hoppingMode = %ld\n",
+          PROTOCOL_RRC_CTXT_ARGS(ctxt_pP),
+          carrier->sib2->radioResourceConfigCommon.pusch_ConfigCommon.pusch_ConfigBasic.hoppingMode);
+    LOG_T(RRC, PROTOCOL_RRC_CTXT_FMT" pusch_config_common.pusch_HoppingOffset = %ld\n",
+          PROTOCOL_RRC_CTXT_ARGS(ctxt_pP),
+          carrier->sib2->radioResourceConfigCommon.pusch_ConfigCommon.pusch_ConfigBasic.pusch_HoppingOffset);
+    LOG_T(RRC, PROTOCOL_RRC_CTXT_FMT" pusch_config_common.enable64QAM = %d\n",
+          PROTOCOL_RRC_CTXT_ARGS(ctxt_pP),
+          (int)carrier->sib2->radioResourceConfigCommon.pusch_ConfigCommon.pusch_ConfigBasic.enable64QAM);
+    LOG_T(RRC, PROTOCOL_RRC_CTXT_FMT" pusch_config_common.groupHoppingEnabled = %d\n",
+          PROTOCOL_RRC_CTXT_ARGS(ctxt_pP),
+          (int)carrier->sib2->radioResourceConfigCommon.pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.groupHoppingEnabled);
+    LOG_T(RRC, PROTOCOL_RRC_CTXT_FMT" pusch_config_common.groupAssignmentPUSCH = %ld\n",
+          PROTOCOL_RRC_CTXT_ARGS(ctxt_pP),
+          carrier->sib2->radioResourceConfigCommon.pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.groupAssignmentPUSCH);
+    LOG_T(RRC, PROTOCOL_RRC_CTXT_FMT" pusch_config_common.sequenceHoppingEnabled = %d\n",
+          PROTOCOL_RRC_CTXT_ARGS(ctxt_pP),
+          (int)carrier->sib2->radioResourceConfigCommon.pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.sequenceHoppingEnabled);
+    LOG_T(RRC, PROTOCOL_RRC_CTXT_FMT" pusch_config_common.cyclicShift  = %ld\n",
+          PROTOCOL_RRC_CTXT_ARGS(ctxt_pP),
+          carrier->sib2->radioResourceConfigCommon.pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.cyclicShift);
+    
 #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0))
-
-  if (RC.rrc[ctxt_pP->module_id]->carrier[CC_id].MBMS_flag > 0) {
-    for (i = 0; i < RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib2->mbsfn_SubframeConfigList->list.count; i++) {
-      // SIB 2
-      //   LOG_D(RRC, "[eNB %d] mbsfn_SubframeConfigList.list.count = %ld\n", enb_mod_idP, RC.rrc[enb_mod_idP].sib2->mbsfn_SubframeConfigList->list.count);
-      LOG_D(RRC, PROTOCOL_RRC_CTXT_FMT" SIB13 contents for MBSFN subframe allocation %d/%d(partial)\n",
-            PROTOCOL_RRC_CTXT_ARGS(ctxt_pP),
-            i,
-            RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib2->mbsfn_SubframeConfigList->list.count);
-      LOG_D(RRC, PROTOCOL_RRC_CTXT_FMT" mbsfn_Subframe_pattern is  = %x\n",
-            PROTOCOL_RRC_CTXT_ARGS(ctxt_pP),
-            RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib2->mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.choice.oneFrame.buf[0] >> 0);
-      LOG_D(RRC, PROTOCOL_RRC_CTXT_FMT" radioframe_allocation_period  = %ld (just index number, not the real value)\n",
-            PROTOCOL_RRC_CTXT_ARGS(ctxt_pP),
-            RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib2->mbsfn_SubframeConfigList->list.array[i]->radioframeAllocationPeriod);   // need to display the real value, using array of char (like in dumping SIB2)
-      LOG_D(RRC, PROTOCOL_RRC_CTXT_FMT" radioframe_allocation_offset  = %ld\n",
-            PROTOCOL_RRC_CTXT_ARGS(ctxt_pP),
-            RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib2->mbsfn_SubframeConfigList->list.array[i]->radioframeAllocationOffset);
-    }
-
-    //   SIB13
-    for (i = 0; i < RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib13->mbsfn_AreaInfoList_r9.list.count; i++) {
-      LOG_D(RRC, PROTOCOL_RRC_CTXT_FMT" SIB13 contents for MBSFN sync area %d/%d (partial)\n",
-            PROTOCOL_RRC_CTXT_ARGS(ctxt_pP),
-            i,
-            RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib13->mbsfn_AreaInfoList_r9.list.count);
-      LOG_D(RRC, PROTOCOL_RRC_CTXT_FMT" MCCH Repetition Period: %ld (just index number, not real value)\n",
-            PROTOCOL_RRC_CTXT_ARGS(ctxt_pP),
-            RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib13->mbsfn_AreaInfoList_r9.list.array[i]->mcch_Config_r9.mcch_RepetitionPeriod_r9);
-      LOG_D(RRC, PROTOCOL_RRC_CTXT_FMT" MCCH Offset: %ld\n",
-            PROTOCOL_RRC_CTXT_ARGS(ctxt_pP),
-            RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib13->mbsfn_AreaInfoList_r9.list.array[i]->mcch_Config_r9.mcch_Offset_r9);
-    }
-  } else memset((void *)&RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib13,0,sizeof(RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib13));
-
-  //TTN - SIB 18
-  if (configuration->SL_configured>0) {
-    for (int j = 0; j < RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib18->commConfig_r12->commRxPool_r12.list.count; j++) {
-      LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" Contents of SIB18 %d/%d \n",
-            PROTOCOL_RRC_CTXT_ARGS(ctxt_pP),
-            j+1,
-            RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib18->commConfig_r12->commRxPool_r12.list.count);
-      LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB18 rxPool_sc_CP_Len: %ld \n",
-            PROTOCOL_RRC_CTXT_ARGS(ctxt_pP),
-            RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib18->commConfig_r12->commRxPool_r12.list.array[j]->sc_CP_Len_r12);
-      LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB18 sc_Period_r12: %ld \n",
-            PROTOCOL_RRC_CTXT_ARGS(ctxt_pP),
-            RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib18->commConfig_r12->commRxPool_r12.list.array[j]->sc_Period_r12);
-      LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB18 data_CP_Len_r12: %ld \n",
-            PROTOCOL_RRC_CTXT_ARGS(ctxt_pP),
-            RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib18->commConfig_r12->commRxPool_r12.list.array[j]->data_CP_Len_r12);
-      LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB18 prb_Num_r12: %ld \n",
-            PROTOCOL_RRC_CTXT_ARGS(ctxt_pP),
-            RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib18->commConfig_r12->commRxPool_r12.list.array[j]->sc_TF_ResourceConfig_r12.prb_Num_r12);
-      LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB18 prb_Start_r12: %ld \n",
-            PROTOCOL_RRC_CTXT_ARGS(ctxt_pP),
-            RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib18->commConfig_r12->commRxPool_r12.list.array[j]->sc_TF_ResourceConfig_r12.prb_Start_r12);
-      LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB18 prb_End_r12: %ld \n",
-            PROTOCOL_RRC_CTXT_ARGS(ctxt_pP),
-            RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib18->commConfig_r12->commRxPool_r12.list.array[j]->sc_TF_ResourceConfig_r12.prb_End_r12);
-      LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB18 offsetIndicator: %ld \n",
-            PROTOCOL_RRC_CTXT_ARGS(ctxt_pP),
-            RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib18->commConfig_r12->commRxPool_r12.list.array[j]->sc_TF_ResourceConfig_r12.offsetIndicator_r12.choice.small_r12);
-      LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB18 subframeBitmap_choice_bs_buf: %s \n",
-            PROTOCOL_RRC_CTXT_ARGS(ctxt_pP),
-            RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib18->commConfig_r12->commRxPool_r12.list.array[j]->sc_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs16_r12.buf);
-    }
-
-    for (int j = 0; j < RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib19->discConfig_r12->discRxPool_r12.list.count; j++) {
-      LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" Contents of SIB19 %d/%d \n",
-            PROTOCOL_RRC_CTXT_ARGS(ctxt_pP),
-            j+1,
-            RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib19->discConfig_r12->discRxPool_r12.list.count);
-      LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB19 cp_Len_r12: %ld \n",
-            PROTOCOL_RRC_CTXT_ARGS(ctxt_pP),
-            RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib19->discConfig_r12->discRxPool_r12.list.array[j]->cp_Len_r12);
-      LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB19 discPeriod_r12: %ld \n",
-            PROTOCOL_RRC_CTXT_ARGS(ctxt_pP),
-            RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib19->discConfig_r12->discRxPool_r12.list.array[j]->discPeriod_r12);
-      LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB19 numRetx_r12: %ld \n",
-            PROTOCOL_RRC_CTXT_ARGS(ctxt_pP),
-            RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib19->discConfig_r12->discRxPool_r12.list.array[j]->numRetx_r12);
-      LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB19 numRepetition_r12: %ld \n",
-            PROTOCOL_RRC_CTXT_ARGS(ctxt_pP),
-            RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib19->discConfig_r12->discRxPool_r12.list.array[j]->numRepetition_r12);
-      LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB19 tf_ResourceConfig_r12 prb_Num_r12: %ld \n",
-            PROTOCOL_RRC_CTXT_ARGS(ctxt_pP),
-            RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib19->discConfig_r12->discRxPool_r12.list.array[j]->tf_ResourceConfig_r12.prb_Num_r12);
-      LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB19 tf_ResourceConfig_r12 prb_Start_r12: %ld \n",
-            PROTOCOL_RRC_CTXT_ARGS(ctxt_pP),
-            RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib19->discConfig_r12->discRxPool_r12.list.array[j]->tf_ResourceConfig_r12.prb_Start_r12);
-      LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB19 tf_ResourceConfig_r12 prb_End_r12: %ld \n",
-            PROTOCOL_RRC_CTXT_ARGS(ctxt_pP),
-            RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib19->discConfig_r12->discRxPool_r12.list.array[j]->tf_ResourceConfig_r12.prb_End_r12);
-      LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB19 tf_ResourceConfig_r12 offsetIndicator: %ld \n",
-            PROTOCOL_RRC_CTXT_ARGS(ctxt_pP),
-            RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib19->discConfig_r12->discRxPool_r12.list.array[j]->tf_ResourceConfig_r12.offsetIndicator_r12.choice.small_r12);
-      LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB19 tf_ResourceConfig_r12 subframeBitmap_choice_bs_buf: %s \n",
-            PROTOCOL_RRC_CTXT_ARGS(ctxt_pP),
-            RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib19->discConfig_r12->discRxPool_r12.list.array[j]->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs16_r12.buf);
+    
+    if (carrier->MBMS_flag > 0) {
+      for (i = 0; i < carrier->sib2->mbsfn_SubframeConfigList->list.count; i++) {
+	// SIB 2
+	//   LOG_D(RRC, "[eNB %d] mbsfn_SubframeConfigList.list.count = %ld\n", enb_mod_idP, RC.rrc[enb_mod_idP].sib2->mbsfn_SubframeConfigList->list.count);
+        LOG_D(RRC, PROTOCOL_RRC_CTXT_FMT" SIB13 contents for MBSFN subframe allocation %d/%d(partial)\n",
+              PROTOCOL_RRC_CTXT_ARGS(ctxt_pP),
+              i,
+              carrier->sib2->mbsfn_SubframeConfigList->list.count);
+        LOG_D(RRC, PROTOCOL_RRC_CTXT_FMT" mbsfn_Subframe_pattern is  = %x\n",
+              PROTOCOL_RRC_CTXT_ARGS(ctxt_pP),
+              carrier->sib2->mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.choice.oneFrame.buf[0] >> 0);
+        LOG_D(RRC, PROTOCOL_RRC_CTXT_FMT" radioframe_allocation_period  = %ld (just index number, not the real value)\n",
+              PROTOCOL_RRC_CTXT_ARGS(ctxt_pP),
+              carrier->sib2->mbsfn_SubframeConfigList->list.array[i]->radioframeAllocationPeriod);   // need to display the real value, using array of char (like in dumping SIB2)
+        LOG_D(RRC, PROTOCOL_RRC_CTXT_FMT" radioframe_allocation_offset  = %ld\n",
+              PROTOCOL_RRC_CTXT_ARGS(ctxt_pP),
+              carrier->sib2->mbsfn_SubframeConfigList->list.array[i]->radioframeAllocationOffset);
+      }
+      
+      //   SIB13
+      for (i = 0; i < carrier->sib13->mbsfn_AreaInfoList_r9.list.count; i++) {
+        LOG_D(RRC, PROTOCOL_RRC_CTXT_FMT" SIB13 contents for MBSFN sync area %d/%d (partial)\n",
+              PROTOCOL_RRC_CTXT_ARGS(ctxt_pP),
+              i,
+              carrier->sib13->mbsfn_AreaInfoList_r9.list.count);
+        LOG_D(RRC, PROTOCOL_RRC_CTXT_FMT" MCCH Repetition Period: %ld (just index number, not real value)\n",
+              PROTOCOL_RRC_CTXT_ARGS(ctxt_pP),
+              carrier->sib13->mbsfn_AreaInfoList_r9.list.array[i]->mcch_Config_r9.mcch_RepetitionPeriod_r9);
+        LOG_D(RRC, PROTOCOL_RRC_CTXT_FMT" MCCH Offset: %ld\n",
+              PROTOCOL_RRC_CTXT_ARGS(ctxt_pP),
+              carrier->sib13->mbsfn_AreaInfoList_r9.list.array[i]->mcch_Config_r9.mcch_Offset_r9);
+      }
+    } else memset((void *)&RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib13,0,sizeof(RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib13));
+    
+    //TTN - SIB 18
+    if (configuration->SL_configured > 0) {
+      for (int j = 0; j < carrier->sib18->commConfig_r12->commRxPool_r12.list.count; j++) {
+        LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" Contents of SIB18 %d/%d \n",
+              PROTOCOL_RRC_CTXT_ARGS(ctxt_pP),
+              j+1,
+              carrier->sib18->commConfig_r12->commRxPool_r12.list.count);
+        LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB18 rxPool_sc_CP_Len: %ld \n",
+              PROTOCOL_RRC_CTXT_ARGS(ctxt_pP),
+              carrier->sib18->commConfig_r12->commRxPool_r12.list.array[j]->sc_CP_Len_r12);
+        LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB18 sc_Period_r12: %ld \n",
+              PROTOCOL_RRC_CTXT_ARGS(ctxt_pP),
+              carrier->sib18->commConfig_r12->commRxPool_r12.list.array[j]->sc_Period_r12);
+        LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB18 data_CP_Len_r12: %ld \n",
+              PROTOCOL_RRC_CTXT_ARGS(ctxt_pP),
+              carrier->sib18->commConfig_r12->commRxPool_r12.list.array[j]->data_CP_Len_r12);
+        LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB18 prb_Num_r12: %ld \n",
+              PROTOCOL_RRC_CTXT_ARGS(ctxt_pP),
+              carrier->sib18->commConfig_r12->commRxPool_r12.list.array[j]->sc_TF_ResourceConfig_r12.prb_Num_r12);
+        LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB18 prb_Start_r12: %ld \n",
+              PROTOCOL_RRC_CTXT_ARGS(ctxt_pP),
+              carrier->sib18->commConfig_r12->commRxPool_r12.list.array[j]->sc_TF_ResourceConfig_r12.prb_Start_r12);
+        LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB18 prb_End_r12: %ld \n",
+              PROTOCOL_RRC_CTXT_ARGS(ctxt_pP),
+              carrier->sib18->commConfig_r12->commRxPool_r12.list.array[j]->sc_TF_ResourceConfig_r12.prb_End_r12);
+        LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB18 offsetIndicator: %ld \n",
+              PROTOCOL_RRC_CTXT_ARGS(ctxt_pP),
+              carrier->sib18->commConfig_r12->commRxPool_r12.list.array[j]->sc_TF_ResourceConfig_r12.offsetIndicator_r12.choice.small_r12);
+        LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB18 subframeBitmap_choice_bs_buf: %s \n",
+              PROTOCOL_RRC_CTXT_ARGS(ctxt_pP),
+              carrier->sib18->commConfig_r12->commRxPool_r12.list.array[j]->sc_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs16_r12.buf);
+      }
+      
+      //TTN - SIB 19
+      for (int j = 0; j < carrier->sib19->discConfig_r12->discRxPool_r12.list.count; j++) {
+        LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" Contents of SIB19 %d/%d \n",
+              PROTOCOL_RRC_CTXT_ARGS(ctxt_pP),
+              j+1,
+              carrier->sib19->discConfig_r12->discRxPool_r12.list.count);
+        LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB19 cp_Len_r12: %ld \n",
+              PROTOCOL_RRC_CTXT_ARGS(ctxt_pP),
+              carrier->sib19->discConfig_r12->discRxPool_r12.list.array[j]->cp_Len_r12);
+        LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB19 discPeriod_r12: %ld \n",
+              PROTOCOL_RRC_CTXT_ARGS(ctxt_pP),
+              carrier->sib19->discConfig_r12->discRxPool_r12.list.array[j]->discPeriod_r12);
+        LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB19 numRetx_r12: %ld \n",
+              PROTOCOL_RRC_CTXT_ARGS(ctxt_pP),
+              carrier->sib19->discConfig_r12->discRxPool_r12.list.array[j]->numRetx_r12);
+        LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB19 numRepetition_r12: %ld \n",
+              PROTOCOL_RRC_CTXT_ARGS(ctxt_pP),
+              carrier->sib19->discConfig_r12->discRxPool_r12.list.array[j]->numRepetition_r12);
+        LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB19 tf_ResourceConfig_r12 prb_Num_r12: %ld \n",
+              PROTOCOL_RRC_CTXT_ARGS(ctxt_pP),
+              carrier->sib19->discConfig_r12->discRxPool_r12.list.array[j]->tf_ResourceConfig_r12.prb_Num_r12);
+        LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB19 tf_ResourceConfig_r12 prb_Start_r12: %ld \n",
+              PROTOCOL_RRC_CTXT_ARGS(ctxt_pP),
+              carrier->sib19->discConfig_r12->discRxPool_r12.list.array[j]->tf_ResourceConfig_r12.prb_Start_r12);
+        LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB19 tf_ResourceConfig_r12 prb_End_r12: %ld \n",
+              PROTOCOL_RRC_CTXT_ARGS(ctxt_pP),
+              carrier->sib19->discConfig_r12->discRxPool_r12.list.array[j]->tf_ResourceConfig_r12.prb_End_r12);
+        LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB19 tf_ResourceConfig_r12 offsetIndicator: %ld \n",
+              PROTOCOL_RRC_CTXT_ARGS(ctxt_pP),
+              carrier->sib19->discConfig_r12->discRxPool_r12.list.array[j]->tf_ResourceConfig_r12.offsetIndicator_r12.choice.small_r12);
+        LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB19 tf_ResourceConfig_r12 subframeBitmap_choice_bs_buf: %s \n",
+              PROTOCOL_RRC_CTXT_ARGS(ctxt_pP),
+              carrier->sib19->discConfig_r12->discRxPool_r12.list.array[j]->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs16_r12.buf);
+      }
     }
-  }
-
 #endif // (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0))    
+  }
+   
   LOG_D(RRC,
         PROTOCOL_RRC_CTXT_FMT" RRC_UE --- MAC_CONFIG_REQ (SIB1.tdd & SIB2 params) ---> MAC_UE\n",
         PROTOCOL_RRC_CTXT_ARGS(ctxt_pP));
 #if (LTE_RRC_VERSION >= MAKE_VERSION(13, 0, 0))
 
-  if ((RC.rrc[ctxt_pP->module_id]->carrier[CC_id].mib.message.schedulingInfoSIB1_BR_r13>0) &&
-      (RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib1_BR!=NULL)) {
-    AssertFatal(RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib1_BR->nonCriticalExtension!=NULL,
-                "sib2_br->nonCriticalExtension is null (v8.9)\n");
-    AssertFatal(RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib1_BR->nonCriticalExtension->nonCriticalExtension!=NULL,
-                "sib2_br->nonCriticalExtension is null (v9.2)\n");
-    AssertFatal(RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib1_BR->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension!=NULL,
-                "sib2_br->nonCriticalExtension is null (v11.3)\n");
-    AssertFatal(RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib1_BR->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension!=NULL,
-                "sib2_br->nonCriticalExtension is null (v12.5)\n");
-    AssertFatal(RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib1_BR->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension!=NULL,
-                "sib2_br->nonCriticalExtension is null (v13.10)\n");
-    sib1_v13ext = RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib1_BR->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension;
-    // Basic Asserts for CE_level0 PRACH configuration
-    LTE_RadioResourceConfigCommonSIB_t *radioResourceConfigCommon_BR = &RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib2_BR->radioResourceConfigCommon;
-    struct LTE_PRACH_ConfigSIB_v1310 *ext4_prach=radioResourceConfigCommon_BR->ext4->prach_ConfigCommon_v1310;
-    LTE_PRACH_ParametersListCE_r13_t   *prach_ParametersListCE_r13 = &ext4_prach->prach_ParametersListCE_r13;
-    AssertFatal(prach_ParametersListCE_r13->list.count>0,"prach_ParametersListCE_r13 is empty\n");
-    LTE_PRACH_ParametersCE_r13_t *p = prach_ParametersListCE_r13->list.array[0];
-    AssertFatal(p->prach_StartingSubframe_r13 != NULL, "prach_StartingSubframe_r13 celevel0 is null\n");
-    AssertFatal((1<<p->numRepetitionPerPreambleAttempt_r13)<=(2<<*p->prach_StartingSubframe_r13),
-                "prachce0->numReptitionPerPreambleAttempt_r13 %d > prach_StartingSubframe_r13 %d\n",
-                1<<p->numRepetitionPerPreambleAttempt_r13,
-                2<<*p->prach_StartingSubframe_r13);
+  // LTE-M stuff here (take out CU-DU for now)
+  if (NODE_IS_MONOLITHIC(rrc->node_type)) {
+    if ((carrier->mib.message.schedulingInfoSIB1_BR_r13>0) && 
+        (carrier->sib1_BR!=NULL)) {
+      AssertFatal(carrier->sib1_BR->nonCriticalExtension!=NULL,
+                  "sib2_br->nonCriticalExtension is null (v8.9)\n");
+      AssertFatal(carrier->sib1_BR->nonCriticalExtension->nonCriticalExtension!=NULL,
+                  "sib2_br->nonCriticalExtension is null (v9.2)\n");
+      AssertFatal(carrier->sib1_BR->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension!=NULL,
+                  "sib2_br->nonCriticalExtension is null (v11.3)\n");
+      AssertFatal(carrier->sib1_BR->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension!=NULL,
+                  "sib2_br->nonCriticalExtension is null (v12.5)\n");
+      AssertFatal(carrier->sib1_BR->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension!=NULL,
+                  "sib2_br->nonCriticalExtension is null (v13.10)\n");
+
+      sib1_v13ext = carrier->sib1_BR->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension;
+
+      // Basic Asserts for CE_level0 PRACH configuration
+      LTE_RadioResourceConfigCommonSIB_t *radioResourceConfigCommon_BR = &carrier[CC_id].sib2_BR->radioResourceConfigCommon;
+      struct LTE_PRACH_ConfigSIB_v1310 *ext4_prach=radioResourceConfigCommon_BR->ext4->prach_ConfigCommon_v1310;
+      LTE_PRACH_ParametersListCE_r13_t	 *prach_ParametersListCE_r13 = &ext4_prach->prach_ParametersListCE_r13;
+      AssertFatal(prach_ParametersListCE_r13->list.count>0,"prach_ParametersListCE_r13 is empty\n");
+                  LTE_PRACH_ParametersCE_r13_t *p = prach_ParametersListCE_r13->list.array[0];
+      AssertFatal(p->prach_StartingSubframe_r13 != NULL, "prach_StartingSubframe_r13 celevel0 is null\n");
+      AssertFatal((1<<p->numRepetitionPerPreambleAttempt_r13)<=(2<<*p->prach_StartingSubframe_r13),
+                  "prachce0->numReptitionPerPreambleAttempt_r13 %d > prach_StartingSubframe_r13 %d\n",
+                  1<<p->numRepetitionPerPreambleAttempt_r13,
+                  2<<*p->prach_StartingSubframe_r13);
+    }
+  
   }
-
 #endif
-  LOG_D(RRC, "About to call rrc_mac_config_req_eNB\n");
-  rrc_mac_config_req_eNB(ctxt_pP->module_id, CC_id,
-                         RC.rrc[ctxt_pP->module_id]->carrier[CC_id].physCellId,
-                         RC.rrc[ctxt_pP->module_id]->carrier[CC_id].p_eNB,
-                         RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Ncp,
-                         RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib1->freqBandIndicator,
-                         RC.rrc[ctxt_pP->module_id]->carrier[CC_id].dl_CarrierFreq,
+  /*
+  if (rrc->node_type == ngran_eNB_DU) {
+    LOG_D(RRC, "About to call rrc_mac_config_req_eNB for ngran_eNB_DU\n");
+    
+    rrc_mac_config_req_eNB(ctxt_pP->module_id, CC_id,
+			   carrier->physCellId,
+			   carrier->p_eNB,
+			   carrier->Ncp,
+			   carrier->sib1->freqBandIndicator,
+			   carrier->dl_CarrierFreq,
 #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
-                         RC.rrc[ctxt_pP->module_id]->carrier[CC_id].pbch_repetition,
+			   carrier->pbch_repetition,
 #endif
-                         0, // rnti
-                         (LTE_BCCH_BCH_Message_t *)
-                         &RC.rrc[ctxt_pP->module_id]->carrier[CC_id].mib,
-                         (LTE_RadioResourceConfigCommonSIB_t *) &
-                         RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib2->radioResourceConfigCommon,
+			   0, // rnti
+			   (BCCH_BCH_Message_t *)
+			   &carrier->mib,
+			   (RadioResourceConfigCommonSIB_t *) NULL,
 #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
-                         (LTE_RadioResourceConfigCommonSIB_t *) &
-                         RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib2_BR->radioResourceConfigCommon,
+			   (RadioResourceConfigCommonSIB_t *) NULL,
 #endif
-                         (struct LTE_PhysicalConfigDedicated *)NULL,
+			   (struct PhysicalConfigDedicated *)NULL,
 #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0))
-                         (LTE_SCellToAddMod_r10_t *)NULL,
-                         //(struct LTE_PhysicalConfigDedicatedSCell_r10 *)NULL,
+			   (SCellToAddMod_r10_t *)NULL,
+			   //(struct PhysicalConfigDedicatedSCell_r10 *)NULL,
+#endif
+			   (MeasObjectToAddMod_t **) NULL,
+			   (MAC_MainConfig_t *) NULL, 0,
+			   (struct LogicalChannelConfig *)NULL,
+			   (MeasGapConfig_t *) NULL,
+			   carrier->sib1->tdd_Config,
+			   NULL,
+			   &carrier->sib1->schedulingInfoList,
+			   carrier->ul_CarrierFreq,
+			   NULL,
+			   NULL,
+			   NULL
+#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0))
+			   ,
+			   carrier->MBMS_flag,
+			   NULL,
+			   (PMCH_InfoList_r9_t *) NULL
+#endif
+#if (LTE_RRC_VERSION >= MAKE_VERSION(13, 0, 0))
+			   , 
+			   NULL
+#endif
+			   );
+  }
+  else 
+  */
+  if (NODE_IS_MONOLITHIC(rrc->node_type)) {
+    LOG_D(RRC, "About to call rrc_mac_config_req_eNB for ngran_eNB\n");
+    
+    rrc_mac_config_req_eNB(ctxt_pP->module_id, CC_id,
+                           carrier->physCellId,
+                           carrier->p_eNB,
+                           carrier->Ncp,
+                           carrier->sib1->freqBandIndicator,
+                           carrier->dl_CarrierFreq,
+#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
+                           carrier->pbch_repetition,
+#endif
+                           0, // rnti
+                           (LTE_BCCH_BCH_Message_t *) &carrier->mib,
+                           (LTE_RadioResourceConfigCommonSIB_t *) &carrier->sib2->radioResourceConfigCommon,
+#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
+                           (LTE_RadioResourceConfigCommonSIB_t *) &carrier->sib2_BR->radioResourceConfigCommon,
 #endif
-                         (LTE_MeasObjectToAddMod_t **) NULL,
-                         (LTE_MAC_MainConfig_t *) NULL, 0,
-                         (struct LTE_LogicalChannelConfig *)NULL,
-                         (LTE_MeasGapConfig_t *) NULL,
-                         RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib1->tdd_Config,
-                         NULL,
-                         &RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib1->schedulingInfoList,
-                         RC.rrc[ctxt_pP->module_id]->carrier[CC_id].ul_CarrierFreq,
-                         RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib2->freqInfo.ul_Bandwidth,
-                         &RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib2->freqInfo.additionalSpectrumEmission,
-                         (LTE_MBSFN_SubframeConfigList_t *) RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib2->mbsfn_SubframeConfigList
+                           (struct LTE_PhysicalConfigDedicated *)NULL,
+#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0))
+                           (LTE_SCellToAddMod_r10_t *)NULL,
+                           //(struct PhysicalConfigDedicatedSCell_r10 *)NULL,
+#endif
+                           (LTE_MeasObjectToAddMod_t **) NULL,
+                           (LTE_MAC_MainConfig_t *) NULL, 0,
+                           (struct LTE_LogicalChannelConfig *)NULL,
+                           (LTE_MeasGapConfig_t *) NULL,
+                           carrier->sib1->tdd_Config,
+                           NULL,
+                           &carrier->sib1->schedulingInfoList,
+                           carrier->ul_CarrierFreq,
+                           carrier->sib2->freqInfo.ul_Bandwidth,
+                           &carrier->sib2->freqInfo.additionalSpectrumEmission,
+                           (LTE_MBSFN_SubframeConfigList_t*) carrier->sib2->mbsfn_SubframeConfigList
 #if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0))
-                         ,
-                         RC.rrc[ctxt_pP->module_id]->carrier[CC_id].MBMS_flag,
-                         (LTE_MBSFN_AreaInfoList_r9_t *) & RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib13->mbsfn_AreaInfoList_r9,
-                         (LTE_PMCH_InfoList_r9_t *) NULL
+                           ,
+                           carrier->MBMS_flag,
+                           (LTE_MBSFN_AreaInfoList_r9_t*) & carrier->sib13->mbsfn_AreaInfoList_r9,
+                           (LTE_PMCH_InfoList_r9_t *) NULL
 #endif
 #if (LTE_RRC_VERSION >= MAKE_VERSION(13, 0, 0))
-                         ,
-                         sib1_v13ext
+                           ,
+                           sib1_v13ext
 #endif
-                        );
+                           );
+  }
+
+	/* set flag to indicate that cell information is configured. This is required
+	 * in DU to trigger F1AP_SETUP procedure */
+  pthread_mutex_lock(&rrc->cell_info_mutex);
+  rrc->cell_info_configured=1;
+  pthread_mutex_unlock(&rrc->cell_info_mutex);
 }
 
 #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0))
@@ -452,6 +517,8 @@ init_MCCH(
 {
   int                                 sync_area = 0;
   // initialize RRC_eNB_INST MCCH entry
+  eNB_RRC_INST *rrc = RC.rrc[enb_mod_idP];
+
   RC.rrc[enb_mod_idP]->carrier[CC_id].MCCH_MESSAGE =
     malloc(RC.rrc[enb_mod_idP]->carrier[CC_id].num_mbsfn_sync_area * sizeof(uint8_t *));
 
@@ -488,38 +555,40 @@ init_MCCH(
   // call mac_config_req with appropriate structure from ASN.1 description
   //  LOG_I(RRC, "DUY: serviceID is %d\n",RC.rrc[enb_mod_idP]->mcch_message->pmch_InfoList_r9.list.array[0]->mbms_SessionInfoList_r9.list.array[0]->tmgi_r9.serviceId_r9.buf[2]);
   //  LOG_I(RRC, "DUY: session ID is %d\n",RC.rrc[enb_mod_idP]->mcch_message->pmch_InfoList_r9.list.array[0]->mbms_SessionInfoList_r9.list.array[0]->sessionId_r9->buf[0]);
-  rrc_mac_config_req_eNB(enb_mod_idP, CC_id,
-                         0,0,0,0,0,
+  if (NODE_IS_MONOLITHIC(rrc->node_type)) {
+    rrc_mac_config_req_eNB(enb_mod_idP, CC_id,
+                           0,0,0,0,0,
 #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
-                         0,
+                           0,
 #endif
-                         0,//rnti
-                         (LTE_BCCH_BCH_Message_t *)NULL,
-                         (LTE_RadioResourceConfigCommonSIB_t *) NULL,
+                           0,//rnti
+                           (LTE_BCCH_BCH_Message_t *)NULL,
+                           (LTE_RadioResourceConfigCommonSIB_t *) NULL,
 #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
-                         (LTE_RadioResourceConfigCommonSIB_t *) NULL,
+                           (LTE_RadioResourceConfigCommonSIB_t *) NULL,
 #endif
-                         (struct LTE_PhysicalConfigDedicated *)NULL,
-                         (LTE_SCellToAddMod_r10_t *)NULL,
+                           (struct LTE_PhysicalConfigDedicated *)NULL,
+                           (LTE_SCellToAddMod_r10_t *)NULL,
                          //(struct LTE_PhysicalConfigDedicatedSCell_r10 *)NULL,
-                         (LTE_MeasObjectToAddMod_t **) NULL,
-                         (LTE_MAC_MainConfig_t *) NULL,
-                         0,
-                         (struct LTE_LogicalChannelConfig *)NULL,
-                         (LTE_MeasGapConfig_t *) NULL,
-                         (LTE_TDD_Config_t *) NULL,
-                         (LTE_MobilityControlInfo_t *)NULL,
-                         (LTE_SchedulingInfoList_t *) NULL,
-                         0, NULL, NULL, (LTE_MBSFN_SubframeConfigList_t *) NULL
-                         ,
-                         0,
-                         (LTE_MBSFN_AreaInfoList_r9_t *) NULL,
-                         (LTE_PMCH_InfoList_r9_t *) & (RC.rrc[enb_mod_idP]->carrier[CC_id].mcch_message->pmch_InfoList_r9)
+                           (LTE_MeasObjectToAddMod_t **) NULL,
+                           (LTE_MAC_MainConfig_t *) NULL,
+                           0,
+                           (struct LTE_LogicalChannelConfig *)NULL,
+                           (LTE_MeasGapConfig_t *) NULL,
+                           (LTE_TDD_Config_t *) NULL,
+                           (LTE_MobilityControlInfo_t *)NULL,
+                           (LTE_SchedulingInfoList_t *) NULL,
+                           0, NULL, NULL, (LTE_MBSFN_SubframeConfigList_t *) NULL
+                           ,
+                           0,
+                           (LTE_MBSFN_AreaInfoList_r9_t *) NULL,
+                           (LTE_PMCH_InfoList_r9_t *) & (RC.rrc[enb_mod_idP]->carrier[CC_id].mcch_message->pmch_InfoList_r9)
 #if (LTE_RRC_VERSION >= MAKE_VERSION(13, 0, 0))
-                         ,
-                         (LTE_SystemInformationBlockType1_v1310_IEs_t *)NULL
+                           ,
+                           (LTE_SystemInformationBlockType1_v1310_IEs_t *)NULL
 #endif
-                        );
+                           );
+  }
   //LOG_I(RRC,"DUY: lcid after rrc_mac_config_req is %02d\n",RC.rrc[enb_mod_idP]->mcch_message->pmch_InfoList_r9.list.array[0]->mbms_SessionInfoList_r9.list.array[0]->logicalChannelIdentity_r9);
 }
 
@@ -548,16 +617,19 @@ static void init_MBMS(
                              NULL   // key encryption
                              , &(RC.rrc[enb_mod_idP]->carrier[CC_id].mcch_message->pmch_InfoList_r9)
                              ,NULL);
-    rrc_rlc_config_asn1_req(&ctxt,
-                            NULL, // LTE_SRB_ToAddModList
-                            NULL,   // LTE_DRB_ToAddModList
-                            NULL,   // DRB_ToReleaseList
-                            &(RC.rrc[enb_mod_idP]->carrier[CC_id].mcch_message->pmch_InfoList_r9)
+    
+    if (!NODE_IS_CU(RC.rrc[enb_mod_idP]->node_type)) {
+      rrc_rlc_config_asn1_req(&ctxt,
+                              NULL, // LTE_SRB_ToAddModList
+                              NULL,   // LTE_DRB_ToAddModList
+                              NULL,   // DRB_ToReleaseList
+                              &(RC.rrc[enb_mod_idP]->carrier[CC_id].mcch_message->pmch_InfoList_r9)
 #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
-                            ,0, 0
+			      ,0, 0
 #endif
-                           );
-    //rrc_mac_config_req();
+			      );
+    }
+	    //rrc_mac_config_req();
   }
 }
 #endif
@@ -692,6 +764,7 @@ rrc_eNB_get_next_free_ue_context(
           PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP));
     return NULL;
   }
+  return(ue_context_p);
 }
 
 //-----------------------------------------------------------------------------
@@ -846,30 +919,36 @@ rrc_eNB_free_UE(
     return;
   }
 
-  if (EPC_MODE_ENABLED) {
-    if ((ue_context_pP->ue_context.ul_failure_timer >= 20000) && (mac_eNB_get_rrc_status(enb_mod_idP, rnti) >= RRC_CONNECTED)) {
-      LOG_I(RRC, "[eNB %d] S1AP_UE_CONTEXT_RELEASE_REQ sent for RNTI %x, cause 21, radio connection with ue lost\n",
-            enb_mod_idP,
-            rnti);
-      rrc_eNB_send_S1AP_UE_CONTEXT_RELEASE_REQ(enb_mod_idP, ue_context_pP, S1AP_CAUSE_RADIO_NETWORK, 21);
-      // send cause 21: radio connection with ue lost
-      /* From 3GPP 36300v10 p129 : 19.2.2.2.2 S1 UE Context Release Request (eNB triggered)
-        * If the E-UTRAN internal reason is a radio link failure detected in the eNB, the eNB shall wait a sufficient time before
-        *  triggering the S1 UE Context Release Request procedure in order to allow the UE to perform the NAS recovery
-        *  procedure, see TS 23.401 [17].
-        */
-      return;
-    }
+   if(EPC_MODE_ENABLED) {
+     if (!NODE_IS_DU(RC.rrc[enb_mod_idP]->node_type)) {
+       if((ue_context_pP->ue_context.ul_failure_timer >= 20000) && (mac_eNB_get_rrc_status(enb_mod_idP, rnti) >= RRC_CONNECTED)) {
+         LOG_I(RRC, "[eNB %d] S1AP_UE_CONTEXT_RELEASE_REQ sent for RNTI %x, cause 21, radio connection with ue lost\n",
+               enb_mod_idP,
+               rnti);
+         rrc_eNB_send_S1AP_UE_CONTEXT_RELEASE_REQ(enb_mod_idP,
+                                                  ue_context_pP,
+                                                  S1AP_CAUSE_RADIO_NETWORK,
+                                                  21); // send cause 21: radio connection with ue lost
+        /* From 3GPP 36300v10 p129 : 19.2.2.2.2 S1 UE Context Release Request (eNB triggered)
+         * If the E-UTRAN internal reason is a radio link failure detected in the eNB, the eNB shall wait a sufficient time before
+         *  triggering the S1 UE Context Release Request procedure in order to allow the UE to perform the NAS recovery
+         *  procedure, see TS 23.401 [17].
+         */
+        return;
+      }
 
-    if((ue_context_pP->ue_context.ue_rrc_inactivity_timer >= RC.rrc[enb_mod_idP]->configuration.rrc_inactivity_timer_thres) &&
-        (mac_eNB_get_rrc_status(enb_mod_idP, rnti) >= RRC_CONNECTED) &&
-        (RC.rrc[enb_mod_idP]->configuration.rrc_inactivity_timer_thres > 0)) {
-      LOG_I(RRC, "[eNB %d] S1AP_UE_CONTEXT_RELEASE_REQ sent for RNTI %x, cause 20, user inactivity\n",
-            enb_mod_idP,
-            rnti);
-      rrc_eNB_send_S1AP_UE_CONTEXT_RELEASE_REQ(enb_mod_idP, ue_context_pP, S1AP_CAUSE_RADIO_NETWORK, 20);
-      // send cause 20: user inactivity
-      return;
+      if((ue_context_pP->ue_context.ue_rrc_inactivity_timer >= RC.rrc[enb_mod_idP]->configuration.rrc_inactivity_timer_thres) &&
+          (mac_eNB_get_rrc_status(enb_mod_idP, rnti) >= RRC_CONNECTED) &&
+          (RC.rrc[enb_mod_idP]->configuration.rrc_inactivity_timer_thres > 0)) {
+        LOG_I(RRC, "[eNB %d] S1AP_UE_CONTEXT_RELEASE_REQ sent for RNTI %x, cause 20, user inactivity\n",
+              enb_mod_idP,
+              rnti);
+        rrc_eNB_send_S1AP_UE_CONTEXT_RELEASE_REQ(enb_mod_idP,
+                                                 ue_context_pP,
+                                                 S1AP_CAUSE_RADIO_NETWORK,
+                                                 20); // send cause 20: user inactivity
+        return;
+      }
     }
   }
 
@@ -967,9 +1046,9 @@ void release_UE_in_freeList(module_id_t mod_id) {
           }
         }
 
-        if (rrc_agent_registered[mod_id]) {
-          agent_rrc_xface[mod_id]->flexran_agent_notify_ue_state_change(mod_id,
-              rnti, PROTOCOL__FLEX_UE_STATE_CHANGE_TYPE__FLUESC_DEACTIVATED);
+        if (flexran_agent_get_rrc_xface(mod_id)) {
+          flexran_agent_get_rrc_xface(mod_id)->flexran_agent_notify_ue_state_change(
+              mod_id, rnti, PROTOCOL__FLEX_UE_STATE_CHANGE_TYPE__FLUESC_DEACTIVATED);
         }
 
         for(j = 0; j < 10; j++) {
@@ -997,13 +1076,23 @@ void release_UE_in_freeList(module_id_t mod_id) {
         }
       }
 
-      rrc_mac_remove_ue(mod_id,rnti);
-      rrc_rlc_remove_ue(&ctxt);
-      pdcp_remove_UE(&ctxt);
+      if (!NODE_IS_CU(RC.rrc[mod_id]->node_type)) {
+        rrc_mac_remove_ue(mod_id,rnti);
+        rrc_rlc_remove_ue(&ctxt);
+        pdcp_remove_UE(&ctxt);
+      }
+      else {
+        MessageDef *m = itti_alloc_new_message(TASK_RRC_ENB, F1AP_UE_CONTEXT_RELEASE_CMD);
+        F1AP_UE_CONTEXT_RELEASE_CMD(m).rnti = rnti;
+        F1AP_UE_CONTEXT_RELEASE_CMD(m).cause = F1AP_CAUSE_RADIO_NETWORK;
+        F1AP_UE_CONTEXT_RELEASE_CMD(m).cause_value = 10; // 10 = F1AP_CauseRadioNetwork_normal_release
+        F1AP_UE_CONTEXT_RELEASE_CMD(m).rrc_container = NULL;
+        F1AP_UE_CONTEXT_RELEASE_CMD(m).rrc_container_length = 0;
+        itti_send_msg_to_task(TASK_CU_F1, mod_id, m);
+      }
 
       if(remove_UEContext) {
-        ue_context_pP = rrc_eNB_get_ue_context(
-                          RC.rrc[mod_id],rnti);
+        ue_context_pP = rrc_eNB_get_ue_context(RC.rrc[mod_id],rnti);
 
         if(ue_context_pP) {
           rrc_eNB_remove_ue_context(&ctxt,RC.rrc[mod_id],
@@ -1086,14 +1175,18 @@ rrc_eNB_generate_SecurityModeCommand(
     ue_context_pP->ue_context.rnti,
     rrc_eNB_mui,
     size);
-  rrc_data_req(
-    ctxt_pP,
-    DCCH,
-    rrc_eNB_mui++,
-    SDU_CONFIRM_NO,
-    size,
-    buffer,
-    PDCP_TRANSMISSION_MODE_CONTROL);
+
+  if (!NODE_IS_DU(RC.rrc[ctxt_pP->module_id]->node_type)) {
+    LOG_I(RRC,"calling rrc_data_req :securityModeCommand\n");
+
+    rrc_data_req(ctxt_pP,
+                 DCCH,
+                 rrc_eNB_mui++,
+                 SDU_CONFIRM_NO,
+                 size,
+                 buffer,
+                 PDCP_TRANSMISSION_MODE_CONTROL);
+  }
 }
 
 //-----------------------------------------------------------------------------
@@ -1153,26 +1246,29 @@ rrc_eNB_generate_RRCConnectionReject(
 {
   T(T_ENB_RRC_CONNECTION_REJECT, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame),
     T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti));
-  RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.payload_size =
+
+  eNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context;
+  ue_p->Srb0.Tx_buffer.payload_size =
     do_RRCConnectionReject(ctxt_pP->module_id,
-                           (uint8_t *) RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.Payload);
+                          (uint8_t*) ue_p->Srb0.Tx_buffer.Payload);
+
   LOG_DUMPMSG(RRC,DEBUG_RRC,
-              (char *)(RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.Payload),
-              RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.payload_size,
+              (char *)(ue_p->Srb0.Tx_buffer.Payload),
+              ue_p->Srb0.Tx_buffer.payload_size,
               "[MSG] RRCConnectionReject\n");
   MSC_LOG_TX_MESSAGE(
     MSC_RRC_ENB,
     MSC_RRC_UE,
-    RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.Header,
-    RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.payload_size,
+    ue_p->Srb0.Tx_buffer.Header,
+    ue_p->Srb0.Tx_buffer.payload_size,
     MSC_AS_TIME_FMT" LTE_RRCConnectionReject UE %x size %u",
     MSC_AS_TIME_ARGS(ctxt_pP),
     ue_context_pP == NULL ? -1 : ue_context_pP->ue_context.rnti,
-    RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.payload_size);
+    ue_p->Srb0.Tx_buffer.payload_size);
   LOG_I(RRC,
         PROTOCOL_RRC_CTXT_UE_FMT" [RAPROC] Logical Channel DL-CCCH, Generating LTE_RRCConnectionReject (bytes %d)\n",
         PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),
-        RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.payload_size);
+        ue_p->Srb0.Tx_buffer.payload_size);
 }
 
 //-----------------------------------------------------------------------------
@@ -1190,19 +1286,23 @@ rrc_eNB_generate_RRCConnectionReestablishment(
   int                                 cnt;
   T(T_ENB_RRC_CONNECTION_REESTABLISHMENT, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame),
     T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti));
-  SRB_configList = &ue_context_pP->ue_context.SRB_configList;
-  RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.payload_size =
+
+  eNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context; 
+
+  SRB_configList = &ue_p->SRB_configList;
+
+  ue_p->Srb0.Tx_buffer.payload_size =
     do_RRCConnectionReestablishment(ctxt_pP,
                                     ue_context_pP,
                                     CC_id,
-                                    (uint8_t *) RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.Payload,
+                                    (uint8_t *) ue_p->Srb0.Tx_buffer.Payload,
                                     (uint8_t) RC.rrc[ctxt_pP->module_id]->carrier[CC_id].p_eNB, //at this point we do not have the UE capability information, so it can only be TM1 or TM2
                                     rrc_eNB_get_next_transaction_identifier(ctxt_pP->module_id),
                                     SRB_configList,
                                     &ue_context_pP->ue_context.physicalConfigDedicated);
   LOG_DUMPMSG(RRC,DEBUG_RRC,
-              (char *)(RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.Payload),
-              RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.payload_size,
+              (char *)(ue_p->Srb0.Tx_buffer.Payload),
+              ue_p->Srb0.Tx_buffer.payload_size,
               "[MSG] RRCConnectionReestablishment\n"
              );
   // configure SRB1 for UE
@@ -1226,69 +1326,72 @@ rrc_eNB_generate_RRCConnectionReestablishment(
         LOG_D(RRC,
               PROTOCOL_RRC_CTXT_UE_FMT" RRC_eNB --- MAC_CONFIG_REQ  (SRB1) ---> MAC_eNB\n",
               PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP));
-        rrc_mac_config_req_eNB(ctxt_pP->module_id,
-                               ue_context_pP->ue_context.primaryCC_id,
-                               0,0,0,0,0,
+        if (NODE_IS_MONOLITHIC(RC.rrc[ctxt_pP->module_id]->node_type)) {
+          rrc_mac_config_req_eNB(ctxt_pP->module_id,
+                                 ue_context_pP->ue_context.primaryCC_id,
+                                 0,0,0,0,0,
 #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
-                               0,
+                                 0,
 #endif
-                               ctxt_pP->rnti,
-                               (LTE_BCCH_BCH_Message_t *) NULL,
-                               (LTE_RadioResourceConfigCommonSIB_t *) NULL,
+                                 ctxt_pP->rnti,
+                                 (LTE_BCCH_BCH_Message_t *) NULL,
+                                 (LTE_RadioResourceConfigCommonSIB_t *) NULL,
 #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
-                               (LTE_RadioResourceConfigCommonSIB_t *) NULL,
+                                 (LTE_RadioResourceConfigCommonSIB_t *) NULL,
 #endif
-                               (struct LTE_PhysicalConfigDedicated * ) ue_context_pP->ue_context.physicalConfigDedicated,
+                                 (struct LTE_PhysicalConfigDedicated * ) ue_context_pP->ue_context.physicalConfigDedicated,
 #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0))
-                               (LTE_SCellToAddMod_r10_t *)NULL,
-                               //(struct LTE_PhysicalConfigDedicatedSCell_r10 *)NULL,
+                                 (LTE_SCellToAddMod_r10_t *)NULL,
+                                 //(struct LTE_PhysicalConfigDedicatedSCell_r10 *)NULL,
 #endif
-                               (LTE_MeasObjectToAddMod_t **) NULL,
-                               ue_context_pP->ue_context.mac_MainConfig,
-                               1,
-                               SRB1_logicalChannelConfig,
-                               ue_context_pP->ue_context.measGapConfig,
-                               (LTE_TDD_Config_t *) NULL,
-                               NULL,
-                               (LTE_SchedulingInfoList_t *) NULL,
-                               0, NULL, NULL, (LTE_MBSFN_SubframeConfigList_t *) NULL
+                                 (LTE_MeasObjectToAddMod_t **) NULL,
+                                 ue_context_pP->ue_context.mac_MainConfig,
+                                 1,
+                                 SRB1_logicalChannelConfig,
+                                 ue_context_pP->ue_context.measGapConfig,
+                                 (LTE_TDD_Config_t *) NULL,
+                                 NULL,
+                                 (LTE_SchedulingInfoList_t *) NULL,
+                                 0, NULL, NULL, (LTE_MBSFN_SubframeConfigList_t *) NULL
 #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0))
-                               , 0, (LTE_MBSFN_AreaInfoList_r9_t *) NULL, (LTE_PMCH_InfoList_r9_t *) NULL
+                                 , 0, (LTE_MBSFN_AreaInfoList_r9_t *) NULL, (LTE_PMCH_InfoList_r9_t *) NULL
 #endif
 #if (LTE_RRC_VERSION >= MAKE_VERSION(13, 0, 0))
-                               ,(LTE_SystemInformationBlockType1_v1310_IEs_t *)NULL
+                                 ,(LTE_SystemInformationBlockType1_v1310_IEs_t *)NULL
 #endif
-                              );
-        break;
+                                );
+          break;
+        }
       }
     }
   }
 
   MSC_LOG_TX_MESSAGE(MSC_RRC_ENB,
                      MSC_RRC_UE,
-                     RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.Header,
-                     RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.payload_size,
+                     ue_p->Srb0.Tx_buffer.Header,
+                     ue_p->Srb0.Tx_buffer.payload_size,
                      MSC_AS_TIME_FMT" LTE_RRCConnectionReestablishment UE %x size %u",
                      MSC_AS_TIME_ARGS(ctxt_pP),
                      ue_context_pP->ue_context.rnti,
-                     RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.payload_size);
+                     ue_p->Srb0.Tx_buffer.payload_size);
+
   LOG_I(RRC,
         PROTOCOL_RRC_CTXT_UE_FMT" [RAPROC] Logical Channel DL-CCCH, Generating LTE_RRCConnectionReestablishment (bytes %d)\n",
         PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),
-        RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.payload_size);
-  int UE_id = find_UE_id(ctxt_pP->module_id, ctxt_pP->rnti);
-
-  if(UE_id != -1) {
-    // activate release timer, if RRCComplete not received after 100 frames, remove UE
-    RC.mac[ctxt_pP->module_id]->UE_list.UE_sched_ctrl[UE_id].ue_reestablishment_reject_timer = 1;
-    // remove UE after 100 frames after LTE_RRCConnectionReestablishmentRelease is triggered
-    RC.mac[ctxt_pP->module_id]->UE_list.UE_sched_ctrl[UE_id].ue_reestablishment_reject_timer_thres = 1000;
-  } else {
-    LOG_E(RRC,
-          PROTOCOL_RRC_CTXT_UE_FMT" Generating LTE_RRCConnectionReestablishment without UE_id(MAC) rnti %x\n",
-          PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),ctxt_pP->rnti);
+        ue_p->Srb0.Tx_buffer.payload_size);
+  if (!NODE_IS_CU(RC.rrc[ctxt_pP->module_id]->node_type)) {
+	  int UE_id = find_UE_id(ctxt_pP->module_id, ctxt_pP->rnti);
+	  if(UE_id != -1){
+	    // activate release timer, if RRCComplete not received after 100 frames, remove UE
+	    RC.mac[ctxt_pP->module_id]->UE_list.UE_sched_ctrl[UE_id].ue_reestablishment_reject_timer = 1;
+	    // remove UE after 100 frames after RRCConnectionReestablishmentRelease is triggered
+	    RC.mac[ctxt_pP->module_id]->UE_list.UE_sched_ctrl[UE_id].ue_reestablishment_reject_timer_thres = 1000;
+	  } else{
+	    LOG_E(RRC,
+	          PROTOCOL_RRC_CTXT_UE_FMT" Generating LTE_RRCConnectionReestablishment without UE_id(MAC) rnti %x\n",
+	          PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), ctxt_pP->rnti);
+	  }
   }
-
   // activate release timer, if RRCComplete not received after 100 frames, remove UE
   ue_context_pP->ue_context.ue_reestablishment_timer = 1;
   // remove UE after 100 frames after LTE_RRCConnectionReestablishmentRelease is triggered
@@ -1404,50 +1507,50 @@ rrc_eNB_process_RRCConnectionReestablishmentComplete(
   //ue_context_pP->ue_context.Srb2.Srb_info.Srb_id = 2;
 
   if (EPC_MODE_ENABLED) {
-    hashtable_rc_t    h_rc;
-    int               j;
-    rrc_ue_s1ap_ids_t *rrc_ue_s1ap_ids_p = NULL;
-    uint16_t ue_initial_id = ue_context_pP->ue_context.ue_initial_id;
-    uint32_t eNB_ue_s1ap_id = ue_context_pP->ue_context.eNB_ue_s1ap_id;
-    eNB_RRC_INST *rrc_instance_p = RC.rrc[ENB_INSTANCE_TO_MODULE_ID(ctxt_pP->instance)];
-
-    if (eNB_ue_s1ap_id > 0) {
-      h_rc = hashtable_get(rrc_instance_p->s1ap_id2_s1ap_ids, (hash_key_t)eNB_ue_s1ap_id, (void **)&rrc_ue_s1ap_ids_p);
-
-      if  (h_rc == HASH_TABLE_OK) {
-        rrc_ue_s1ap_ids_p->ue_rnti = ctxt_pP->rnti;
-      }
+  hashtable_rc_t    h_rc;
+  int               j;
+  rrc_ue_s1ap_ids_t *rrc_ue_s1ap_ids_p = NULL;
+  uint16_t ue_initial_id = ue_context_pP->ue_context.ue_initial_id;
+  uint32_t eNB_ue_s1ap_id = ue_context_pP->ue_context.eNB_ue_s1ap_id;
+  eNB_RRC_INST *rrc_instance_p = RC.rrc[ENB_INSTANCE_TO_MODULE_ID(ctxt_pP->instance)];
+
+  if (eNB_ue_s1ap_id > 0) {
+    h_rc = hashtable_get(rrc_instance_p->s1ap_id2_s1ap_ids, (hash_key_t)eNB_ue_s1ap_id, (void **)&rrc_ue_s1ap_ids_p);
+
+    if  (h_rc == HASH_TABLE_OK) {
+      rrc_ue_s1ap_ids_p->ue_rnti = ctxt_pP->rnti;
     }
+  }
 
-    if (ue_initial_id != 0) {
-      h_rc = hashtable_get(rrc_instance_p->initial_id2_s1ap_ids, (hash_key_t)ue_initial_id, (void **)&rrc_ue_s1ap_ids_p);
+  if (ue_initial_id != 0) {
+    h_rc = hashtable_get(rrc_instance_p->initial_id2_s1ap_ids, (hash_key_t)ue_initial_id, (void **)&rrc_ue_s1ap_ids_p);
 
-      if  (h_rc == HASH_TABLE_OK) {
-        rrc_ue_s1ap_ids_p->ue_rnti = ctxt_pP->rnti;
-      }
+    if  (h_rc == HASH_TABLE_OK) {
+      rrc_ue_s1ap_ids_p->ue_rnti = ctxt_pP->rnti;
     }
+  }
 
-    gtpv1u_enb_create_tunnel_req_t  create_tunnel_req;
-    /* Save e RAB information for later */
-    memset(&create_tunnel_req, 0, sizeof(create_tunnel_req));
-
-    for ( j = 0, i = 0; i < NB_RB_MAX; i++) {
-      if (ue_context_pP->ue_context.e_rab[i].status == E_RAB_STATUS_ESTABLISHED || ue_context_pP->ue_context.e_rab[i].status == E_RAB_STATUS_DONE) {
-        create_tunnel_req.eps_bearer_id[j]   = ue_context_pP->ue_context.e_rab[i].param.e_rab_id;
-        create_tunnel_req.sgw_S1u_teid[j]  = ue_context_pP->ue_context.e_rab[i].param.gtp_teid;
-        memcpy(&create_tunnel_req.sgw_addr[j],
-               &ue_context_pP->ue_context.e_rab[i].param.sgw_addr,
-               sizeof(transport_layer_addr_t));
-        j++;
-      }
+  gtpv1u_enb_create_tunnel_req_t  create_tunnel_req;
+  /* Save e RAB information for later */
+  memset(&create_tunnel_req, 0, sizeof(create_tunnel_req));
+
+  for ( j = 0, i = 0; i < NB_RB_MAX; i++) {
+    if (ue_context_pP->ue_context.e_rab[i].status == E_RAB_STATUS_ESTABLISHED || ue_context_pP->ue_context.e_rab[i].status == E_RAB_STATUS_DONE) {
+      create_tunnel_req.eps_bearer_id[j]   = ue_context_pP->ue_context.e_rab[i].param.e_rab_id;
+      create_tunnel_req.sgw_S1u_teid[j]  = ue_context_pP->ue_context.e_rab[i].param.gtp_teid;
+      memcpy(&create_tunnel_req.sgw_addr[j],
+             &ue_context_pP->ue_context.e_rab[i].param.sgw_addr,
+             sizeof(transport_layer_addr_t));
+      j++;
     }
+  }
 
-    create_tunnel_req.rnti       = ctxt_pP->rnti; // warning put zero above
-    create_tunnel_req.num_tunnels    = j;
-    gtpv1u_update_s1u_tunnel(
-      ctxt_pP->instance,
-      &create_tunnel_req,
-      reestablish_rnti);
+  create_tunnel_req.rnti       = ctxt_pP->rnti; // warning put zero above
+  create_tunnel_req.num_tunnels    = j;
+  gtpv1u_update_s1u_tunnel(
+    ctxt_pP->instance,
+    &create_tunnel_req,
+    reestablish_rnti);
   } /* EPC_MODE_ENABLED */
 
   /* Update RNTI in ue_context */
@@ -1455,12 +1558,12 @@ rrc_eNB_process_RRCConnectionReestablishmentComplete(
   ue_context_pP->ue_context.rnti               = ctxt_pP->rnti;
 
   if (EPC_MODE_ENABLED) {
-    uint8_t send_security_mode_command = FALSE;
-    rrc_pdcp_config_security(
-      ctxt_pP,
-      ue_context_pP,
-      send_security_mode_command);
-    LOG_D(RRC, "set security successfully \n");
+  uint8_t send_security_mode_command = FALSE;
+  rrc_pdcp_config_security(
+    ctxt_pP,
+    ue_context_pP,
+    send_security_mode_command);
+  LOG_D(RRC, "set security successfully \n");
   }
 
   // Measurement ID list
@@ -1738,6 +1841,7 @@ rrc_eNB_process_RRCConnectionReestablishmentComplete(
     }
     /* TODO should test if e RAB are Ok before! */
     ue_context_pP->ue_context.e_rab[i].status = E_RAB_STATUS_DONE;
+    ue_context_pP->ue_context.e_rab[i].xid    = xid;
     LOG_D(RRC, "setting the status for the default DRB (index %d) to (%d,%s)\n",
           i, ue_context_pP->ue_context.e_rab[i].status, "E_RAB_STATUS_DONE");
   }
@@ -1878,6 +1982,7 @@ rrc_eNB_generate_RRCConnectionReestablishmentReject(
 )
 //-----------------------------------------------------------------------------
 {
+ if (!NODE_IS_CU(RC.rrc[ctxt_pP->module_id]->node_type)) {
   int UE_id = find_UE_id(ctxt_pP->module_id, ctxt_pP->rnti);
 
   if(UE_id != -1) {
@@ -1888,29 +1993,34 @@ rrc_eNB_generate_RRCConnectionReestablishmentReject(
           PROTOCOL_RRC_CTXT_UE_FMT" Generating LTE_RRCConnectionReestablishmentReject without UE_id(MAC) rnti %x\n",
           PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),ctxt_pP->rnti);
   }
-
+ }
   T(T_ENB_RRC_CONNECTION_REESTABLISHMENT_REJECT, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame),
     T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti));
-  RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.payload_size =
+
+  eNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context; 
+
+  ue_p->Srb0.Tx_buffer.payload_size =
     do_RRCConnectionReestablishmentReject(ctxt_pP->module_id,
-                                          (uint8_t *) RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.Payload);
+                          (uint8_t*) ue_p->Srb0.Tx_buffer.Payload);
+
   LOG_DUMPMSG(RRC,DEBUG_RRC,
-              (char *)(RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.Payload),
-              RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.payload_size,
+              (char *)(ue_p->Srb0.Tx_buffer.Payload),
+              ue_p->Srb0.Tx_buffer.payload_size,
               "[MSG] RRCConnectionReestablishmentReject\n");
   MSC_LOG_TX_MESSAGE(
     MSC_RRC_ENB,
     MSC_RRC_UE,
-    RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.Header,
-    RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.payload_size,
+    ue_p->Srb0.Tx_buffer.Header,
+    ue_p->Srb0.Tx_buffer.payload_size,
     MSC_AS_TIME_FMT" LTE_RRCConnectionReestablishmentReject UE %x size %u",
     MSC_AS_TIME_ARGS(ctxt_pP),
     ue_context_pP == NULL ? -1 : ue_context_pP->ue_context.rnti,
-    RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.payload_size);
+    ue_p->Srb0.Tx_buffer.payload_size);
+
   LOG_I(RRC,
         PROTOCOL_RRC_CTXT_UE_FMT" [RAPROC] Logical Channel DL-CCCH, Generating LTE_RRCConnectionReestablishmentReject (bytes %d)\n",
         PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),
-        RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.payload_size);
+        ue_p->Srb0.Tx_buffer.payload_size);
 }
 
 //-----------------------------------------------------------------------------
@@ -1977,13 +2087,23 @@ rrc_eNB_generate_RRCConnectionRelease(
   }
 
   pthread_mutex_unlock(&rrc_release_freelist);
-  rrc_data_req(ctxt_pP,
-               DCCH,
-               rrc_eNB_mui++,
-               SDU_CONFIRM_NO,
-               size,
-               buffer,
-               PDCP_TRANSMISSION_MODE_CONTROL);
+  if (NODE_IS_CU(RC.rrc[ctxt_pP->module_id]->node_type)) {
+    MessageDef *m = itti_alloc_new_message(TASK_RRC_ENB, F1AP_UE_CONTEXT_RELEASE_CMD);
+    F1AP_UE_CONTEXT_RELEASE_CMD(m).rnti = ctxt_pP->rnti;
+    F1AP_UE_CONTEXT_RELEASE_CMD(m).cause = F1AP_CAUSE_RADIO_NETWORK;
+    F1AP_UE_CONTEXT_RELEASE_CMD(m).cause_value = 10; // 10 = F1AP_CauseRadioNetwork_normal_release
+    F1AP_UE_CONTEXT_RELEASE_CMD(m).rrc_container = buffer;
+    F1AP_UE_CONTEXT_RELEASE_CMD(m).rrc_container_length = size;
+    itti_send_msg_to_task(TASK_CU_F1, ctxt_pP->module_id, m);
+  } else {
+    rrc_data_req(ctxt_pP,
+                 DCCH,
+                 rrc_eNB_mui++,
+                 SDU_CONFIRM_NO,
+                 size,
+                 buffer,
+                 PDCP_TRANSMISSION_MODE_CONTROL);
+  }
 }
 
 uint8_t qci_to_priority[9]= {2,4,3,5,1,6,7,8,9};
@@ -2840,41 +2960,41 @@ rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t *cons
       LOG_D(RRC,"Setting transmission mode to %ld+1\n",rrc_inst->configuration.radioresourceconfig[0].ue_TransmissionMode);
 
       if (rrc_inst->configuration.radioresourceconfig[0].ue_TransmissionMode==LTE_AntennaInfoDedicated__transmissionMode_tm3) {
-        (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction=
-          CALLOC(1,sizeof(LTE_AntennaInfoDedicated__codebookSubsetRestriction_PR));
-        (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->present =
-          LTE_AntennaInfoDedicated__codebookSubsetRestriction_PR_n2TxAntenna_tm3;
-        (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm3.buf= MALLOC(1);
-        (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm3.buf[0] = 0xc0;
-        (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm3.size=1;
-        (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm3.bits_unused=6;
+	(*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction=     
+	  CALLOC(1,sizeof(LTE_AntennaInfoDedicated__codebookSubsetRestriction_PR));
+	(*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->present =
+	  LTE_AntennaInfoDedicated__codebookSubsetRestriction_PR_n2TxAntenna_tm3;
+	(*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm3.buf= MALLOC(1);
+	(*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm3.buf[0] = 0xc0;
+	(*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm3.size=1;
+	(*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm3.bits_unused=6;
       } else if (rrc_inst->configuration.radioresourceconfig[0].ue_TransmissionMode==LTE_AntennaInfoDedicated__transmissionMode_tm4) {
-        (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction=
-          CALLOC(1,sizeof(LTE_AntennaInfoDedicated__codebookSubsetRestriction_PR));
-        (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->present =
-          LTE_AntennaInfoDedicated__codebookSubsetRestriction_PR_n2TxAntenna_tm4;
-        (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm4.buf= MALLOC(1);
-        (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm4.buf[0] = 0xfc;
-        (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm4.size=1;
-        (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm4.bits_unused=2;
+	(*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction=     
+	  CALLOC(1,sizeof(LTE_AntennaInfoDedicated__codebookSubsetRestriction_PR));
+	(*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->present =
+	  LTE_AntennaInfoDedicated__codebookSubsetRestriction_PR_n2TxAntenna_tm4;
+	(*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm4.buf= MALLOC(1);
+	(*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm4.buf[0] = 0xfc;
+	(*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm4.size=1;
+	(*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm4.bits_unused=2;
       } else if (rrc_inst->configuration.radioresourceconfig[0].ue_TransmissionMode==LTE_AntennaInfoDedicated__transmissionMode_tm5) {
-        (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction=
-          CALLOC(1,sizeof(LTE_AntennaInfoDedicated__codebookSubsetRestriction_PR));
-        (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->present =
-          LTE_AntennaInfoDedicated__codebookSubsetRestriction_PR_n2TxAntenna_tm5;
-        (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm5.buf= MALLOC(1);
-        (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm5.buf[0] = 0xf0;
-        (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm5.size=1;
-        (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm5.bits_unused=4;
+	(*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction=     
+	  CALLOC(1,sizeof(LTE_AntennaInfoDedicated__codebookSubsetRestriction_PR));
+	(*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->present =
+	  LTE_AntennaInfoDedicated__codebookSubsetRestriction_PR_n2TxAntenna_tm5;
+	(*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm5.buf= MALLOC(1);
+	(*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm5.buf[0] = 0xf0;
+	(*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm5.size=1;
+	(*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm5.bits_unused=4;
       } else if (rrc_inst->configuration.radioresourceconfig[0].ue_TransmissionMode==LTE_AntennaInfoDedicated__transmissionMode_tm6) {
-        (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction=
-          CALLOC(1,sizeof(LTE_AntennaInfoDedicated__codebookSubsetRestriction_PR));
-        (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->present =
-          LTE_AntennaInfoDedicated__codebookSubsetRestriction_PR_n2TxAntenna_tm6;
-        (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm6.buf= MALLOC(1);
-        (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm6.buf[0] = 0xf0;
-        (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm6.size=1;
-        (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm6.bits_unused=4;
+	(*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction=     
+	  CALLOC(1,sizeof(LTE_AntennaInfoDedicated__codebookSubsetRestriction_PR));
+	(*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->present =
+	  LTE_AntennaInfoDedicated__codebookSubsetRestriction_PR_n2TxAntenna_tm6;
+	(*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm6.buf= MALLOC(1);
+	(*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm6.buf[0] = 0xf0;
+	(*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm6.size=1;
+	(*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm6.bits_unused=4;
       }
     } else {
       LOG_E(RRC,"antenna_info not present in physical_config_dedicated. Not reconfiguring!\n");
@@ -2882,11 +3002,11 @@ rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t *cons
 
     if ((*physicalConfigDedicated)->cqi_ReportConfig) {
       if ((rrc_inst->configuration.radioresourceconfig[0].ue_TransmissionMode==LTE_AntennaInfoDedicated__transmissionMode_tm4) ||
-          (rrc_inst->configuration.radioresourceconfig[0].ue_TransmissionMode==LTE_AntennaInfoDedicated__transmissionMode_tm5) ||
-          (rrc_inst->configuration.radioresourceconfig[0].ue_TransmissionMode==LTE_AntennaInfoDedicated__transmissionMode_tm6)) {
-        //feedback mode needs to be set as well
-        //TODO: I think this is taken into account in the PHY automatically based on the transmission mode variable
-        printf("setting cqi reporting mode to rm31\n");
+	  (rrc_inst->configuration.radioresourceconfig[0].ue_TransmissionMode==LTE_AntennaInfoDedicated__transmissionMode_tm5) ||
+	  (rrc_inst->configuration.radioresourceconfig[0].ue_TransmissionMode==LTE_AntennaInfoDedicated__transmissionMode_tm6)) {
+	//feedback mode needs to be set as well
+	//TODO: I think this is taken into account in the PHY automatically based on the transmission mode variable
+	printf("setting cqi reporting mode to rm31\n");
 #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0))
         *((*physicalConfigDedicated)->cqi_ReportConfig->cqi_ReportModeAperiodic)=LTE_CQI_ReportModeAperiodic_rm31;
 #else
@@ -2942,8 +3062,10 @@ rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t *cons
   memset((void *)MeasObj, 0, sizeof(*MeasObj));
   MeasObj->measObjectId = 1;
   MeasObj->measObject.present = LTE_MeasObjectToAddMod__measObject_PR_measObjectEUTRA;
-  MeasObj->measObject.choice.measObjectEUTRA.carrierFreq = (LTE_ARFCN_ValueEUTRA_t)to_earfcn_DL(RC.rrc[ctxt_pP->module_id]->carrier[0].eutra_band, RC.rrc[ctxt_pP->module_id]->carrier[0].dl_CarrierFreq,
-      RC.rrc[ctxt_pP->module_id]->carrier[0].N_RB_DL);
+  MeasObj->measObject.choice.measObjectEUTRA.carrierFreq =
+      to_earfcn_DL(RC.rrc[ctxt_pP->module_id]->configuration.eutra_band[0],
+                   RC.rrc[ctxt_pP->module_id]->configuration.downlink_frequency[0],
+                   RC.rrc[ctxt_pP->module_id]->configuration.N_RB_DL[0]);
   MeasObj->measObject.choice.measObjectEUTRA.allowedMeasBandwidth = LTE_AllowedMeasBandwidth_mbw25;
   MeasObj->measObject.choice.measObjectEUTRA.presenceAntennaPort1 = 1;
   MeasObj->measObject.choice.measObjectEUTRA.neighCellConfig.buf = CALLOC(1, sizeof(uint8_t));
@@ -3473,41 +3595,41 @@ flexran_rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt
       LOG_D(RRC,"Setting transmission mode to %ld+1\n",rrc_inst->configuration.radioresourceconfig[0].ue_TransmissionMode);
 
       if (rrc_inst->configuration.radioresourceconfig[0].ue_TransmissionMode==LTE_AntennaInfoDedicated__transmissionMode_tm3) {
-        (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction=
-          CALLOC(1,sizeof(LTE_AntennaInfoDedicated__codebookSubsetRestriction_PR));
-        (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->present =
-          LTE_AntennaInfoDedicated__codebookSubsetRestriction_PR_n2TxAntenna_tm3;
-        (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm3.buf= MALLOC(1);
-        (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm3.buf[0] = 0xc0;
-        (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm3.size=1;
-        (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm3.bits_unused=6;
+	(*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction=
+	  CALLOC(1,sizeof(LTE_AntennaInfoDedicated__codebookSubsetRestriction_PR));
+	(*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->present =
+	  LTE_AntennaInfoDedicated__codebookSubsetRestriction_PR_n2TxAntenna_tm3;
+	(*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm3.buf= MALLOC(1);
+	(*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm3.buf[0] = 0xc0;
+	(*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm3.size=1;
+	(*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm3.bits_unused=6;
       } else if (rrc_inst->configuration.radioresourceconfig[0].ue_TransmissionMode==LTE_AntennaInfoDedicated__transmissionMode_tm4) {
-        (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction=
-          CALLOC(1,sizeof(LTE_AntennaInfoDedicated__codebookSubsetRestriction_PR));
-        (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->present =
-          LTE_AntennaInfoDedicated__codebookSubsetRestriction_PR_n2TxAntenna_tm4;
-        (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm4.buf= MALLOC(1);
-        (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm4.buf[0] = 0xfc;
-        (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm4.size=1;
-        (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm4.bits_unused=2;
+	(*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction=
+	  CALLOC(1,sizeof(LTE_AntennaInfoDedicated__codebookSubsetRestriction_PR));
+	(*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->present =
+	  LTE_AntennaInfoDedicated__codebookSubsetRestriction_PR_n2TxAntenna_tm4;
+	(*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm4.buf= MALLOC(1);
+	(*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm4.buf[0] = 0xfc;
+	(*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm4.size=1;
+	(*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm4.bits_unused=2;
       } else if (rrc_inst->configuration.radioresourceconfig[0].ue_TransmissionMode==LTE_AntennaInfoDedicated__transmissionMode_tm5) {
-        (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction=
-          CALLOC(1,sizeof(LTE_AntennaInfoDedicated__codebookSubsetRestriction_PR));
-        (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->present =
-          LTE_AntennaInfoDedicated__codebookSubsetRestriction_PR_n2TxAntenna_tm5;
-        (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm5.buf= MALLOC(1);
-        (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm5.buf[0] = 0xf0;
-        (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm5.size=1;
-        (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm5.bits_unused=4;
+	(*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction=
+	  CALLOC(1,sizeof(LTE_AntennaInfoDedicated__codebookSubsetRestriction_PR));
+	(*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->present =
+	  LTE_AntennaInfoDedicated__codebookSubsetRestriction_PR_n2TxAntenna_tm5;
+	(*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm5.buf= MALLOC(1);
+	(*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm5.buf[0] = 0xf0;
+	(*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm5.size=1;
+	(*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm5.bits_unused=4;
       } else if (rrc_inst->configuration.radioresourceconfig[0].ue_TransmissionMode==LTE_AntennaInfoDedicated__transmissionMode_tm6) {
-        (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction=
-          CALLOC(1,sizeof(LTE_AntennaInfoDedicated__codebookSubsetRestriction_PR));
-        (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->present =
-          LTE_AntennaInfoDedicated__codebookSubsetRestriction_PR_n2TxAntenna_tm6;
-        (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm6.buf= MALLOC(1);
-        (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm6.buf[0] = 0xf0;
-        (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm6.size=1;
-        (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm6.bits_unused=4;
+	(*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction=
+	  CALLOC(1,sizeof(LTE_AntennaInfoDedicated__codebookSubsetRestriction_PR));
+	(*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->present =
+	  LTE_AntennaInfoDedicated__codebookSubsetRestriction_PR_n2TxAntenna_tm6;
+	(*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm6.buf= MALLOC(1);
+	(*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm6.buf[0] = 0xf0;
+	(*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm6.size=1;
+	(*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm6.bits_unused=4;
       }
     } else {
       LOG_E(RRC,"antenna_info not present in physical_config_dedicated. Not reconfiguring!\n");
@@ -3515,11 +3637,11 @@ flexran_rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt
 
     if ((*physicalConfigDedicated)->cqi_ReportConfig) {
       if ((rrc_inst->configuration.radioresourceconfig[0].ue_TransmissionMode==LTE_AntennaInfoDedicated__transmissionMode_tm4) ||
-          (rrc_inst->configuration.radioresourceconfig[0].ue_TransmissionMode==LTE_AntennaInfoDedicated__transmissionMode_tm5) ||
-          (rrc_inst->configuration.radioresourceconfig[0].ue_TransmissionMode==LTE_AntennaInfoDedicated__transmissionMode_tm6)) {
-        //feedback mode needs to be set as well
-        //TODO: I think this is taken into account in the PHY automatically based on the transmission mode variable
-        printf("setting cqi reporting mode to rm31\n");
+	  (rrc_inst->configuration.radioresourceconfig[0].ue_TransmissionMode==LTE_AntennaInfoDedicated__transmissionMode_tm5) ||
+	  (rrc_inst->configuration.radioresourceconfig[0].ue_TransmissionMode==LTE_AntennaInfoDedicated__transmissionMode_tm6)) {
+	//feedback mode needs to be set as well
+	//TODO: I think this is taken into account in the PHY automatically based on the transmission mode variable
+	printf("setting cqi reporting mode to rm31\n");
 #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0))
         *((*physicalConfigDedicated)->cqi_ReportConfig->cqi_ReportModeAperiodic)=LTE_CQI_ReportModeAperiodic_rm31;
 #else
@@ -4204,11 +4326,11 @@ check_handovers(
               ctxt_pP->module_id, ctxt_pP->frame, ue_context_p->ue_context.rnti);
         rrc_data_req(
           ctxt_pP,
-          DCCH,
-          rrc_eNB_mui++,
-          SDU_CONFIRM_NO,
-          ue_context_p->ue_context.handover_info->size,
-          ue_context_p->ue_context.handover_info->buf,
+                               DCCH,
+                               rrc_eNB_mui++,
+                               SDU_CONFIRM_NO,
+                               ue_context_p->ue_context.handover_info->size,
+                               ue_context_p->ue_context.handover_info->buf,
           PDCP_TRANSMISSION_MODE_CONTROL);
 
         ue_context_p->ue_context.handover_info->state = HO_COMPLETE;
@@ -4764,8 +4886,10 @@ rrc_eNB_generate_HO_RRCConnectionReconfiguration(const protocol_ctxt_t *const ct
   memset((void *)MeasObj, 0, sizeof(*MeasObj));
   MeasObj->measObjectId = 1;
   MeasObj->measObject.present = LTE_MeasObjectToAddMod__measObject_PR_measObjectEUTRA;
-  MeasObj->measObject.choice.measObjectEUTRA.carrierFreq = (LTE_ARFCN_ValueEUTRA_t)to_earfcn_DL(RC.rrc[ctxt_pP->module_id]->carrier[0].eutra_band, RC.rrc[ctxt_pP->module_id]->carrier[0].dl_CarrierFreq,
-      RC.rrc[ctxt_pP->module_id]->carrier[0].N_RB_DL);
+  MeasObj->measObject.choice.measObjectEUTRA.carrierFreq =
+      to_earfcn_DL(RC.rrc[ctxt_pP->module_id]->configuration.eutra_band[0],
+                   RC.rrc[ctxt_pP->module_id]->configuration.downlink_frequency[0],
+                   RC.rrc[ctxt_pP->module_id]->configuration.N_RB_DL[0]);
   MeasObj->measObject.choice.measObjectEUTRA.allowedMeasBandwidth = LTE_AllowedMeasBandwidth_mbw25;
   MeasObj->measObject.choice.measObjectEUTRA.presenceAntennaPort1 = 1;
   MeasObj->measObject.choice.measObjectEUTRA.neighCellConfig.buf = CALLOC(1, sizeof(uint8_t));
@@ -4993,8 +5117,10 @@ rrc_eNB_generate_HO_RRCConnectionReconfiguration(const protocol_ctxt_t *const ct
     rrc_inst->carrier[0] /* CROUX TBC */.sib2->radioResourceConfigCommon.ul_CyclicPrefixLength;
   //End of configuration of radioResourceConfigCommon
   mobilityInfo->carrierFreq = CALLOC(1, sizeof(*mobilityInfo->carrierFreq));  //CALLOC(1,sizeof(CarrierFreqEUTRA_t)); 36090
-  mobilityInfo->carrierFreq->dl_CarrierFreq = (LTE_ARFCN_ValueEUTRA_t)to_earfcn_DL(RC.rrc[ctxt_pP->module_id]->carrier[0].eutra_band, RC.rrc[ctxt_pP->module_id]->carrier[0].dl_CarrierFreq,
-      RC.rrc[ctxt_pP->module_id]->carrier[0].N_RB_DL);
+  mobilityInfo->carrierFreq->dl_CarrierFreq =
+      to_earfcn_DL(RC.rrc[ctxt_pP->module_id]->configuration.eutra_band[0],
+                   RC.rrc[ctxt_pP->module_id]->configuration.downlink_frequency[0],
+                   RC.rrc[ctxt_pP->module_id]->configuration.N_RB_DL[0]);
   mobilityInfo->carrierFreq->ul_CarrierFreq = NULL;
   mobilityInfo->carrierBandwidth = CALLOC(1, sizeof(
       *mobilityInfo->carrierBandwidth));    //CALLOC(1,sizeof(struct CarrierBandwidthEUTRA));  AllowedMeasBandwidth_mbw25
@@ -5190,18 +5316,18 @@ rrc_eNB_configure_rbs_handover(struct rrc_eNB_ue_context_s *ue_context_p, protoc
                          );
 
   if (EPC_MODE_ENABLED) {
-    rrc_eNB_process_security (
-      ctxt_pP,
-      ue_context_p,
-      &ue_context_p->ue_context.security_capabilities);
-    process_eNB_security_key (
-      ctxt_pP,
-      ue_context_p,
-      ue_context_p->ue_context.kenb);
-    rrc_pdcp_config_security(
-      ctxt_pP,
-      ue_context_p,
-      FALSE);
+  rrc_eNB_process_security (
+    ctxt_pP,
+    ue_context_p,
+    &ue_context_p->ue_context.security_capabilities);
+  process_eNB_security_key (
+    ctxt_pP,
+    ue_context_p,
+    ue_context_p->ue_context.kenb);
+  rrc_pdcp_config_security(
+    ctxt_pP,
+    ue_context_p,
+    FALSE);
   }
 
   // Add a new user (called during the HO procedure)
@@ -5245,9 +5371,9 @@ rrc_eNB_configure_rbs_handover(struct rrc_eNB_ue_context_s *ue_context_p, protoc
     (LTE_SystemInformationBlockType1_v1310_IEs_t *)NULL
 #endif
   );
-#if 0
-}
-#endif
+//#if 0
+//}
+//#endif
 }
 
 //-----------------------------------------------------------------------------
@@ -5387,32 +5513,32 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete(
                 ctxt_pP->module_id, ctxt_pP->frame, (int)DRB_configList->list.array[i]->drb_Identity);
 
           if (!EPC_MODE_ENABLED && !ENB_NAS_USE_TUN) {
-            LOG_I(OIP, "[eNB %d] trying to bring up the OAI interface oai%d\n",
-                  ctxt_pP->module_id,
-                  ctxt_pP->module_id);
-            oip_ifup = nas_config(
-                         ctxt_pP->module_id,   // interface index
+          LOG_I(OIP, "[eNB %d] trying to bring up the OAI interface oai%d\n",
+                ctxt_pP->module_id,
+                ctxt_pP->module_id);
+          oip_ifup = nas_config(
+                       ctxt_pP->module_id,   // interface index
                          ctxt_pP->module_id + 1,   // thrid octet
                          ctxt_pP->module_id + 1,   // fourth octet
                          "oai");
 
-            if (oip_ifup == 0) {    // interface is up --> send a config the DRB
-              module_id_t ue_module_id;
-              dest_ip_offset = 8;
-              LOG_I(OIP,
-                    "[eNB %d] Config the oai%d to send/receive pkt on DRB %ld to/from the protocol stack\n",
-                    ctxt_pP->module_id, ctxt_pP->module_id,
+          if (oip_ifup == 0) {    // interface is up --> send a config the DRB
+            module_id_t ue_module_id;
+            dest_ip_offset = 8;
+            LOG_I(OIP,
+                  "[eNB %d] Config the oai%d to send/receive pkt on DRB %ld to/from the protocol stack\n",
+                  ctxt_pP->module_id, ctxt_pP->module_id,
                     (long int)((ue_context_pP->local_uid * LTE_maxDRB) + DRB_configList->list.array[i]->drb_Identity));
-              ue_module_id = oai_emulation.info.eNB_ue_local_uid_to_ue_module_id[ctxt_pP->module_id][ue_context_pP->local_uid];
-              rb_conf_ipv4(0, //add
-                           ue_module_id,  //cx
-                           ctxt_pP->module_id,    //inst
+            ue_module_id = oai_emulation.info.eNB_ue_local_uid_to_ue_module_id[ctxt_pP->module_id][ue_context_pP->local_uid];
+            rb_conf_ipv4(0, //add
+                         ue_module_id,  //cx
+                         ctxt_pP->module_id,    //inst
                            (ue_module_id * LTE_maxDRB) + DRB_configList->list.array[i]->drb_Identity, // RB
-                           0,    //dscp
-                           ipv4_address(ctxt_pP->module_id + 1, ctxt_pP->module_id + 1),  //saddr
-                           ipv4_address(ctxt_pP->module_id + 1, dest_ip_offset + ue_module_id + 1));  //daddr
-              LOG_D(RRC, "[eNB %d] State = Attached (UE rnti %x module id %u)\n",
-                    ctxt_pP->module_id, ue_context_pP->ue_context.rnti, ue_module_id);
+                         0,    //dscp
+                         ipv4_address(ctxt_pP->module_id + 1, ctxt_pP->module_id + 1),  //saddr
+                         ipv4_address(ctxt_pP->module_id + 1, dest_ip_offset + ue_module_id + 1));  //daddr
+            LOG_D(RRC, "[eNB %d] State = Attached (UE rnti %x module id %u)\n",
+                  ctxt_pP->module_id, ue_context_pP->ue_context.rnti, ue_module_id);
             } /* oip_ifup */
           } /* !EPC_MODE_ENABLED && ENB_NAS_USE_TUN*/
 
@@ -5424,98 +5550,102 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete(
             DRB2LCHAN[i] = (uint8_t) * DRB_configList->list.array[i]->logicalChannelIdentity;
           }
 
-          rrc_mac_config_req_eNB(
-            ctxt_pP->module_id,
-            ue_context_pP->ue_context.primaryCC_id,
-            0,0,0,0,0,
+	  if (NODE_IS_MONOLITHIC(RC.rrc[ctxt_pP->module_id]->node_type)) {
+	    rrc_mac_config_req_eNB(ctxt_pP->module_id,
+                             ue_context_pP->ue_context.primaryCC_id,
+                             0,0,0,0,0,
 #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
-            0,
+                             0,
 #endif
-            ue_context_pP->ue_context.rnti,
-            (LTE_BCCH_BCH_Message_t *) NULL,
-            (LTE_RadioResourceConfigCommonSIB_t *) NULL,
+                             ue_context_pP->ue_context.rnti,
+                             (LTE_BCCH_BCH_Message_t *) NULL,
+                             (LTE_RadioResourceConfigCommonSIB_t *) NULL,
 #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
-            (LTE_RadioResourceConfigCommonSIB_t *) NULL,
+                             (LTE_RadioResourceConfigCommonSIB_t *) NULL,
 #endif
-            ue_context_pP->ue_context.physicalConfigDedicated,
+                             ue_context_pP->ue_context.physicalConfigDedicated,
 #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0))
-            (LTE_SCellToAddMod_r10_t *)NULL,
-            //(struct LTE_PhysicalConfigDedicatedSCell_r10 *)NULL,
+                             (LTE_SCellToAddMod_r10_t *)NULL,
+                             //(struct LTE_PhysicalConfigDedicatedSCell_r10 *)NULL,
 #endif
-            (LTE_MeasObjectToAddMod_t **) NULL,
-            ue_context_pP->ue_context.mac_MainConfig,
-            DRB2LCHAN[i],
-            DRB_configList->list.array[i]->logicalChannelConfig,
-            ue_context_pP->ue_context.measGapConfig,
-            (LTE_TDD_Config_t *) NULL,
-            NULL,
-            (LTE_SchedulingInfoList_t *) NULL,
-            0, NULL, NULL, (LTE_MBSFN_SubframeConfigList_t *) NULL
+                             (LTE_MeasObjectToAddMod_t **) NULL,
+                             ue_context_pP->ue_context.mac_MainConfig,
+                             DRB2LCHAN[i],
+                             DRB_configList->list.array[i]->logicalChannelConfig,
+                             ue_context_pP->ue_context.measGapConfig,
+                             (LTE_TDD_Config_t *) NULL,
+                             NULL,
+                             (LTE_SchedulingInfoList_t *) NULL,
+                             0, NULL, NULL, (LTE_MBSFN_SubframeConfigList_t *) NULL
 #if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0))
-            , 0, (LTE_MBSFN_AreaInfoList_r9_t *) NULL, (LTE_PMCH_InfoList_r9_t *) NULL
+                             , 0, (LTE_MBSFN_AreaInfoList_r9_t *) NULL, (LTE_PMCH_InfoList_r9_t *) NULL
 #endif
 #if (LTE_RRC_VERSION >= MAKE_VERSION(13, 0, 0))
-            ,
-            (LTE_SystemInformationBlockType1_v1310_IEs_t *)NULL
+                             ,
+                              (LTE_SystemInformationBlockType1_v1310_IEs_t *)NULL
 #endif
-          );
-        } else {        // remove LCHAN from MAC/PHY
-          if (ue_context_pP->ue_context.DRB_active[drb_id] == 1) {
+      );
+    }
+  } else {        // remove LCHAN from MAC/PHY
+
+        if (ue_context_pP->ue_context.DRB_active[drb_id] == 1) {
             // DRB has just been removed so remove RLC + PDCP for DRB
             /*      rrc_pdcp_config_req (ctxt_pP->module_id, frameP, 1, CONFIG_ACTION_REMOVE,
                (ue_mod_idP * NB_RB_MAX) + DRB2LCHAN[i],UNDEF_SECURITY_MODE);
              */
-            rrc_rlc_config_req(
-              ctxt_pP,
-              SRB_FLAG_NO,
-              MBMS_FLAG_NO,
-              CONFIG_ACTION_REMOVE,
-              DRB2LCHAN[i],
-              Rlc_info_um);
+          if (!NODE_IS_CU(RC.rrc[ctxt_pP->module_id]->node_type)) {
+            rrc_rlc_config_req(ctxt_pP,
+                               SRB_FLAG_NO,
+                               MBMS_FLAG_NO,
+                               CONFIG_ACTION_REMOVE,
+                               DRB2LCHAN[i],
+                               Rlc_info_um);
+          }
           }
 
           ue_context_pP->ue_context.DRB_active[drb_id] = 0;
           LOG_D(RRC,
                 PROTOCOL_RRC_CTXT_UE_FMT" RRC_eNB --- MAC_CONFIG_REQ  (DRB) ---> MAC_eNB\n",
                 PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP));
-          rrc_mac_config_req_eNB(ctxt_pP->module_id,
-                                 ue_context_pP->ue_context.primaryCC_id,
-                                 0,0,0,0,0,
+          if (NODE_IS_MONOLITHIC(RC.rrc[ctxt_pP->module_id]->node_type)) {
+            rrc_mac_config_req_eNB(ctxt_pP->module_id,
+                                   ue_context_pP->ue_context.primaryCC_id,
+                                   0,0,0,0,0,
 #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
-                                 0,
+                                   0,
 #endif
-                                 ue_context_pP->ue_context.rnti,
-                                 (LTE_BCCH_BCH_Message_t *) NULL,
-                                 (LTE_RadioResourceConfigCommonSIB_t *) NULL,
+                                   ue_context_pP->ue_context.rnti,
+                                   (LTE_BCCH_BCH_Message_t *) NULL,
+                                   (LTE_RadioResourceConfigCommonSIB_t *) NULL,
 #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
-                                 (LTE_RadioResourceConfigCommonSIB_t *) NULL,
+                                   (LTE_RadioResourceConfigCommonSIB_t *) NULL,
 #endif
-                                 ue_context_pP->ue_context.physicalConfigDedicated,
+                                   ue_context_pP->ue_context.physicalConfigDedicated,
 #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0))
-                                 (LTE_SCellToAddMod_r10_t *)NULL,
-                                 //(struct LTE_PhysicalConfigDedicatedSCell_r10 *)NULL,
+                                   (LTE_SCellToAddMod_r10_t *)NULL,
+                                   //(struct LTE_PhysicalConfigDedicatedSCell_r10 *)NULL,
 #endif
-                                 (LTE_MeasObjectToAddMod_t **) NULL,
-                                 ue_context_pP->ue_context.mac_MainConfig,
-                                 DRB2LCHAN[i],
-                                 (LTE_LogicalChannelConfig_t *) NULL,
-                                 (LTE_MeasGapConfig_t *) NULL,
-                                 (LTE_TDD_Config_t *) NULL,
-                                 NULL,
-                                 (LTE_SchedulingInfoList_t *) NULL,
-                                 0, NULL, NULL, NULL
+                                   (LTE_MeasObjectToAddMod_t **) NULL,
+                                   ue_context_pP->ue_context.mac_MainConfig,
+                                   DRB2LCHAN[i],
+                                   (LTE_LogicalChannelConfig_t *) NULL,
+                                   (LTE_MeasGapConfig_t *) NULL,
+                                   (LTE_TDD_Config_t *) NULL,
+                                   NULL,
+                                   (LTE_SchedulingInfoList_t *) NULL,
+                                   0, NULL, NULL, NULL
 #if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0))
-                                 , 0, (LTE_MBSFN_AreaInfoList_r9_t *) NULL, (LTE_PMCH_InfoList_r9_t *) NULL
+                                   , 0, (LTE_MBSFN_AreaInfoList_r9_t *) NULL, (LTE_PMCH_InfoList_r9_t *) NULL
 #endif
 #if (LTE_RRC_VERSION >= MAKE_VERSION(13, 0, 0))
-                                 ,
-                                 (LTE_SystemInformationBlockType1_v1310_IEs_t *)NULL
+                                   ,
+                                   (LTE_SystemInformationBlockType1_v1310_IEs_t *)NULL
 #endif
-                                );
+                                  );
+          }
         }
       }
     }
-
     free(DRB_configList);
     ue_context_pP->ue_context.DRB_configList2[xid] = NULL;
   }
@@ -5539,9 +5669,9 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete(
 
 //-----------------------------------------------------------------------------
 void rrc_eNB_generate_RRCConnectionSetup(const protocol_ctxt_t *const ctxt_pP,
-    rrc_eNB_ue_context_t          *const ue_context_pP,
-    const int                    CC_id
-                                        )
+					 rrc_eNB_ue_context_t          *const ue_context_pP,
+					 const int                    CC_id
+					 )
 //-----------------------------------------------------------------------------
 {
 #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
@@ -5551,120 +5681,165 @@ void rrc_eNB_generate_RRCConnectionSetup(const protocol_ctxt_t *const ctxt_pP,
   LTE_SRB_ToAddModList_t                **SRB_configList;
   LTE_SRB_ToAddMod_t                     *SRB1_config;
   int                                 cnt;
+  MessageDef                            *message_p;
+     
   T(T_ENB_RRC_CONNECTION_SETUP, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame),
     T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti));
-  SRB_configList = &ue_context_pP->ue_context.SRB_configList;
+
+  eNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context; 
+
+  SRB_configList = &ue_p->SRB_configList;
 #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
 
   if (is_mtc) {
-    RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.payload_size =
+    ue_p->Srb0.Tx_buffer.payload_size =
       do_RRCConnectionSetup_BR(ctxt_pP,
-                               ue_context_pP,
-                               CC_id,
-                               (uint8_t *) RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.Payload,
-                               (const uint8_t) RC.rrc[ctxt_pP->module_id]->carrier[CC_id].p_eNB, //at this point we do not have the UE capability information, so it can only be TM1 or TM2
-                               rrc_eNB_get_next_transaction_identifier(ctxt_pP->module_id),
-                               SRB_configList,
-                               &ue_context_pP->ue_context.physicalConfigDedicated);
+			       ue_context_pP,
+			       CC_id,
+			       (uint8_t *) ue_p->Srb0.Tx_buffer.Payload,
+			       (const uint8_t) RC.rrc[ctxt_pP->module_id]->carrier[CC_id].p_eNB, //at this point we do not have the UE capability information, so it can only be TM1 or TM2
+			       rrc_eNB_get_next_transaction_identifier(ctxt_pP->module_id),
+			       SRB_configList,
+			       &ue_context_pP->ue_context.physicalConfigDedicated);
   } else
 #endif
   {
-    RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.payload_size =
+    ue_p->Srb0.Tx_buffer.payload_size =
       do_RRCConnectionSetup(ctxt_pP,
-			    ue_context_pP,
-			    CC_id,
-			    (uint8_t *) RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.Payload,
-			    (uint8_t) RC.rrc[ctxt_pP->module_id]->carrier[CC_id].p_eNB, //at this point we do not have the UE capability information, so it can only be TM1 or TM2
-			    rrc_eNB_get_next_transaction_identifier(ctxt_pP->module_id),
-			    SRB_configList,
-			    &ue_context_pP->ue_context.physicalConfigDedicated);
-  }
-  LOG_DUMPMSG(RRC,DEBUG_RRC,
-	(char *)(RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.Payload),
-	RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.payload_size,
-	"[MSG] RRC Connection Setup\n");
-    
-    // configure SRB1/SRB2, PhysicalConfigDedicated, LTE_MAC_MainConfig for UE
-    
-  if (*SRB_configList != NULL) {
+                            ue_context_pP,
+                            CC_id,
+                            (uint8_t*) ue_p->Srb0.Tx_buffer.Payload,
+                            (uint8_t) RC.rrc[ctxt_pP->module_id]->carrier[CC_id].p_eNB, //at this point we do not have the UE capability information, so it can only be TM1 or TM2
+                            rrc_eNB_get_next_transaction_identifier(ctxt_pP->module_id),
+                            SRB_configList,
+                            &ue_context_pP->ue_context.physicalConfigDedicated);
+  }
+    LOG_DUMPMSG(RRC,DEBUG_RRC,
+                (char *)(ue_p->Srb0.Tx_buffer.Payload),
+                ue_p->Srb0.Tx_buffer.payload_size,
+                "[MSG] RRC Connection Setup\n");
+
+  // configure SRB1/SRB2, PhysicalConfigDedicated, MAC_MainConfig for UE
+   switch (RC.rrc[ctxt_pP->module_id]->node_type){
+    case ngran_eNB_CU    :
+    case ngran_ng_eNB_CU :
+    case ngran_gNB_CU    :
+      // create an ITTI message
+      /* TODO: F1 IDs ar missing in RRC */
+      message_p = itti_alloc_new_message (TASK_RRC_ENB, F1AP_DL_RRC_MESSAGE);
+      F1AP_DL_RRC_MESSAGE (message_p).rrc_container =  (uint8_t*)ue_p->Srb0.Tx_buffer.Payload;
+
+      F1AP_DL_RRC_MESSAGE (message_p).rrc_container_length = ue_p->Srb0.Tx_buffer.payload_size;
+      F1AP_DL_RRC_MESSAGE (message_p).gNB_CU_ue_id     = 0;  
+      F1AP_DL_RRC_MESSAGE (message_p).gNB_DU_ue_id = 0;
+      F1AP_DL_RRC_MESSAGE (message_p).old_gNB_DU_ue_id  = 0xFFFFFFFF; // unknown 
+      F1AP_DL_RRC_MESSAGE (message_p).rnti = ue_p->rnti; 
+      F1AP_DL_RRC_MESSAGE (message_p).srb_id = CCCH;  
+      F1AP_DL_RRC_MESSAGE (message_p).execute_duplication      = 1;
+      F1AP_DL_RRC_MESSAGE (message_p).RAT_frequency_priority_information.en_dc      = 0; 
+      itti_send_msg_to_task (TASK_CU_F1, ctxt_pP->module_id, message_p);
+      LOG_D(RRC, "Send F1AP_DL_RRC_MESSAGE with ITTI\n");
+      break;
+    case ngran_eNB_DU    :
+    case ngran_gNB_DU  :
+      // nothing to do for DU 
+      AssertFatal(1==0,"nothing to do for DU\n");
+      break;
+    case ngran_eNB:   
+    case ngran_ng_eNB :
+    case ngran_gNB  :  
+  
+    if (*SRB_configList != NULL) {
     for (cnt = 0; cnt < (*SRB_configList)->list.count; cnt++) {
       if ((*SRB_configList)->list.array[cnt]->srb_Identity == 1) {
-          SRB1_config = (*SRB_configList)->list.array[cnt];
-	  
-	  if (SRB1_config->logicalChannelConfig) {
-	    if (SRB1_config->logicalChannelConfig->present ==
-		LTE_SRB_ToAddMod__logicalChannelConfig_PR_explicitValue) {
-	      SRB1_logicalChannelConfig = &SRB1_config->logicalChannelConfig->choice.explicitValue;
-	    } else {
-	      SRB1_logicalChannelConfig = &SRB1_logicalChannelConfig_defaultValue;
-	    }
-	  } else {
-	    SRB1_logicalChannelConfig = &SRB1_logicalChannelConfig_defaultValue;
-	  }
-	  
-	  LOG_D(RRC,
-		PROTOCOL_RRC_CTXT_UE_FMT" RRC_eNB --- MAC_CONFIG_REQ  (SRB1) ---> MAC_eNB\n",
-		PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP));
-	  rrc_mac_config_req_eNB(
-				 ctxt_pP->module_id,
-				 ue_context_pP->ue_context.primaryCC_id,
-				 0,0,0,0,0,
+        SRB1_config = (*SRB_configList)->list.array[cnt];
+
+        if (SRB1_config->logicalChannelConfig) {
+          if (SRB1_config->logicalChannelConfig->present ==
+              LTE_SRB_ToAddMod__logicalChannelConfig_PR_explicitValue) {
+            SRB1_logicalChannelConfig = &SRB1_config->logicalChannelConfig->choice.explicitValue;
+          } else {
+            SRB1_logicalChannelConfig = &SRB1_logicalChannelConfig_defaultValue;
+          }
+        } else {
+          SRB1_logicalChannelConfig = &SRB1_logicalChannelConfig_defaultValue;
+        }
+
+        LOG_D(RRC,
+              PROTOCOL_RRC_CTXT_UE_FMT" RRC_eNB --- MAC_CONFIG_REQ  (SRB1) ---> MAC_eNB\n",
+              PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP));
+        if (RC.rrc[ctxt_pP->module_id]->node_type == ngran_eNB) {
+          rrc_mac_config_req_eNB(ctxt_pP->module_id,
+                                 ue_context_pP->ue_context.primaryCC_id,
+                                 0,0,0,0,0,
 #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
-            0,
+                                 0,
 #endif
-            ue_context_pP->ue_context.rnti,
-            (LTE_BCCH_BCH_Message_t *) NULL,
-            (LTE_RadioResourceConfigCommonSIB_t *) NULL,
+                                 ue_context_pP->ue_context.rnti,
+                                 (LTE_BCCH_BCH_Message_t *) NULL,
+                                 (LTE_RadioResourceConfigCommonSIB_t *) NULL,
 #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
-            (LTE_RadioResourceConfigCommonSIB_t *) NULL,
+                                 (LTE_RadioResourceConfigCommonSIB_t *) NULL,
 #endif
-            ue_context_pP->ue_context.physicalConfigDedicated,
+                                 ue_context_pP->ue_context.physicalConfigDedicated,
 #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0))
-            (LTE_SCellToAddMod_r10_t *)NULL,
-            //(struct LTE_PhysicalConfigDedicatedSCell_r10 *)NULL,
+                                 (LTE_SCellToAddMod_r10_t *)NULL,
+                                 //(struct LTE_PhysicalConfigDedicatedSCell_r10 *)NULL,
 #endif
-            (LTE_MeasObjectToAddMod_t **) NULL,
-            ue_context_pP->ue_context.mac_MainConfig,
-            1,
-            SRB1_logicalChannelConfig,
-            ue_context_pP->ue_context.measGapConfig,
-            (LTE_TDD_Config_t *) NULL,
-            NULL,
-            (LTE_SchedulingInfoList_t *) NULL,
-            0, NULL, NULL, (LTE_MBSFN_SubframeConfigList_t *) NULL
+                                 (LTE_MeasObjectToAddMod_t **) NULL,
+                                 ue_context_pP->ue_context.mac_MainConfig,
+                                 1,
+                                 SRB1_logicalChannelConfig,
+                                 ue_context_pP->ue_context.measGapConfig,
+                                 (LTE_TDD_Config_t *) NULL,
+                                 NULL,
+                                 (LTE_SchedulingInfoList_t *) NULL,
+                                 0, NULL, NULL, (LTE_MBSFN_SubframeConfigList_t *) NULL
 #if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0))
-            , 0, (LTE_MBSFN_AreaInfoList_r9_t *) NULL, (LTE_PMCH_InfoList_r9_t *) NULL
+                                 , 0, (LTE_MBSFN_AreaInfoList_r9_t *) NULL, (LTE_PMCH_InfoList_r9_t *) NULL
 #endif
 #if (LTE_RRC_VERSION >= MAKE_VERSION(13, 0, 0))
-            ,
-            (LTE_SystemInformationBlockType1_v1310_IEs_t *)NULL
+                                 ,
+                                 (LTE_SystemInformationBlockType1_v1310_IEs_t *)NULL
 #endif
           );
-          break;
         }
       }
-    
-    MSC_LOG_TX_MESSAGE(
-      MSC_RRC_ENB,
-      MSC_RRC_UE,
-      RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.Header, // LG WARNING
-      RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.payload_size,
-      MSC_AS_TIME_FMT" LTE_RRCConnectionSetup UE %x size %u",
-      MSC_AS_TIME_ARGS(ctxt_pP),
-      ue_context_pP->ue_context.rnti,
-      RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.payload_size);
-    LOG_I(RRC,
-          PROTOCOL_RRC_CTXT_UE_FMT" [RAPROC] Logical Channel DL-CCCH, Generating LTE_RRCConnectionSetup (bytes %d)\n",
-          PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),
-          RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.payload_size);
-    //ue_context_pP->ue_context.ue_release_timer_thres=100;
-    // activate release timer, if RRCSetupComplete not received after 100 frames, remove UE
-    ue_context_pP->ue_context.ue_release_timer=1;
-    // remove UE after 10 frames after LTE_RRCConnectionRelease is triggered
-    ue_context_pP->ue_context.ue_release_timer_thres=1000;
+    }
+
+  break;
+ default : 
+    LOG_W(RRC, "Unknown node type %d\n", RC.rrc[ctxt_pP->module_id]->node_type);		
+  }
+  
+  MSC_LOG_TX_MESSAGE(
+    MSC_RRC_ENB,
+    MSC_RRC_UE,
+    ue_p->Srb0.Tx_buffer.Header, // LG WARNING
+    ue_p->Srb0.Tx_buffer.payload_size,
+    MSC_AS_TIME_FMT" RRCConnectionSetup UE %x size %u",
+    MSC_AS_TIME_ARGS(ctxt_pP),
+    ue_context_pP->ue_context.rnti,
+    ue_p->Srb0.Tx_buffer.payload_size);
+
+
+  LOG_I(RRC,
+        PROTOCOL_RRC_CTXT_UE_FMT" [RAPROC] Logical Channel DL-CCCH, Generating RRCConnectionSetup (bytes %d)\n",
+        PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),
+        ue_p->Srb0.Tx_buffer.payload_size);
+
+  //ue_context_pP->ue_context.ue_release_timer_thres=100;
+     // activate release timer, if RRCSetupComplete not received after 100 frames, remove UE
+   ue_context_pP->ue_context.ue_release_timer=1;
+   // remove UE after 10 frames after RRCConnectionRelease is triggered
+   ue_context_pP->ue_context.ue_release_timer_thres=1000;
   }
 }
 
+void setup_ngran_CU(eNB_RRC_INST *rrc) {
+
+  
+}
 
 //-----------------------------------------------------------------------------
 char openair_rrc_eNB_configuration(
@@ -5692,9 +5867,8 @@ char openair_rrc_eNB_configuration(
   AssertFatal(configuration!=NULL,"configuration input is null\n");
   RC.rrc[ctxt.module_id]->Nb_ue = 0;
 
-  for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
-    RC.rrc[ctxt.module_id]->carrier[CC_id].Srb0.Active = 0;
-  }
+  pthread_mutex_init(&RC.rrc[ctxt.module_id]->cell_info_mutex,NULL);
+  RC.rrc[ctxt.module_id]->cell_info_configured = 0;
 
   uid_linear_allocator_init(&RC.rrc[ctxt.module_id]->uid_allocator);
   RB_INIT(&RC.rrc[ctxt.module_id]->rrc_ue_head);
@@ -5703,7 +5877,7 @@ char openair_rrc_eNB_configuration(
   //    }
   RC.rrc[ctxt.module_id]->initial_id2_s1ap_ids = hashtable_create (MAX_MOBILES_PER_ENB * 2, NULL, NULL);
   RC.rrc[ctxt.module_id]->s1ap_id2_s1ap_ids    = hashtable_create (MAX_MOBILES_PER_ENB * 2, NULL, NULL);
-  memcpy(&RC.rrc[ctxt.module_id]->configuration,configuration,sizeof(RrcConfigurationReq));
+
   /// System Information INIT
   LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" Checking release \n",
         PROTOCOL_RRC_CTXT_ARGS(&ctxt));
@@ -5745,10 +5919,7 @@ char openair_rrc_eNB_configuration(
 #endif
 
   for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
-    init_SI(&ctxt,
-            CC_id
-            , configuration
-           );
+    init_SI(&ctxt, CC_id, configuration);
 
     for (int ue_id = 0; ue_id < MAX_MOBILES_PER_ENB; ue_id++) {
       RC.rrc[ctxt.module_id]->carrier[CC_id].sizeof_paging[ue_id] = 0;
@@ -5789,15 +5960,31 @@ char openair_rrc_eNB_configuration(
 #endif
     openair_rrc_top_init_eNB(RC.rrc[ctxt.module_id]->carrier[CC_id].MBMS_flag,0);
   }
+	
   openair_rrc_on(&ctxt);
+
+/*
+  RC.rrc[ctxt.module_id]->mcc= rrc_configuration_req->mcc;
+  RC.rrc[ctxt.module_id]->mnc= rrc_configuration_req->mnc;
+  RC.rrc[ctxt.module_id]->mnc_digit_length= rrc_configuration_req->mnc_digit_length;
+  RC.rrc[ctxt.module_id]->tac= rrc_configuration_req->tac;
+
+  LOG_W(RRC, "[inst %d] RRC->MCC/MSG->MCC %d/%d \n", ctxt.module_id, RC.rrc[ctxt.module_id]->mcc, rrc_configuration_req->mcc);
+  */
+  if (NODE_IS_CU(RC.rrc[ctxt.module_id]->node_type))
+  	// msg_p = itti_alloc_new_message (TASK_ENB_APP, F1AP_SCTP_REQ);
+    // RCconfig_CU_F1(msg_p, enb_id);
+    setup_ngran_CU(RC.rrc[ctxt.module_id]);
+	
   return 0;
 }
 
 /*------------------------------------------------------------------------------*/
 int
 rrc_eNB_decode_ccch(
-  protocol_ctxt_t *const ctxt_pP,
-  const SRB_INFO        *const Srb_info,
+  protocol_ctxt_t* const ctxt_pP,
+  const uint8_t          *buffer,
+  int                    buffer_length,
   const int              CC_id
 )
 //-----------------------------------------------------------------------------
@@ -5816,17 +6003,17 @@ rrc_eNB_decode_ccch(
   //memset(ul_ccch_msg,0,sizeof(UL_CCCH_Message_t));
   LOG_I(RRC, PROTOCOL_RRC_CTXT_UE_FMT" Decoding UL CCCH %x.%x.%x.%x.%x.%x (%p)\n",
         PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),
-        ((uint8_t *) Srb_info->Rx_buffer.Payload)[0],
-        ((uint8_t *) Srb_info->Rx_buffer.Payload)[1],
-        ((uint8_t *) Srb_info->Rx_buffer.Payload)[2],
-        ((uint8_t *) Srb_info->Rx_buffer.Payload)[3],
-        ((uint8_t *) Srb_info->Rx_buffer.Payload)[4],
-        ((uint8_t *) Srb_info->Rx_buffer.Payload)[5], (uint8_t *) Srb_info->Rx_buffer.Payload);
+        ((uint8_t*) buffer)[0],
+        ((uint8_t *) buffer)[1],
+        ((uint8_t *) buffer)[2],
+        ((uint8_t *) buffer)[3],
+        ((uint8_t *) buffer)[4],
+        ((uint8_t *) buffer)[5], (uint8_t *) buffer);
   dec_rval = uper_decode(
                NULL,
                &asn_DEF_LTE_UL_CCCH_Message,
                (void **)&ul_ccch_msg,
-               (uint8_t *) Srb_info->Rx_buffer.Payload,
+               (uint8_t *) buffer,
                100,
                0,
                0);
@@ -5853,8 +6040,7 @@ rrc_eNB_decode_ccch(
       case LTE_UL_CCCH_MessageType__c1_PR_rrcConnectionReestablishmentRequest:
         T(T_ENB_RRC_CONNECTION_REESTABLISHMENT_REQUEST, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame),
           T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti));
-        LOG_DUMPMSG(RRC,DEBUG_RRC,(char *)(Srb_info->Rx_buffer.Payload),
-                    Srb_info->Rx_buffer.payload_size,
+        LOG_DUMPMSG(RRC,DEBUG_RRC,(char *)(buffer), buffer_length,
                     "[MSG] RRC Connection Reestablishment Request\n");
         LOG_D(RRC,
               PROTOCOL_RRC_CTXT_UE_FMT"MAC_eNB--- MAC_DATA_IND (rrcConnectionReestablishmentRequest on SRB0) --> RRC_eNB\n",
@@ -6025,13 +6211,15 @@ rrc_eNB_decode_ccch(
                                    NULL
                                    , (LTE_PMCH_InfoList_r9_t *) NULL
                                    ,NULL);
-          rrc_rlc_config_asn1_req(ctxt_pP,
-                                  ue_context_p->ue_context.SRB_configList,
-                                  (LTE_DRB_ToAddModList_t *) NULL,
-                                  (LTE_DRB_ToReleaseList_t *) NULL
-                                  , (LTE_PMCH_InfoList_r9_t *) NULL,
-                                  0,0
-                                 );
+          if (!NODE_IS_CU(RC.rrc[ctxt_pP->module_id]->node_type)) {
+            rrc_rlc_config_asn1_req(ctxt_pP,
+                                    ue_context_p->ue_context.SRB_configList,
+                                    (LTE_DRB_ToAddModList_t *) NULL,
+                                    (LTE_DRB_ToReleaseList_t *) NULL
+                                    , (LTE_PMCH_InfoList_r9_t *) NULL,
+                                    0,0
+                                   );
+        }
 #endif //NO_RRM
         }
         break;
@@ -6039,8 +6227,9 @@ rrc_eNB_decode_ccch(
       case LTE_UL_CCCH_MessageType__c1_PR_rrcConnectionRequest:
         T(T_ENB_RRC_CONNECTION_REQUEST, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame),
           T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti));
-        LOG_DUMPMSG(RRC,DEBUG_RRC,(char *)(Srb_info->Rx_buffer.Payload),
-                    Srb_info->Rx_buffer.payload_size,
+
+      LOG_DUMPMSG(RRC,DEBUG_RRC,(char *)buffer,
+                  buffer_length,
                     "[MSG] RRC Connection Request\n");
         LOG_D(RRC,
               PROTOCOL_RRC_CTXT_UE_FMT"MAC_eNB --- MAC_DATA_IND  (rrcConnectionRequest on SRB0) --> RRC_eNB\n",
@@ -6055,7 +6244,7 @@ rrc_eNB_decode_ccch(
           MSC_LOG_RX_DISCARDED_MESSAGE(
             MSC_RRC_ENB,
             MSC_RRC_UE,
-            Srb_info->Rx_buffer.Payload,
+            buffer,
             dec_rval.consumed,
             MSC_AS_TIME_FMT" LTE_RRCConnectionRequest UE %x size %u (UE already in context)",
             MSC_AS_TIME_ARGS(ctxt_pP),
@@ -6085,6 +6274,14 @@ rrc_eNB_decode_ccch(
               }
 
               ue_context_p = rrc_eNB_get_next_free_ue_context(ctxt_pP, random_value);
+
+              ue_context_p->ue_context.Srb0.Srb_id = 0;
+              ue_context_p->ue_context.Srb0.Active = 1;
+              memcpy(ue_context_p->ue_context.Srb0.Rx_buffer.Payload,
+                     buffer,
+                     buffer_length);
+              ue_context_p->ue_context.Srb0.Rx_buffer.payload_size = buffer_length;
+
             } else if (LTE_InitialUE_Identity_PR_s_TMSI == rrcConnectionRequest->ue_Identity.present) {
               /* Save s-TMSI */
               LTE_S_TMSI_t   s_TMSI = rrcConnectionRequest->ue_Identity.choice.s_TMSI;
@@ -6094,7 +6291,20 @@ rrc_eNB_decode_ccch(
 
               if ((ue_context_p = rrc_eNB_ue_context_stmsi_exist(ctxt_pP, mme_code, m_tmsi))) {
                 LOG_I(RRC," S-TMSI exists, ue_context_p %p, old rnti %x => %x\n",ue_context_p,ue_context_p->ue_context.rnti,ctxt_pP->rnti);
-                rrc_mac_remove_ue(ctxt_pP->module_id, ue_context_p->ue_context.rnti);
+
+                if (!NODE_IS_CU(RC.rrc[ctxt_pP->module_id]->node_type)) {
+                  rrc_mac_remove_ue(ctxt_pP->module_id, ue_context_p->ue_context.rnti);
+                }
+                else {
+                  MessageDef *m = itti_alloc_new_message(TASK_RRC_ENB, F1AP_UE_CONTEXT_RELEASE_CMD);
+                  F1AP_UE_CONTEXT_RELEASE_CMD(m).rnti = ctxt_pP->rnti;
+                  F1AP_UE_CONTEXT_RELEASE_CMD(m).cause = F1AP_CAUSE_RADIO_NETWORK;
+                  F1AP_UE_CONTEXT_RELEASE_CMD(m).cause_value = 10; // 10 = F1AP_CauseRadioNetwork_normal_release
+                  F1AP_UE_CONTEXT_RELEASE_CMD(m).rrc_container = NULL;
+                  F1AP_UE_CONTEXT_RELEASE_CMD(m).rrc_container_length = 0;
+                  itti_send_msg_to_task(TASK_CU_F1, ctxt_pP->module_id, m);
+                }
+
                 stmsi_received=1;
                 /* replace rnti in the context */
                 /* for that, remove the context from the RB tree */
@@ -6131,7 +6341,7 @@ rrc_eNB_decode_ccch(
               MSC_LOG_RX_MESSAGE(
                 MSC_RRC_ENB,
                 MSC_RRC_UE,
-                Srb_info->Rx_buffer.Payload,
+                buffer,
                 dec_rval.consumed,
                 MSC_AS_TIME_FMT" RRCConnectionRequest UE %x size %u (s-TMSI mmec %u m_TMSI %u random UE id (0x%" PRIx64 ")",
                 MSC_AS_TIME_ARGS(ctxt_pP),
@@ -6177,8 +6387,8 @@ rrc_eNB_decode_ccch(
               RC.rrc[ctxt_pP->module_id]->Nb_ue++;
           } else {
             // no context available
-            if (rrc_agent_registered[ctxt_pP->module_id]) {
-              agent_rrc_xface[ctxt_pP->module_id]->flexran_agent_notify_ue_state_change(ctxt_pP->module_id,
+            if (flexran_agent_get_rrc_xface(ctxt_pP->module_id)) {
+              flexran_agent_get_rrc_xface(ctxt_pP->module_id)->flexran_agent_notify_ue_state_change(ctxt_pP->module_id,
                   ctxt_pP->rnti,
                   PROTOCOL__FLEX_UE_STATE_CHANGE_TYPE__FLUESC_DEACTIVATED);
             }
@@ -6186,7 +6396,17 @@ rrc_eNB_decode_ccch(
             LOG_I(RRC, PROTOCOL_RRC_CTXT_UE_FMT" Can't create new context for UE random UE identity (0x%" PRIx64 ")\n",
                   PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),
                   random_value);
-            rrc_mac_remove_ue(ctxt_pP->module_id,ctxt_pP->rnti);
+            if (NODE_IS_MONOLITHIC(RC.rrc[ctxt_pP->module_id]->node_type))
+              rrc_mac_remove_ue(ctxt_pP->module_id,ctxt_pP->rnti);
+            else if (NODE_IS_CU(RC.rrc[ctxt_pP->module_id]->node_type)) {
+              MessageDef *m = itti_alloc_new_message(TASK_RRC_ENB, F1AP_UE_CONTEXT_RELEASE_CMD);
+              F1AP_UE_CONTEXT_RELEASE_CMD(m).rnti = ctxt_pP->rnti;
+              F1AP_UE_CONTEXT_RELEASE_CMD(m).cause = F1AP_CAUSE_RADIO_NETWORK;
+              F1AP_UE_CONTEXT_RELEASE_CMD(m).cause_value = 10; // 10 = F1AP_CauseRadioNetwork_normal_release
+              F1AP_UE_CONTEXT_RELEASE_CMD(m).rrc_container = NULL;
+              F1AP_UE_CONTEXT_RELEASE_CMD(m).rrc_container_length = 0;
+              itti_send_msg_to_task(TASK_CU_F1, ctxt_pP->module_id, m);
+            }
             return -1;
           }
         }
@@ -6239,15 +6459,18 @@ rrc_eNB_decode_ccch(
                                  , (LTE_PMCH_InfoList_r9_t *) NULL
 #endif
                                  ,NULL);
-        rrc_rlc_config_asn1_req(ctxt_pP,
-                                ue_context_p->ue_context.SRB_configList,
-                                (LTE_DRB_ToAddModList_t *) NULL,
-                                (LTE_DRB_ToReleaseList_t *) NULL
+
+        if (!NODE_IS_CU(RC.rrc[ctxt_pP->module_id]->node_type)) {
+          rrc_rlc_config_asn1_req(ctxt_pP,
+                                  ue_context_p->ue_context.SRB_configList,
+                                  (LTE_DRB_ToAddModList_t *) NULL,
+                                  (LTE_DRB_ToReleaseList_t *) NULL
 #if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0))
-                                , (LTE_PMCH_InfoList_r9_t *) NULL
-                                , 0, 0
+                                  , (LTE_PMCH_InfoList_r9_t *) NULL
+                                  , 0, 0
 #endif
-                               );
+                                 );
+        }
 #endif //NO_RRM
         break;
 
@@ -6405,6 +6628,9 @@ rrc_eNB_decode_dcch(
                 break;
               }
 
+              AssertFatal(!NODE_IS_CU(RC.rrc[ctxt_pP->module_id]->node_type),
+                          "CU cannot decode DCCH: no access to RC.mac[]\n");
+
               if(RC.mac[ctxt_pP->module_id]->UE_list.UE_sched_ctrl[UE_id].crnti_reconfigurationcomplete_flag == 1) {
                 LOG_I(RRC,
                       PROTOCOL_RRC_CTXT_UE_FMT" UE State = RRC_RECONFIGURED (dedicated DRB, xid %ld) C-RNTI Complete\n",
@@ -6451,8 +6677,8 @@ rrc_eNB_decode_dcch(
             ul_dcch_msg->message.choice.c1.choice.rrcConnectionReconfigurationComplete.rrc_TransactionIdentifier);
 
           //WARNING:Inform the controller about the UE activation. Should be moved to RRC agent in the future
-          if (rrc_agent_registered[ctxt_pP->module_id]) {
-            agent_rrc_xface[ctxt_pP->module_id]->flexran_agent_notify_ue_state_change(ctxt_pP->module_id,
+          if (flexran_agent_get_rrc_xface(ctxt_pP->module_id)) {
+            flexran_agent_get_rrc_xface(ctxt_pP->module_id)->flexran_agent_notify_ue_state_change(ctxt_pP->module_id,
                 ue_context_p->ue_id_rnti,
                 PROTOCOL__FLEX_UE_STATE_CHANGE_TYPE__FLUESC_UPDATED);
           }
@@ -6607,8 +6833,8 @@ rrc_eNB_decode_dcch(
                 &ul_dcch_msg->message.choice.c1.choice.rrcConnectionReestablishmentComplete.criticalExtensions.choice.rrcConnectionReestablishmentComplete_r8);
 
             //WARNING:Inform the controller about the UE activation. Should be moved to RRC agent in the future
-            if (mac_agent_registered[ctxt_pP->module_id]) {
-              agent_rrc_xface[ctxt_pP->module_id]->flexran_agent_notify_ue_state_change(ctxt_pP->module_id,
+            if (flexran_agent_get_rrc_xface(ctxt_pP->module_id)) {
+              flexran_agent_get_rrc_xface(ctxt_pP->module_id)->flexran_agent_notify_ue_state_change(ctxt_pP->module_id,
                   ue_context_p->ue_id_rnti,
                   PROTOCOL__FLEX_UE_STATE_CHANGE_TYPE__FLUESC_ACTIVATED);
             }
@@ -6652,6 +6878,8 @@ rrc_eNB_decode_dcch(
           if (ul_dcch_msg->message.choice.c1.choice.rrcConnectionSetupComplete.criticalExtensions.choice.c1.
               present ==
               LTE_RRCConnectionSetupComplete__criticalExtensions__c1_PR_rrcConnectionSetupComplete_r8) {
+            AssertFatal(!NODE_IS_DU(RC.rrc[ctxt_pP->module_id]->node_type),
+                        "should not be reached in DU\n");
             rrc_eNB_process_RRCConnectionSetupComplete(
               ctxt_pP,
               ue_context_p,
@@ -6660,8 +6888,8 @@ rrc_eNB_decode_dcch(
                   PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP));
 
             //WARNING:Inform the controller about the UE activation. Should be moved to RRC agent in the future
-            if (rrc_agent_registered[ctxt_pP->module_id]) {
-              agent_rrc_xface[ctxt_pP->module_id]->flexran_agent_notify_ue_state_change(ctxt_pP->module_id,
+            if (flexran_agent_get_rrc_xface(ctxt_pP->module_id)) {
+              flexran_agent_get_rrc_xface(ctxt_pP->module_id)->flexran_agent_notify_ue_state_change(ctxt_pP->module_id,
                   ue_context_p->ue_id_rnti,
                   PROTOCOL__FLEX_UE_STATE_CHANGE_TYPE__FLUESC_ACTIVATED);
             }
@@ -6818,9 +7046,9 @@ rrc_eNB_decode_dcch(
         }
 
         if (EPC_MODE_ENABLED) {
-          rrc_eNB_send_S1AP_UE_CAPABILITIES_IND(ctxt_pP,
-                                                ue_context_p,
-                                                ul_dcch_msg);
+            rrc_eNB_send_S1AP_UE_CAPABILITIES_IND(ctxt_pP,
+                                                  ue_context_p,
+                                                  ul_dcch_msg);
         } else {
           ue_context_p->ue_context.nb_of_e_rabs = 1;
 
@@ -6920,7 +7148,7 @@ rrc_eNB_decode_dcch(
     return 0;
     //TTN for D2D
   } else if (ul_dcch_msg->message.present == LTE_UL_DCCH_MessageType_PR_messageClassExtension) {
-    LOG_I(RRC, "THINH [UL_DCCH_MessageType_PR_messageClassExtension]\n");
+    LOG_I(RRC, "THINH [LTE_UL_DCCH_MessageType_PR_messageClassExtension]\n");
 
     switch (ul_dcch_msg->message.choice.messageClassExtension.present) {
       case LTE_UL_DCCH_MessageType__messageClassExtension_PR_NOTHING: /* No components present */
@@ -6928,7 +7156,7 @@ rrc_eNB_decode_dcch(
 
       case LTE_UL_DCCH_MessageType__messageClassExtension_PR_c2: //SidelinkUEInformation
         //case UL_DCCH_MessageType__messageClassExtension__c2_PR_sidelinkUEInformation_r12: //SidelinkUEInformation
-        LOG_I(RRC,"THINH [UL_DCCH_MessageType__messageClassExtension_PR_c2]\n");
+        LOG_I(RRC,"THINH [LTE_UL_DCCH_MessageType__messageClassExtension_PR_c2]\n");
         LOG_DUMPMSG(RRC,DEBUG_RRC,(char *)Rx_sdu,sdu_sizeP,
                     "[MSG] RRC SidelinkUEInformation \n");
         MSC_LOG_RX_MESSAGE(
@@ -6998,6 +7226,120 @@ void rrc_eNB_reconfigure_DRBs (const protocol_ctxt_t *const ctxt_pP,
   rrc_eNB_generate_dedicatedRRCConnectionReconfiguration(ctxt_pP, ue_context_pP, 0);
 }
 
+void handle_f1_setup_req(f1ap_setup_req_t *f1_setup_req) { 
+
+  
+  LOG_I(RRC,"Received F1 Setup Request from gNB_DU %llu (%s)\n",(unsigned long long int)f1_setup_req->gNB_DU_id,f1_setup_req->gNB_DU_name);
+  
+  //uint16_t num_cells_to_activate = 0;
+  
+  int cu_cell_ind=0;
+
+  MessageDef                         *msg_p = NULL;
+
+  //LOG_W(RRC,"num_cells_available %d \n", f1_setup_req->num_cells_available);
+  for (int i=0;i<f1_setup_req->num_cells_available;i++) {
+    // check that mcc/mnc match and grab MIB/SIB1
+    int found_cell=0;
+    for (int j=0;j<RC.nb_inst;j++) {
+      eNB_RRC_INST *rrc = RC.rrc[j];
+      if (rrc->configuration.mcc[0] == f1_setup_req->mcc[i] &&
+	  rrc->configuration.mnc[0] == f1_setup_req->mnc[i] &&
+	  rrc->nr_cellid == f1_setup_req->nr_cellid[i]) {
+        // check that CU rrc instance corresponds to mcc/mnc/cgi (normally cgi should be enough, but just in case)
+
+        rrc->carrier[0].MIB = malloc(f1_setup_req->mib_length[i]);
+        rrc->carrier[0].sizeof_MIB = f1_setup_req->mib_length[i];
+        LOG_W(RRC, "instance %d mib length %d\n", i, f1_setup_req->mib_length[i]);
+        LOG_W(RRC, "instance %d sib1 length %d\n", i, f1_setup_req->sib1_length[i]);
+       
+        memcpy((void*)rrc->carrier[0].MIB,f1_setup_req->mib[i],f1_setup_req->mib_length[i]);
+        asn_dec_rval_t dec_rval = uper_decode_complete(NULL,
+                         &asn_DEF_LTE_BCCH_BCH_Message,
+        					       (void **)&rrc->carrier[0].mib_DU,
+        					       f1_setup_req->mib[i],
+        					       f1_setup_req->mib_length[i]);
+        AssertFatal(dec_rval.code == RC_OK,
+              "[eNB_DU %"PRIu8"] Failed to decode LTE_BCCH_BCH_MESSAGE (%zu bits)\n",
+        	    j,
+        	    dec_rval.consumed );	
+        LTE_BCCH_BCH_Message_t *mib = &rrc->carrier[0].mib;
+        LTE_BCCH_BCH_Message_t *mib_DU = rrc->carrier[0].mib_DU;
+        mib->message.dl_Bandwidth = mib_DU->message.dl_Bandwidth;
+        mib->message.phich_Config.phich_Resource = mib_DU->message.phich_Config.phich_Resource;
+        mib->message.phich_Config.phich_Duration = mib_DU->message.phich_Config.phich_Duration;
+
+        rrc->carrier[0].SIB1 = malloc(f1_setup_req->sib1_length[i]);
+        rrc->carrier[0].sizeof_SIB1 = f1_setup_req->sib1_length[i];
+        memcpy((void*)rrc->carrier[0].SIB1,f1_setup_req->sib1[i],f1_setup_req->sib1_length[i]); 
+        dec_rval = uper_decode_complete(NULL,
+                &asn_DEF_LTE_BCCH_DL_SCH_Message,
+        				(void **)&rrc->carrier[0].siblock1_DU,
+        				f1_setup_req->sib1[i],
+        				f1_setup_req->sib1_length[i]);
+        AssertFatal(dec_rval.code == RC_OK,
+              "[eNB_DU %"PRIu8"] Failed to decode LTE_BCCH_DLSCH_MESSAGE (%zu bits)\n",
+        	    j,
+        	    dec_rval.consumed );	
+        // Parse message and extract SystemInformationBlockType1 field
+        LTE_BCCH_DL_SCH_Message_t *bcch_message = rrc->carrier[0].siblock1_DU;
+        AssertFatal(bcch_message->message.present == LTE_BCCH_DL_SCH_MessageType_PR_c1,
+              "bcch_message->message.present != LTE_BCCH_DL_SCH_MessageType_PR_c1\n");
+        AssertFatal(bcch_message->message.choice.c1.present == LTE_BCCH_DL_SCH_MessageType__c1_PR_systemInformationBlockType1,
+              "bcch_message->message.choice.c1.present != LTE_BCCH_DL_SCH_MessageType__c1_PR_systemInformationBlockType1\n");
+        rrc->carrier[0].sib1 = &bcch_message->message.choice.c1.choice.systemInformationBlockType1;
+        rrc->carrier[0].physCellId = f1_setup_req->nr_pci[i];
+        // prepare F1_SETUP_RESPONSE
+
+        if (msg_p == NULL) {
+          msg_p = itti_alloc_new_message (TASK_CU_F1,F1AP_SETUP_RESP); 						 
+        }
+        F1AP_SETUP_RESP (msg_p).gNB_CU_name                                = rrc->node_name;
+        F1AP_SETUP_RESP (msg_p).mcc[cu_cell_ind]                           = rrc->configuration.mcc[0];
+        F1AP_SETUP_RESP (msg_p).mnc[cu_cell_ind]                           = rrc->configuration.mnc[0];
+        F1AP_SETUP_RESP (msg_p).mnc_digit_length[cu_cell_ind]              = rrc->configuration.mnc_digit_length[0];
+	F1AP_SETUP_RESP (msg_p).nr_cellid[cu_cell_ind]                     = rrc->nr_cellid;
+        F1AP_SETUP_RESP (msg_p).nrpci[cu_cell_ind]                         = f1_setup_req->nr_pci[i];
+        int num_SI= 0;
+        if (rrc->carrier[0].SIB23) {
+          F1AP_SETUP_RESP (msg_p).SI_container[cu_cell_ind][num_SI]        = rrc->carrier[0].SIB23;
+          F1AP_SETUP_RESP (msg_p).SI_container_length[cu_cell_ind][num_SI] = rrc->carrier[0].sizeof_SIB23;
+          //printf("SI %d size %d: ", 0, F1AP_SETUP_RESP(msg_p).SI_container_length[j][num_SI]);
+          //for (int n = 0; n < F1AP_SETUP_RESP(msg_p).SI_container_length[j][num_SI]; n++)
+          //  printf("%02x ", F1AP_SETUP_RESP(msg_p).SI_container[0][num_SI][n]);
+          //printf("\n");
+          num_SI++;
+        }
+        F1AP_SETUP_RESP (msg_p).num_SI[cu_cell_ind] = num_SI;
+
+        cu_cell_ind++;
+        found_cell=1;
+
+        F1AP_SETUP_RESP (msg_p).num_cells_to_activate = cu_cell_ind;
+        // send ITTI message to F1AP-CU task
+        itti_send_msg_to_task (TASK_CU_F1, ENB_MODULE_ID_TO_INSTANCE(j), msg_p);
+        break;
+      } else {// setup_req mcc/mnc match rrc internal list element
+        
+        LOG_W(RRC,"[Inst %d] No matching MCC/MNC: rrc->mcc/f1_setup_req->mcc %d/%d rrc->mnc/f1_setup_req->mnc %d/%d \n", 
+            j, rrc->configuration.mcc[0], f1_setup_req->mcc[i],rrc->configuration.mnc[0], f1_setup_req->mnc[i]);
+
+      }
+    }// for (int j=0;j<RC.nb_inst;j++)
+    if (found_cell==0) {
+      AssertFatal(1==0,"No cell found\n");
+      /*msg_p = itti_alloc_new_message (TASK_CU_F1,F1AP_SETUP_FAILURE); 						 
+      F1AP_SETUP_RESP (msg_p).cause                             = rrc->node_name;
+      F1AP_SETUP_RESP (msg_p).time_to_wait                      = rrc->node_id;
+      F1AP_SETUP_RESP (msg_p).criticality_diagnostics           = rrc->node_name;*/
+    }
+    // handle other failure cases
+  }//for (int i=0;i<f1_setup_req->num_cells_available;i++)
+}
+ 
+
+  // ignore 5GNR fields for now, just take MIB and SIB1
+//-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
 void rrc_enb_init(void) {
   pthread_mutex_init(&lock_ue_freelist, NULL);
@@ -7015,7 +7357,7 @@ void rrc_subframe_process(protocol_ctxt_t *const ctxt_pP, const int CC_id)
   struct rrc_eNB_ue_context_s *ue_to_be_removed = NULL;
 #ifdef LOCALIZATION
   double estimated_distance = 0;
-  protocol_ctxt_t ctxt;
+  protocol_ctxt_t                     ctxt;
 #endif
   MessageDef *msg;
 
@@ -7026,7 +7368,7 @@ void rrc_subframe_process(protocol_ctxt_t *const ctxt_pP, const int CC_id)
     msg = itti_alloc_new_message(TASK_RRC_ENB, X2AP_SUBFRAME_PROCESS);
     itti_send_msg_to_task(TASK_X2AP, ctxt_pP->module_id, msg);
 
-    check_handovers(ctxt_pP); // counter, get the value and aggregate
+  check_handovers(ctxt_pP); // counter, get the value and aggregate
   }
 
   // check for UL failure or for UE to be released
@@ -7066,7 +7408,7 @@ void rrc_subframe_process(protocol_ctxt_t *const ctxt_pP, const int CC_id)
               ue_context_p->ue_context.rnti,
               ue_context_p->ue_context.ue_release_timer_thres_s1);
 
-        if (EPC_MODE_ENABLED)
+        if (EPC_MODE_ENABLED && !NODE_IS_DU(RC.rrc[ctxt_pP->module_id]->node_type))
           rrc_eNB_generate_RRCConnectionRelease(ctxt_pP, ue_context_p);
         else
           ue_to_be_removed = ue_context_p;
@@ -7119,44 +7461,30 @@ void rrc_subframe_process(protocol_ctxt_t *const ctxt_pP, const int CC_id)
           ue_context_p->ue_context.ue_release_timer_rrc = 1;
           ue_context_p->ue_context.ue_release_timer_thres_rrc = 100;
 
-          if (EPC_MODE_ENABLED) {
-            int e_rab = 0;
-            MessageDef *msg_complete_p = NULL;
-            MessageDef *msg_delete_tunnels_p = NULL;
-            uint32_t eNB_ue_s1ap_id = ue_context_p->ue_context.eNB_ue_s1ap_id;
-
+          if (EPC_MODE_ENABLED && !NODE_IS_DU(RC.rrc[ctxt_pP->module_id]->node_type)) {
             if (rrc_release_info.RRC_release_ctrl[release_num].flag == 4) { // if timer_s1 == 0
-              MSC_LOG_TX_MESSAGE(MSC_RRC_ENB, MSC_S1AP_ENB, NULL, 0,
-                                 "0 S1AP_UE_CONTEXT_RELEASE_COMPLETE eNB_ue_s1ap_id 0x%06"PRIX32" ",
-                                 eNB_ue_s1ap_id);
-              msg_complete_p = itti_alloc_new_message(TASK_RRC_ENB, S1AP_UE_CONTEXT_RELEASE_COMPLETE);
-              S1AP_UE_CONTEXT_RELEASE_COMPLETE(msg_complete_p).eNB_ue_s1ap_id = eNB_ue_s1ap_id;
-              itti_send_msg_to_task(TASK_S1AP, ctxt_pP->module_id, msg_complete_p);
+              rrc_eNB_send_S1AP_UE_CONTEXT_RELEASE_CPLT(ctxt_pP->module_id,
+                  ue_context_p->ue_context.eNB_ue_s1ap_id);
             }
 
-            MSC_LOG_TX_MESSAGE(MSC_RRC_ENB, MSC_GTPU_ENB, NULL,0, "0 GTPV1U_ENB_DELETE_TUNNEL_REQ rnti %x ", eNB_ue_s1ap_id);
-            msg_delete_tunnels_p = itti_alloc_new_message(TASK_RRC_ENB, GTPV1U_ENB_DELETE_TUNNEL_REQ);
-            memset(&GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p), 0, sizeof(GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p)));
-            // do not wait response
-            GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).rnti = ue_context_p->ue_context.rnti;
-
-            for (e_rab = 0; e_rab < ue_context_p->ue_context.nb_of_e_rabs; e_rab++) {
-              GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).eps_bearer_id[GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).num_erab++] =
-                ue_context_p->ue_context.enb_gtp_ebi[e_rab];
-              // erase data
+            rrc_eNB_send_GTPV1U_ENB_DELETE_TUNNEL_REQ(ctxt_pP->module_id,
+                  ue_context_p);
+            // erase data of GTP tunnels in UE context
+            for (int e_rab = 0; e_rab < ue_context_p->ue_context.nb_of_e_rabs; e_rab++) {
               ue_context_p->ue_context.enb_gtp_teid[e_rab] = 0;
-              memset(&ue_context_p->ue_context.enb_gtp_addrs[e_rab], 0, sizeof(ue_context_p->ue_context.enb_gtp_addrs[e_rab]));
-              ue_context_p->ue_context.enb_gtp_ebi[e_rab] = 0;
+              memset(&ue_context_p->ue_context.enb_gtp_addrs[e_rab],
+                  0, sizeof(ue_context_p->ue_context.enb_gtp_addrs[e_rab]));
+              ue_context_p->ue_context.enb_gtp_ebi[e_rab]  = 0;
             }
 
-            itti_send_msg_to_task(TASK_GTPV1_U, ctxt_pP->module_id, msg_delete_tunnels_p);
             struct rrc_ue_s1ap_ids_s *rrc_ue_s1ap_ids = NULL;
-            rrc_ue_s1ap_ids = rrc_eNB_S1AP_get_ue_ids(RC.rrc[ctxt_pP->module_id], 0, eNB_ue_s1ap_id);
+            rrc_ue_s1ap_ids = rrc_eNB_S1AP_get_ue_ids(RC.rrc[ctxt_pP->module_id], 0,
+                                                      ue_context_p->ue_context.eNB_ue_s1ap_id);
 
             if (rrc_ue_s1ap_ids != NULL) {
               rrc_eNB_S1AP_remove_ue_ids(RC.rrc[ctxt_pP->module_id], rrc_ue_s1ap_ids);
             }
-          } /* EPC_MODE_ENABLED */
+          } /* EPC_MODE_ENABLED && !NODE_IS_DU */
 
           rrc_release_info.RRC_release_ctrl[release_num].flag = 0;
           rrc_release_info.num_UEs--;
@@ -7272,8 +7600,6 @@ void *rrc_enb_process_itti_msg(void *notUsed) {
   const char                         *msg_name_p;
   instance_t                          instance;
   int                                 result;
-  SRB_INFO                           *srb_info_p;
-  int                                 CC_id;
   protocol_ctxt_t                     ctxt;
 
   memset(&ctxt, 0, sizeof(ctxt));
@@ -7299,31 +7625,31 @@ void *rrc_enb_process_itti_msg(void *notUsed) {
     /* Messages from MAC */
     case RRC_MAC_CCCH_DATA_IND:
       PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt,
-                                    instance,
+                                    RRC_MAC_CCCH_DATA_IND(msg_p).enb_index,
                                     ENB_FLAG_YES,
                                     RRC_MAC_CCCH_DATA_IND(msg_p).rnti,
                                     msg_p->ittiMsgHeader.lte_time.frame,
                                     msg_p->ittiMsgHeader.lte_time.slot);
-      LOG_I(RRC, PROTOCOL_RRC_CTXT_UE_FMT" Received %s\n",
-            PROTOCOL_RRC_CTXT_UE_ARGS(&ctxt),
-            msg_name_p);
-      CC_id = RRC_MAC_CCCH_DATA_IND(msg_p).CC_id;
-      srb_info_p = &RC.rrc[instance]->carrier[CC_id].Srb0;
+
       LOG_I(RRC,"Decoding CCCH : inst %d, CC_id %d, ctxt %p, sib_info_p->Rx_buffer.payload_size %d\n",
-            instance,CC_id,&ctxt, RRC_MAC_CCCH_DATA_IND(msg_p).sdu_size);
+            instance,
+            RRC_MAC_CCCH_DATA_IND(msg_p).CC_id,
+            &ctxt,
+            RRC_MAC_CCCH_DATA_IND(msg_p).sdu_size);
 
       if (RRC_MAC_CCCH_DATA_IND(msg_p).sdu_size >= RRC_BUFFER_SIZE_MAX) {
-        LOG_I(RRC, "CCCH message has size %d > %d\n",RRC_MAC_CCCH_DATA_IND(msg_p).sdu_size,RRC_BUFFER_SIZE_MAX);
+        LOG_I(RRC, "CCCH message has size %d > %d\n",
+              RRC_MAC_CCCH_DATA_IND(msg_p).sdu_size,RRC_BUFFER_SIZE_MAX);
         break;
       }
 
-      memcpy(srb_info_p->Rx_buffer.Payload,
-             RRC_MAC_CCCH_DATA_IND(msg_p).sdu,
-             RRC_MAC_CCCH_DATA_IND(msg_p).sdu_size);
-      srb_info_p->Rx_buffer.payload_size = RRC_MAC_CCCH_DATA_IND(msg_p).sdu_size;
-      rrc_eNB_decode_ccch(&ctxt, srb_info_p, CC_id);
+      rrc_eNB_decode_ccch(&ctxt,
+                          (uint8_t*)RRC_MAC_CCCH_DATA_IND(msg_p).sdu,
+                          RRC_MAC_CCCH_DATA_IND(msg_p).sdu_size,
+                          RRC_MAC_CCCH_DATA_IND(msg_p).CC_id);
       break;
 
+
     /* Messages from PDCP */
     case RRC_DCCH_DATA_IND:
       PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt,
@@ -7491,10 +7817,18 @@ void *rrc_enb_process_itti_msg(void *notUsed) {
 
     /* Messages from eNB app */
     case RRC_CONFIGURATION_REQ:
-      LOG_I(RRC, "[eNB %d] Received %s : %p\n", instance, msg_name_p,&RRC_CONFIGURATION_REQ(msg_p));
+      LOG_I(RRC, "[eNB %d] Received %s : %p\n", instance, msg_name_p, &RRC_CONFIGURATION_REQ(msg_p));
       openair_rrc_eNB_configuration(ENB_INSTANCE_TO_MODULE_ID(instance), &RRC_CONFIGURATION_REQ(msg_p));
       break;
 
+    /* Messages from F1AP task */
+    case F1AP_SETUP_REQ:
+      AssertFatal(NODE_IS_CU(RC.rrc[instance]->node_type),
+		  "should not receive F1AP_SETUP_REQUEST, need call by CU!\n");
+      LOG_I(RRC,"[eNB %d] Received %s : %p\n", instance, msg_name_p, &F1AP_SETUP_REQ(msg_p));
+      handle_f1_setup_req(&F1AP_SETUP_REQ(msg_p));
+      break;
+
     case RRC_SUBFRAME_PROCESS:
       rrc_subframe_process(&RRC_SUBFRAME_PROCESS(msg_p).ctxt, RRC_SUBFRAME_PROCESS(msg_p).CC_id);
       break;
@@ -7881,4 +8215,3 @@ rrc_rx_tx(
   itti_send_msg_to_task(TASK_RRC_ENB, ctxt_pP->module_id, message_p);
   return RRC_OK;
 }
-
diff --git a/openair2/RRC/LTE/rrc_eNB_GTPV1U.c b/openair2/RRC/LTE/rrc_eNB_GTPV1U.c
index c8b18bb7d1848a2d96fd175f86e9a8f26238c8b6..ff8f455d6cb5d1c88e6b884984e6db5b46563e3d 100644
--- a/openair2/RRC/LTE/rrc_eNB_GTPV1U.c
+++ b/openair2/RRC/LTE/rrc_eNB_GTPV1U.c
@@ -33,8 +33,8 @@
 # include "rrc_eNB_GTPV1U.h"
 # include "rrc_eNB_UE_context.h"
 # include "msc.h"
-# include "asn1_conversions.h"
-# include "intertask_interface.h"
+#   include "asn1_conversions.h"
+#   include "intertask_interface.h"
 # include "common/ran_context.h"
 
 extern RAN_CONTEXT_t RC;
@@ -65,26 +65,50 @@ rrc_eNB_process_GTPV1U_CREATE_TUNNEL_RESP(
       LOG_I(RRC, PROTOCOL_RRC_CTXT_UE_FMT" rrc_eNB_process_GTPV1U_CREATE_TUNNEL_RESP tunnel (%u, %u) bearer UE context index %u, msg index %u, id %u, gtp addr len %d \n",
             PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),
             create_tunnel_resp_pP->enb_S1u_teid[i],
-            ue_context_p->ue_context.enb_gtp_teid[inde_list[i]],
+            ue_context_p->ue_context.enb_gtp_teid[inde_list[i]],            
             inde_list[i],
-            i,
+	    i,
             create_tunnel_resp_pP->eps_bearer_id[i],
-            create_tunnel_resp_pP->enb_addr.length);
+	    create_tunnel_resp_pP->enb_addr.length);
     }
 
-    MSC_LOG_RX_MESSAGE(
-      MSC_RRC_ENB,
-      MSC_GTPU_ENB,
-      NULL,0,
-      MSC_AS_TIME_FMT" CREATE_TUNNEL_RESP RNTI %"PRIx16" ntuns %u ebid %u enb-s1u teid %u",
-      0,0,rnti,
-      create_tunnel_resp_pP->num_tunnels,
-      ue_context_p->ue_context.enb_gtp_ebi[0],
-      ue_context_p->ue_context.enb_gtp_teid[0]);
-    (void)rnti; /* avoid gcc warning "set but not used" */
+	MSC_LOG_RX_MESSAGE(
+			  MSC_RRC_ENB,
+			  MSC_GTPU_ENB,
+			  NULL,0,
+			  MSC_AS_TIME_FMT" CREATE_TUNNEL_RESP RNTI %"PRIx16" ntuns %u ebid %u enb-s1u teid %u",
+			  0,0,rnti,
+			  create_tunnel_resp_pP->num_tunnels,
+			  ue_context_p->ue_context.enb_gtp_ebi[0],
+			  ue_context_p->ue_context.enb_gtp_teid[0]);
+        (void)rnti; /* avoid gcc warning "set but not used" */
     return 0;
   } else {
     return -1;
   }
 }
 
+void rrc_eNB_send_GTPV1U_ENB_DELETE_TUNNEL_REQ(
+  module_id_t enb_mod_idP,
+  const rrc_eNB_ue_context_t* const ue_context_pP
+)
+{
+  if (!ue_context_pP) {
+    LOG_W(RRC, "[eNB] In %s: invalid UE\n", __func__);
+    return;
+  }
+
+  MSC_LOG_TX_MESSAGE(MSC_RRC_ENB, MSC_GTPU_ENB, NULL, 0,
+                     "0 GTPV1U_ENB_DELETE_TUNNEL_REQ rnti %x ",
+                     ue_context_pP->ue_context.eNB_ue_s1ap_id);
+
+  MessageDef *msg = itti_alloc_new_message(TASK_RRC_ENB, GTPV1U_ENB_DELETE_TUNNEL_REQ);
+  memset(&GTPV1U_ENB_DELETE_TUNNEL_REQ(msg), 0, sizeof(GTPV1U_ENB_DELETE_TUNNEL_REQ(msg)));
+  GTPV1U_ENB_DELETE_TUNNEL_REQ(msg).rnti = ue_context_pP->ue_context.rnti;
+  GTPV1U_ENB_DELETE_TUNNEL_REQ(msg).num_erab = ue_context_pP->ue_context.nb_of_e_rabs;
+  for (int e_rab = 0; e_rab < ue_context_pP->ue_context.nb_of_e_rabs; e_rab++) {
+    const rb_id_t gtp_ebi = ue_context_pP->ue_context.enb_gtp_ebi[e_rab];
+    GTPV1U_ENB_DELETE_TUNNEL_REQ(msg).eps_bearer_id[e_rab] = gtp_ebi;
+  }
+  itti_send_msg_to_task(TASK_GTPV1_U, ENB_MODULE_ID_TO_INSTANCE(enb_mod_idP), msg);
+}
diff --git a/openair2/RRC/LTE/rrc_eNB_GTPV1U.h b/openair2/RRC/LTE/rrc_eNB_GTPV1U.h
index 0cd3f3c51264e428e4f128ef847015eeacc1195e..23806f6a0482544ee0bb8845dc89d043760422d5 100644
--- a/openair2/RRC/LTE/rrc_eNB_GTPV1U.h
+++ b/openair2/RRC/LTE/rrc_eNB_GTPV1U.h
@@ -43,5 +43,14 @@ rrc_eNB_process_GTPV1U_CREATE_TUNNEL_RESP(
   uint8_t                         *inde_list
 );
 
+/*! \fn rrc_eNB_send_GTPV1U_ENB_DELETE_TUNNEL_REQ(module_id_t enb_mod_idP, const rrc_eNB_ue_context_t* const ue_context_pP)
+ *\brief Send GTPV1U_ENB_DELETE_TUNNEL_REQ message to GTPV1U to destroy all UE-related tunnels.
+ *\param module_id Instance ID of eNB.
+ *\param ue_context_pP UE context in the eNB.
+ */
+void rrc_eNB_send_GTPV1U_ENB_DELETE_TUNNEL_REQ(
+  module_id_t enb_mod_idP,
+  const rrc_eNB_ue_context_t* const ue_context_pP
+);
 
 #endif /* RRC_ENB_GTPV1U_H_ */
diff --git a/openair2/RRC/LTE/rrc_eNB_S1AP.c b/openair2/RRC/LTE/rrc_eNB_S1AP.c
index 82818fcd1ed8c3ec226ba0d718d8fa02dfdc61e3..b26e2c1cb06a6246a68c895a8f0c98f81800a10a 100644
--- a/openair2/RRC/LTE/rrc_eNB_S1AP.c
+++ b/openair2/RRC/LTE/rrc_eNB_S1AP.c
@@ -252,7 +252,7 @@ rrc_eNB_S1AP_get_ue_ids(
           ue_desc_p = s1ap_eNB_get_ue_context(s1ap_eNB_instance_p, eNB_ue_s1ap_id); // get s1ap_eNB_ue_context
         } else {
           LOG_E(S1AP, "[eNB instance %d] Couldn't find the eNB S1AP context\n",
-                instance);
+              instance);
           return NULL;
         }
 
@@ -634,7 +634,7 @@ rrc_eNB_send_S1AP_UPLINK_NAS(
             == LTE_ULInformationTransfer_r8_IEs__dedicatedInfoType_PR_dedicatedInfoNAS)) {
       /* This message hold a dedicated info NAS payload, forward it to NAS */
       struct LTE_ULInformationTransfer_r8_IEs__dedicatedInfoType *dedicatedInfoType =
-          &ulInformationTransfer->criticalExtensions.choice.c1.choice.ulInformationTransfer_r8.dedicatedInfoType;
+        &ulInformationTransfer->criticalExtensions.choice.c1.choice.ulInformationTransfer_r8.dedicatedInfoType;
       uint32_t pdu_length;
       uint8_t *pdu_buffer;
       MessageDef *msg_p;
@@ -1021,6 +1021,35 @@ int rrc_eNB_process_S1AP_INITIAL_CONTEXT_SETUP_REQ(MessageDef *msg_p, const char
         rrc_eNB_generate_UECapabilityEnquiry (&ctxt, ue_context_p);
       }
     }
+
+    // in case, send the S1SP initial context response if it is not sent with the attach complete message
+    if (ue_context_p->ue_context.Status == RRC_RECONFIGURED) {
+       LOG_I(RRC, "Sending rrc_eNB_send_S1AP_INITIAL_CONTEXT_SETUP_RESP, cause %ld\n", ue_context_p->ue_context.reestablishment_cause);
+      //if(ue_context_p->ue_context.reestablishment_cause == ReestablishmentCause_spare1){}
+       rrc_eNB_send_S1AP_INITIAL_CONTEXT_SETUP_RESP(&ctxt,ue_context_p);
+    } 
+/*
+    if ((RC.rrc[ctxt.module_id]->node_type == ngran_eNB_CU) ||
+        (RC.rrc[ctxt.module_id]->node_type == ngran_ng_eNB_CU) ||
+        (RC.rrc[ctxt.module_id]->node_type == ngran_gNB_CU) ){
+
+      message_p = itti_alloc_new_message (TASK_RRC_ENB, F1AP_UE_CONTEXT_SETUP_REQ);
+      F1AP_UE_CONTEXT_SETUP_REQ (message_p).rrc_container =  ue_p->Srb0.Tx_buffer.Payload;
+
+      F1AP_UE_CONTEXT_SETUP_REQ (message_p).rrc_container_length = ue_p->Srb0.Tx_buffer.payload_size;
+      F1AP_UE_CONTEXT_SETUP_REQ (message_p).gNB_CU_ue_id     = 0;  
+      F1AP_UE_CONTEXT_SETUP_REQ (message_p).gNB_DU_ue_id = 0;
+      F1AP_UE_CONTEXT_SETUP_REQ (message_p).old_gNB_DU_ue_id  = 0xFFFFFFFF; // unknown 
+      F1AP_UE_CONTEXT_SETUP_REQ (message_p).rnti = ue_p->rnti; 
+      F1AP_UE_CONTEXT_SETUP_REQ (message_p).srb_id = CCCH;  
+      F1AP_UE_CONTEXT_SETUP_REQ (message_p).execute_duplication      = 1;
+      F1AP_UE_CONTEXT_SETUP_REQ (message_p).RAT_frequency_priority_information.en_dc      = 0; 
+      itti_send_msg_to_task (TASK_CU_F1, ctxt_pP->module_id, message_p);
+      LOG_D(RRC, "Send F1AP_UE_CONTEXT_SETUP_REQ with ITTI\n");
+
+    }
+*/
+
     return (0);
   }
 }
@@ -1143,6 +1172,20 @@ rrc_eNB_send_S1AP_UE_CONTEXT_RELEASE_REQ(
   }
 }
 
+void rrc_eNB_send_S1AP_UE_CONTEXT_RELEASE_CPLT(
+  module_id_t enb_mod_idP,
+  uint32_t eNB_ue_s1ap_id
+)
+{
+  MSC_LOG_TX_MESSAGE(MSC_RRC_ENB, MSC_S1AP_ENB, NULL, 0,
+                     "0 S1AP_UE_CONTEXT_RELEASE_COMPLETE eNB_ue_s1ap_id 0x%06"PRIX32" ",
+                     eNB_ue_s1ap_id);
+
+  MessageDef *msg = itti_alloc_new_message(TASK_RRC_ENB, S1AP_UE_CONTEXT_RELEASE_COMPLETE);
+  S1AP_UE_CONTEXT_RELEASE_COMPLETE(msg).eNB_ue_s1ap_id = eNB_ue_s1ap_id;
+  itti_send_msg_to_task(TASK_S1AP, ENB_MODULE_ID_TO_INSTANCE(enb_mod_idP), msg);
+}
+
 
 //-----------------------------------------------------------------------------
 /*
@@ -1759,7 +1802,7 @@ int rrc_eNB_process_PAGING_IND(MessageDef *msg_p, const char *msg_name, instance
           /* set T = min(Tc,Tue) */
           T = Tc < Tue ? Ttab[Tc] : Ttab[Tue];
           /* set pcch_nB = PCCH-Config->nB */
-          pcch_nB = (uint32_t)RC.rrc[instance]->configuration.radioresourceconfig[CC_id].pcch_nB;
+	  pcch_nB = (uint32_t)RC.rrc[instance]->configuration.radioresourceconfig[CC_id].pcch_nB;
 
           switch (pcch_nB) {
             case LTE_PCCH_Config__nB_fourT:
@@ -1905,12 +1948,12 @@ int rrc_eNB_send_PATH_SWITCH_REQ(const protocol_ctxt_t *const ctxt_pP,
   rrc_ue_s1ap_ids_p->eNB_ue_s1ap_id = UE_INITIAL_ID_INVALID;
   rrc_ue_s1ap_ids_p->ue_rnti        = ctxt_pP->rnti;
   h_rc = hashtable_insert(RC.rrc[ctxt_pP->module_id]->initial_id2_s1ap_ids,
-                          (hash_key_t)ue_context_pP->ue_context.ue_initial_id,
-                          rrc_ue_s1ap_ids_p);
+		               (hash_key_t)ue_context_pP->ue_context.ue_initial_id,
+                               rrc_ue_s1ap_ids_p);
 
   if (h_rc != HASH_TABLE_OK) {
     LOG_E(S1AP, "[eNB %d] Error while hashtable_insert in initial_id2_s1ap_ids ue_initial_id %u\n",
-          ctxt_pP->module_id, ue_context_pP->ue_context.ue_initial_id);
+	  ctxt_pP->module_id, ue_context_pP->ue_context.ue_initial_id);
   }
 
   S1AP_PATH_SWITCH_REQ (msg_p).eNB_ue_s1ap_id = ue_context_pP->ue_context.eNB_ue_s1ap_id;
@@ -1923,8 +1966,8 @@ int rrc_eNB_send_PATH_SWITCH_REQ(const protocol_ctxt_t *const ctxt_pP,
   S1AP_PATH_SWITCH_REQ (msg_p).security_capabilities.encryption_algorithms=ue_context_pP->ue_context.security_capabilities.encryption_algorithms;
   S1AP_PATH_SWITCH_REQ (msg_p).security_capabilities.integrity_algorithms=ue_context_pP->ue_context.security_capabilities.integrity_algorithms;
   LOG_I (RRC,"Path switch request: nb nb_of_e_rabs %u status %u\n",
-         ue_context_pP->ue_context.nb_of_e_rabs,
-         ue_context_pP->ue_context.e_rab[e_rab].status);
+          ue_context_pP->ue_context.nb_of_e_rabs,
+          ue_context_pP->ue_context.e_rab[e_rab].status);
   memset(&create_tunnel_req, 0, sizeof(create_tunnel_req));
 
   // the context for UE to be handovered is obtained through ho_req message
@@ -1944,45 +1987,45 @@ int rrc_eNB_send_PATH_SWITCH_REQ(const protocol_ctxt_t *const ctxt_pP,
   create_tunnel_req.rnti           = ue_context_pP->ue_context.rnti;
   create_tunnel_req.num_tunnels    = e_rabs_done;
   gtpv1u_create_s1u_tunnel(
-    ctxt_pP->instance,
-    &create_tunnel_req,
-    &create_tunnel_resp);
+      ctxt_pP->instance,
+      &create_tunnel_req,
+      &create_tunnel_resp);
   rrc_eNB_process_GTPV1U_CREATE_TUNNEL_RESP(
-    ctxt_pP,
-    &create_tunnel_resp,
-    &inde_list[0]);
+        ctxt_pP,
+        &create_tunnel_resp,
+        &inde_list[0]);
 
   for (e_rab = 0; e_rab < e_rabs_done; e_rab++) {
-    S1AP_PATH_SWITCH_REQ (msg_p).e_rabs_tobeswitched[e_rab].e_rab_id = create_tunnel_resp.eps_bearer_id[e_rab];
-    S1AP_PATH_SWITCH_REQ (msg_p).e_rabs_tobeswitched[e_rab].gtp_teid = create_tunnel_resp.enb_S1u_teid[e_rab];
-    S1AP_PATH_SWITCH_REQ (msg_p).e_rabs_tobeswitched[e_rab].eNB_addr = create_tunnel_resp.enb_addr;
-    LOG_I (RRC,"enb_gtp_addr (msg index %d, e_rab index %d, status %d): nb_of_e_rabs %d,  e_rab_id %d, teid: %u, addr: %d.%d.%d.%d \n ",
-           e_rabs_done,  e_rab, ue_context_pP->ue_context.e_rab[inde_list[e_rab]].status,
+      S1AP_PATH_SWITCH_REQ (msg_p).e_rabs_tobeswitched[e_rab].e_rab_id = create_tunnel_resp.eps_bearer_id[e_rab];
+      S1AP_PATH_SWITCH_REQ (msg_p).e_rabs_tobeswitched[e_rab].gtp_teid = create_tunnel_resp.enb_S1u_teid[e_rab];
+      S1AP_PATH_SWITCH_REQ (msg_p).e_rabs_tobeswitched[e_rab].eNB_addr = create_tunnel_resp.enb_addr;
+      LOG_I (RRC,"enb_gtp_addr (msg index %d, e_rab index %d, status %d): nb_of_e_rabs %d,  e_rab_id %d, teid: %u, addr: %d.%d.%d.%d \n ",
+	     e_rabs_done,  e_rab, ue_context_pP->ue_context.e_rab[inde_list[e_rab]].status,
            S1AP_PATH_SWITCH_REQ (msg_p).nb_of_e_rabs,
-           S1AP_PATH_SWITCH_REQ (msg_p).e_rabs_tobeswitched[e_rab].e_rab_id,
-           S1AP_PATH_SWITCH_REQ (msg_p).e_rabs_tobeswitched[e_rab].gtp_teid,
-           S1AP_PATH_SWITCH_REQ (msg_p).e_rabs_tobeswitched[e_rab].eNB_addr.buffer[0],
-           S1AP_PATH_SWITCH_REQ (msg_p).e_rabs_tobeswitched[e_rab].eNB_addr.buffer[1],
-           S1AP_PATH_SWITCH_REQ (msg_p).e_rabs_tobeswitched[e_rab].eNB_addr.buffer[2],
-           S1AP_PATH_SWITCH_REQ (msg_p).e_rabs_tobeswitched[e_rab].eNB_addr.buffer[3]);
+	     S1AP_PATH_SWITCH_REQ (msg_p).e_rabs_tobeswitched[e_rab].e_rab_id,
+	     S1AP_PATH_SWITCH_REQ (msg_p).e_rabs_tobeswitched[e_rab].gtp_teid,
+	     S1AP_PATH_SWITCH_REQ (msg_p).e_rabs_tobeswitched[e_rab].eNB_addr.buffer[0],
+	     S1AP_PATH_SWITCH_REQ (msg_p).e_rabs_tobeswitched[e_rab].eNB_addr.buffer[1],
+	     S1AP_PATH_SWITCH_REQ (msg_p).e_rabs_tobeswitched[e_rab].eNB_addr.buffer[2],
+	     S1AP_PATH_SWITCH_REQ (msg_p).e_rabs_tobeswitched[e_rab].eNB_addr.buffer[3]);
   }
 
-  // NN: add conditions for e_rabs_failed
-  if (e_rabs_done > 0) {
-    LOG_I(RRC,"S1AP_PATH_SWITCH_REQ: sending the message: nb_of_erabstobeswitched %d, total e_rabs %d, index %d\n",
+    // NN: add conditions for e_rabs_failed
+    if (e_rabs_done > 0) {
+      LOG_I(RRC,"S1AP_PATH_SWITCH_REQ: sending the message: nb_of_erabstobeswitched %d, total e_rabs %d, index %d\n",
           S1AP_PATH_SWITCH_REQ (msg_p).nb_of_e_rabs, ue_context_pP->ue_context.setup_e_rabs, e_rab);
-    MSC_LOG_TX_MESSAGE(
-      MSC_RRC_ENB,
-      MSC_S1AP_ENB,
-      (const char *)&S1AP_PATH_SWITCH_REQ (msg_p),
-      sizeof(s1ap_path_switch_req_t),
-      MSC_AS_TIME_FMT" PATH_SWITCH_REQ UE %X eNB_ue_s1ap_id %u e_rabs:%u succ",
-      MSC_AS_TIME_ARGS(ctxt_pP),
-      ue_context_pP->ue_id_rnti,
-      S1AP_PATH_SWITCH_REQ (msg_p).eNB_ue_s1ap_id,
-      e_rabs_done);
-    itti_send_msg_to_task (TASK_S1AP, ctxt_pP->instance, msg_p);
-  }
+      MSC_LOG_TX_MESSAGE(
+			 MSC_RRC_ENB,
+			 MSC_S1AP_ENB,
+			 (const char *)&S1AP_PATH_SWITCH_REQ (msg_p),
+			 sizeof(s1ap_path_switch_req_t),
+			 MSC_AS_TIME_FMT" PATH_SWITCH_REQ UE %X eNB_ue_s1ap_id %u e_rabs:%u succ",
+			 MSC_AS_TIME_ARGS(ctxt_pP),
+			 ue_context_pP->ue_id_rnti,
+			 S1AP_PATH_SWITCH_REQ (msg_p).eNB_ue_s1ap_id,
+			 e_rabs_done);
+	itti_send_msg_to_task (TASK_S1AP, ctxt_pP->instance, msg_p);
+     }
 
   return 0;
 }
@@ -2036,10 +2079,10 @@ int rrc_eNB_process_S1AP_PATH_SWITCH_REQ_ACK (MessageDef *msg_p, const char *msg
       // the index for the rec
       if (nb_e_rabs_tobeswitched>0) {
         int e_rab_switch_index=0;
-        for (i = 0;
+      for (i = 0;
 	     i < ue_context_p->ue_context.setup_e_rabs; // go over total number of e_rabs received through x2_ho_req msg
-	     i++) {
-	  /* Harmonize with enb_gtp_teid, enb_gtp_addrs, and enb_gtp_rbi vars in the top level structure */
+	   i++) {
+	/* Harmonize with enb_gtp_teid, enb_gtp_addrs, and enb_gtp_rbi vars in the top level structure */
           if (ue_context_p->ue_context.e_rab[i].param.e_rab_id == S1AP_PATH_SWITCH_REQ_ACK (msg_p).e_rabs_tobeswitched[e_rab_switch_index].e_rab_id) {
 	    ue_context_p->ue_context.e_rab[i].param.e_rab_id = S1AP_PATH_SWITCH_REQ_ACK (msg_p).e_rabs_tobeswitched[e_rab_switch_index].e_rab_id;
 	    ue_context_p->ue_context.e_rab[i].param.sgw_addr= S1AP_PATH_SWITCH_REQ_ACK (msg_p).e_rabs_tobeswitched[e_rab_switch_index].sgw_addr;
@@ -2058,11 +2101,11 @@ int rrc_eNB_process_S1AP_PATH_SWITCH_REQ_ACK (MessageDef *msg_p, const char *msg
 
     if (ue_context_p->ue_context.nb_release_of_e_rabs>0) {
       int e_rab_release_index=0;
-      for (i = 0;
+    for (i = 0;
 	   i < ue_context_p->ue_context.setup_e_rabs;
-	   i++) {
+	 i++) {
         if (ue_context_p->ue_context.e_rab[i].param.e_rab_id == S1AP_PATH_SWITCH_REQ_ACK (msg_p).e_rabs_tobereleased[e_rab_release_index].e_rab_id) {
-          LOG_I(RRC,"Bearer released with ID: %d\n", ue_context_p->ue_context.e_rab[i].param.e_rab_id);
+      LOG_I(RRC,"Bearer released with ID: %d\n", ue_context_p->ue_context.e_rab[i].param.e_rab_id);
           ue_context_p->ue_context.e_rab[i].status =  E_RAB_STATUS_TORELEASE;
           ue_context_p->ue_context.e_rabs_tobereleased[e_rab_release_index]=S1AP_PATH_SWITCH_REQ_ACK (msg_p).e_rabs_tobereleased[e_rab_release_index].e_rab_id;
           delete_tunnel_req.eps_bearer_id[e_rab_release_index] = S1AP_PATH_SWITCH_REQ_ACK (msg_p).e_rabs_tobereleased[e_rab_release_index].e_rab_id;
@@ -2079,7 +2122,7 @@ int rrc_eNB_process_S1AP_PATH_SWITCH_REQ_ACK (MessageDef *msg_p, const char *msg
       delete_tunnel_req.num_erab= ue_context_p->ue_context.nb_release_of_e_rabs;
       /* this could also be done through ITTI message */
       gtpv1u_delete_s1u_tunnel(instance,
-                               &delete_tunnel_req);
+			       &delete_tunnel_req);
       /* TBD: release the DRB not admitted */
       //rrc_eNB_generate_dedicatedRRCConnectionReconfiguration(&ctxt, ue_context_p, 0);
     }
diff --git a/openair2/RRC/LTE/rrc_eNB_S1AP.h b/openair2/RRC/LTE/rrc_eNB_S1AP.h
index da63fc68a36ab17ec304bc6300015a1e852831b3..5feb55d635c63461b237b439f5f1654d9e2882dc 100644
--- a/openair2/RRC/LTE/rrc_eNB_S1AP.h
+++ b/openair2/RRC/LTE/rrc_eNB_S1AP.h
@@ -73,14 +73,14 @@ rrc_eNB_S1AP_remove_ue_ids(
 void
 rrc_eNB_generate_dedicatedRRCConnectionReconfiguration(const protocol_ctxt_t *const ctxt_pP,
     rrc_eNB_ue_context_t          *const ue_context_pP,
-    const uint8_t                ho_state
-                                                      );
+                                                     const uint8_t                ho_state
+                                                     );
 
 int
 rrc_eNB_modify_dedicatedRRCConnectionReconfiguration(const protocol_ctxt_t *const ctxt_pP,
     rrc_eNB_ue_context_t          *const ue_context_pP,
-    const uint8_t                ho_state
-                                                    );
+                                                     const uint8_t                ho_state
+                                                     );
 
 /*! \fn void rrc_eNB_send_S1AP_INITIAL_CONTEXT_SETUP_RESP(uint8_t mod_id, uint8_t ue_index)
  *\brief create a S1AP_INITIAL_CONTEXT_SETUP_RESP for S1AP.
@@ -148,6 +148,16 @@ void rrc_eNB_send_S1AP_UE_CONTEXT_RELEASE_REQ (
   const long                               cause_valueP
 );
 
+/*! \fn rrc_eNB_send_S1AP_UE_CONTEXT_RELEASE_CPLT(const module_id_t enb_mod_idP, const struct rrc_eNB_ue_context_s *const ue_context_pP)
+ *\brief create a S1AP_UE_CONTEXT_RELEASE_COMPLETE message, the message is sent by the eNB to S1AP task to acknowledge/complete the release of the UE-associated S1-logical connection over the S1 interface. .
+ *\param enb_mod_idP Instance ID of eNB.
+ *\param eNB_ue_s1ap_id UE's S1AP ID in the eNB.
+ */
+void rrc_eNB_send_S1AP_UE_CONTEXT_RELEASE_CPLT(
+  module_id_t enb_mod_idP,
+  uint32_t eNB_ue_s1ap_id
+);
+
 /* Down link procedures */
 
 /*! \fn rrc_eNB_process_S1AP_DOWNLINK_NAS(MessageDef *msg_p, const char *msg_name, instance_t instance, mui_t *rrc_eNB_mui)
@@ -183,7 +193,7 @@ int rrc_eNB_process_S1AP_E_RAB_SETUP_REQ(MessageDef *msg_p, const char *msg_name
  *\brief send a S1AP dedicated E_RAB setup response
  *\param ctxt_pP contxt infirmation
  *\param e_contxt_pP ue specific context at the eNB
- *\param xid transaction identifier
+ *\param xid transaction identifier 
  *\return 0 when successful, -1 if the UE index can not be retrieved.
  */
 int rrc_eNB_send_S1AP_E_RAB_SETUP_RESP(const protocol_ctxt_t *const ctxt_pP, rrc_eNB_ue_context_t  *const ue_context_pP, uint8_t xid );
diff --git a/openair2/RRC/LTE/rrc_proto.h b/openair2/RRC/LTE/rrc_proto.h
index 6a69ecd2726fdb1cf5b50e4f95e4f358315ad012..99b77b6b61dbc05ab57be000e0e7382be85a33d9 100644
--- a/openair2/RRC/LTE/rrc_proto.h
+++ b/openair2/RRC/LTE/rrc_proto.h
@@ -62,7 +62,7 @@ openair_rrc_on_ue(
 
 void rrc_top_cleanup(void);
 
-/** \brief Function to update eNB timers every subframe.
+/** \brief Function to update eNB timers every subframe.  
 @param ctxt_pP  running context
 @param enb_index
 @param CC_id
@@ -220,13 +220,13 @@ uint8_t rrc_eNB_get_next_transaction_identifier(module_id_t module_idP);
 
 /**\brief Entry routine to decode a UL-CCCH-Message.  Invokes PER decoder and parses message.
    \param ctxt_pP Running context
-   \param Srb_info Pointer to SRB0 information structure (buffer, etc.)*/
-int
-rrc_eNB_decode_ccch(
-  protocol_ctxt_t *const ctxt_pP,
-  const SRB_INFO        *const Srb_info,
-  const int              CC_id
-);
+   \param buffer Pointer to SDU
+   \param buffer_length length of SDU in bytes
+   \param CC_id component carrier index*/
+int rrc_eNB_decode_ccch(protocol_ctxt_t* const ctxt_pP,
+                        const uint8_t         *buffer,
+                        int                    buffer_length,
+                        const int              CC_id);
 
 /**\brief Entry routine to decode a UL-DCCH-Message.  Invokes PER decoder and parses message.
    \param ctxt_pP Context
@@ -306,16 +306,16 @@ void
 flexran_rrc_eNB_generate_defaultRRCConnectionReconfiguration(
   const protocol_ctxt_t *const ctxt_pP,
   rrc_eNB_ue_context_t *const ue_context_pP,
-  const uint8_t ho_state,
+							     const uint8_t ho_state,
   agent_reconf_rrc *trig_param
 );
 void
 rrc_eNB_generate_HO_RRCConnectionReconfiguration(const protocol_ctxt_t *const ctxt_pP,
     rrc_eNB_ue_context_t  *const ue_context_pP,
     uint8_t               *buffer,
-    int                    *_size
-    //const uint8_t        ho_state
-                                                );
+                                                 int                    *_size
+                                                 //const uint8_t        ho_state
+                                                 );
 void
 rrc_eNB_configure_rbs_handover(struct rrc_eNB_ue_context_s *ue_context_p, protocol_ctxt_t *const ctxt_pP);
 
@@ -340,7 +340,7 @@ rrc_eNB_generate_dedicatedRRCConnectionReconfiguration_release(
   uint8_t                 *nas_buffer
 );
 
-void
+void 
 rrc_eNB_reconfigure_DRBs (const protocol_ctxt_t *const ctxt_pP,
                           rrc_eNB_ue_context_t  *ue_context_pP);
 
@@ -381,8 +381,8 @@ int
 rrc_eNB_generate_RRCConnectionReconfiguration_Sidelink(
   const protocol_ctxt_t *const ctxt_pP,
   rrc_eNB_ue_context_t           *const ue_context_pP,
-  LTE_SL_DestinationInfoList_r12_t  *destinationInfoList,
-  int n_discoveryMessages
+      LTE_SL_DestinationInfoList_r12_t  *destinationInfoList,
+      int n_discoveryMessages
 );
 
 /** \brief process the received SidelinkUEInformation message at eNB
@@ -402,7 +402,7 @@ rrc_eNB_process_SidelinkUEInformation(
 LTE_SL_CommConfig_r12_t rrc_eNB_get_sidelink_commTXPool(
   const protocol_ctxt_t *const ctxt_pP,
   rrc_eNB_ue_context_t *const ue_context_pP,
-  LTE_SL_DestinationInfoList_r12_t  *destinationInfoList
+      LTE_SL_DestinationInfoList_r12_t  *destinationInfoList
 );
 
 /** \brief Get a Resource Pool for Discovery
@@ -412,7 +412,7 @@ LTE_SL_CommConfig_r12_t rrc_eNB_get_sidelink_commTXPool(
 LTE_SL_DiscConfig_r12_t rrc_eNB_get_sidelink_discTXPool(
   const protocol_ctxt_t *const ctxt_pP,
   rrc_eNB_ue_context_t *const ue_context_pP,
-  int n_discoveryMessages
+      int n_discoveryMessages
 );
 
 /** \brief Process request from control socket
@@ -427,6 +427,7 @@ mac_rrc_data_req(
   const int         CC_id,
   const frame_t     frameP,
   const rb_id_t     Srb_id,
+  const rnti_t      rnti,
   const uint8_t     Nb_tb,
   uint8_t    *const buffer_pP,
   const uint8_t     mbsfn_sync_area
@@ -435,16 +436,17 @@ mac_rrc_data_req(
 int8_t
 mac_rrc_data_ind(
   const module_id_t     module_idP,
-  const int         CC_id,
+  const int             CC_id,
   const frame_t         frameP,
   const sub_frame_t     sub_frameP,
+  const int             UE_id,
   const rnti_t          rntiP,
   const rb_id_t         srb_idP,
   const uint8_t        *sduP,
   const sdu_size_t      sdu_lenP,
   const uint8_t         mbsfn_sync_areaP
 #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
-  , const boolean_t   brOption
+  , const boolean_t		brOption
 #endif
 );
 
@@ -477,22 +479,22 @@ mac_rrc_data_ind_ue(
 void mac_sync_ind( module_id_t Mod_instP, uint8_t status);
 
 void mac_eNB_rrc_ul_failure(const module_id_t Mod_instP,
-                            const int CC_id,
-                            const frame_t frameP,
-                            const sub_frame_t subframeP,
-                            const rnti_t rnti);
+			    const int CC_id,
+			    const frame_t frameP,
+			    const sub_frame_t subframeP,
+			    const rnti_t rnti);
 
 void mac_eNB_rrc_uplane_failure(const module_id_t Mod_instP,
-                                const int CC_id,
-                                const frame_t frameP,
-                                const sub_frame_t subframeP,
-                                const rnti_t rnti);
+                const int CC_id,
+                const frame_t frameP,
+                const sub_frame_t subframeP,
+                const rnti_t rnti);
 
-void mac_eNB_rrc_ul_in_sync(const module_id_t Mod_instP,
-                            const int CC_id,
-                            const frame_t frameP,
-                            const sub_frame_t subframeP,
-                            const rnti_t rnti);
+void mac_eNB_rrc_ul_in_sync(const module_id_t Mod_instP, 
+			    const int CC_id, 
+			    const frame_t frameP,
+			    const sub_frame_t subframeP,
+			    const rnti_t rnti);
 
 uint8_t
 rrc_data_req(
@@ -631,7 +633,7 @@ rrc_eNB_free_mem_UE_context(
 
 void
 rrc_eNB_free_UE(
-  const module_id_t enb_mod_idP,
+		const module_id_t enb_mod_idP,
   const struct rrc_eNB_ue_context_s         *const ue_context_pP
 );
 
@@ -642,10 +644,10 @@ long binary_search_float(float elements[], long numElem, float value);
 void openair_rrc_top_init_eNB(int eMBMS_active,uint8_t HO_active);
 
 void openair_rrc_top_init_ue(
-  int eMBMS_active,
+                        int eMBMS_active,
   char *uecap_xer,
-  uint8_t cba_group_active,
-  uint8_t HO_active
+                        uint8_t cba_group_active,
+                        uint8_t HO_active
 );
 pthread_mutex_t      rrc_release_freelist;
 RRC_release_list_t rrc_release_info;
diff --git a/openair2/UTIL/ASYNC_IF/link_manager.c b/openair2/UTIL/ASYNC_IF/link_manager.c
index c1ce742d0bbe6928623dfa5cea8abf8c194f8670..e9a8e98e0768b282975a3c3b5f9a3223d0535eaf 100644
--- a/openair2/UTIL/ASYNC_IF/link_manager.c
+++ b/openair2/UTIL/ASYNC_IF/link_manager.c
@@ -46,15 +46,10 @@ static void *link_manager_sender_thread(void *_manager)
   LOG_D(MAC, "starting link manager sender thread\n");
 
   while (manager->run) {
-    while (message_get(manager->send_queue, &data, &size, &priority) == 0) {
-      link_send_packet(manager->socket_link, data, size);
+    while ((size = message_get(manager->send_queue, &data, &priority)) > 0) {
+      link_send_packet(manager->socket_link, data, size, manager->peer_addr, manager->peer_port);
       free(data);
     }
-    //    if (message_get(manager->send_queue, &data, &size, &priority))
-    //  goto error;
-    //if (link_send_packet(manager->socket_link, data, size))
-    //  goto error;
-    //free(data);
   }
 
   LOG_D(MAC, "link manager sender thread quits\n");
@@ -124,9 +119,6 @@ link_manager_t *create_link_manager(
   pthread_attr_setschedpolicy(&attr, SCHED_RR);
   //#endif
 
-  if (pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED))
-    goto error;
-
   if (pthread_create(&t, &attr, link_manager_sender_thread, ret))
     goto error;
   ret->sender = t;
@@ -151,9 +143,11 @@ error:
 
 void destroy_link_manager(link_manager_t *manager)
 {
-  LOG_D(MAC, "destroying link manager\n");
   manager->run = 0;
-  /* todo: force threads to stop (using a dummy message?) */
+  message_get_unlock(manager->send_queue);
+  pthread_join(manager->sender, NULL);
+  /* cancel aborts the read performed in the receiver, then cancels the thread */
+  pthread_cancel(manager->receiver);
 }
 
 #ifdef SERVER_TEST
@@ -186,7 +180,7 @@ int main(void)
   data = strdup("hello"); if (data == NULL) goto error;
   if (message_put(send_queue, data, 6, 100)) goto error;
 
-  if (message_get(receive_queue, &data, &size, &priority)) goto error;
+  if ((size = message_get(receive_queue, &data, &priority)) <= 0) goto error;
   printf("received message:\n");
   printf("    data: %s\n", (char *)data);
   printf("    size: %d\n", size);
@@ -230,7 +224,7 @@ int main(void)
   manager = create_link_manager(send_queue, receive_queue, link);
   if (manager == NULL) goto error;
 
-  if (message_get(receive_queue, &data, &size, &priority)) goto error;
+  if ((size = message_get(receive_queue, &data, &priority)) <= 0) goto error;
   printf("received message:\n");
   printf("    data: %s\n", (char *)data);
   printf("    size: %d\n", size);
diff --git a/openair2/UTIL/ASYNC_IF/link_manager.h b/openair2/UTIL/ASYNC_IF/link_manager.h
index 90ede6c3db61865692c72c4d2721da720cd9350c..4148392eecc9e8461c7445f6672349976fbfaae4 100644
--- a/openair2/UTIL/ASYNC_IF/link_manager.h
+++ b/openair2/UTIL/ASYNC_IF/link_manager.h
@@ -31,8 +31,8 @@
 #ifndef LINK_MANAGER_H
 #define LINK_MANAGER_H
 
-//#include "message_queue.h"
-#include "ringbuffer_queue.h"
+#include "message_queue.h"
+//#include "ringbuffer_queue.h"
 #include "socket_link.h"
 
 #include <pthread.h>
@@ -45,6 +45,8 @@ typedef struct {
   message_queue_t *send_queue;
   message_queue_t *receive_queue;
   socket_link_t   *socket_link;
+  const char      *peer_addr; /* for UDP server remote IP */
+  int             peer_port;  /* for UDP server remote address */
   pthread_t       sender;
   pthread_t       receiver;
   volatile int    run;
@@ -54,6 +56,7 @@ link_manager_t *create_link_manager(
         message_queue_t *send_queue,
         message_queue_t *receive_queue,
         socket_link_t   *link);
+
 void destroy_link_manager(link_manager_t *);
 
 #ifdef __cplusplus
diff --git a/openair2/UTIL/ASYNC_IF/message_queue.c b/openair2/UTIL/ASYNC_IF/message_queue.c
index 2581840388a8ed4e3dfe6380c1d31790d313001e..2279a067b4547e8bea6edbeda98bd3968b9ebb85 100644
--- a/openair2/UTIL/ASYNC_IF/message_queue.c
+++ b/openair2/UTIL/ASYNC_IF/message_queue.c
@@ -56,6 +56,10 @@ message_queue_t *new_message_queue(void)
   if (pthread_cond_init(ret->cond, NULL))
     goto error;
 
+  ret->head = NULL;
+  ret->tail = NULL;
+  ret->exit = 0;
+
   return ret;
 
 error:
@@ -72,6 +76,8 @@ error:
 int message_put(message_queue_t *queue, void *data, int size, int priority)
 {
   message_t *m = NULL;
+  if (size <= 0)
+    goto error;
 
   m = calloc(1, sizeof(message_t));
   if (m == NULL)
@@ -106,12 +112,12 @@ int message_put(message_queue_t *queue, void *data, int size, int priority)
   return 0;
 
 error:
-  free(m);
+  if (m) free(m);
   LOG_E(MAC, "%s: an error occured\n", __FUNCTION__);
   return -1;
 }
 
-int message_get(message_queue_t *queue, void **data, int *size, int *priority)
+int message_get(message_queue_t *queue, void **data, int *priority)
 {
   message_t *m;
 
@@ -119,10 +125,15 @@ int message_get(message_queue_t *queue, void **data, int *size, int *priority)
     goto error;
 
   while (queue->count == 0) {
-    if (pthread_cond_wait(queue->cond, queue->mutex)) {
+    int rc = pthread_cond_wait(queue->cond, queue->mutex);
+    if (rc != 0) {
       pthread_mutex_unlock(queue->mutex);
       goto error;
     }
+    if (queue->exit) {
+      pthread_mutex_unlock(queue->mutex);
+      return 0;
+    }
   }
 
   m = queue->head;
@@ -136,17 +147,24 @@ int message_get(message_queue_t *queue, void **data, int *size, int *priority)
     goto error;
 
   *data = m->data;
-  *size = m->size;
+  const int size = m->size;
   *priority = m->priority;
   free(m);
 
-  return 0;
-
+  return size;
 error:
   LOG_E(MAC, "%s: an error occured\n", __FUNCTION__);
   return -1;
 }
 
+void message_get_unlock(message_queue_t *queue)
+{
+  pthread_mutex_lock(queue->mutex);
+  queue->exit = 1;
+  pthread_mutex_unlock(queue->mutex);
+  pthread_cond_signal(queue->cond);
+}
+
 /* when calling this function, the queue must not be used anymore (we don't lock it) */
 /* we suppose that the data pointer in messages was allocated by malloc/calloc/realloc */
 void destroy_message_queue(message_queue_t *queue)
@@ -181,10 +199,10 @@ int main(void)
   if (message_put(q, "hello", 6, 0)) goto error;
   if (message_put(q, "world", 6, 1)) goto error;
 
-  if (message_get(q, &data, &size, &priority)) goto error;
+  if ((size = message_get(q, &data, &priority)) <= 0) goto error;
   printf("message:\n  data: '%s'\n  size: %d\n  priority: %d\n",
          (char *)data, size, priority);
-  if (message_get(q, &data, &size, &priority)) goto error;
+  if ((size = message_get(q, &data, &priority)) <= 0) goto error;
   printf("message:\n  data: '%s'\n  size: %d\n  priority: %d\n",
          (char *)data, size, priority);
 
diff --git a/openair2/UTIL/ASYNC_IF/message_queue.h b/openair2/UTIL/ASYNC_IF/message_queue.h
index 8fedddcc7751fa0233dcd5fbf133df88d6581062..656f3db28e3d87a271c2db0516a645631d62c0b6 100644
--- a/openair2/UTIL/ASYNC_IF/message_queue.h
+++ b/openair2/UTIL/ASYNC_IF/message_queue.h
@@ -41,6 +41,7 @@ typedef struct message_t {
   void *data;
   int  size;
   int  priority;
+
   struct message_t *next;
 } message_t;
 
@@ -50,11 +51,13 @@ typedef struct {
   volatile int    count;
   pthread_mutex_t *mutex;
   pthread_cond_t  *cond;
+  int             exit;
 } message_queue_t;
 
 message_queue_t *new_message_queue(void);
 int message_put(message_queue_t *queue, void *data, int size, int priority);
-int message_get(message_queue_t *queue, void **data, int *size, int *priority);
+int message_get(message_queue_t *queue, void **data, int *priority);
+void message_get_unlock(message_queue_t *queue);
 void destroy_message_queue(message_queue_t *queue);
 
 #ifdef __cplusplus
diff --git a/openair2/UTIL/ASYNC_IF/ringbuffer_queue.c b/openair2/UTIL/ASYNC_IF/ringbuffer_queue.c
index 201603e0c57f327541c7aa0da91ba076a9393ced..7bcd3b564747b143ca31fc0f8ac9251120aba5d1 100644
--- a/openair2/UTIL/ASYNC_IF/ringbuffer_queue.c
+++ b/openair2/UTIL/ASYNC_IF/ringbuffer_queue.c
@@ -67,6 +67,9 @@ int message_put(message_queue_t *queue, void *data, int size, int priority) {
   message_t *overwritten_msg;
   message_t *m = NULL;
 
+  if (size <= 0)
+    goto error;
+
   LFDS700_MISC_MAKE_VALID_ON_CURRENT_LOGICAL_CORE_INITS_COMPLETED_BEFORE_NOW_ON_ANY_OTHER_LOGICAL_CORE;
   lfds700_misc_prng_init(&ls);
   
@@ -94,12 +97,11 @@ int message_put(message_queue_t *queue, void *data, int size, int priority) {
   return 0;
 
  error:
-  free(m);
   LOG_E(MAC, "%s: an error occured\n", __FUNCTION__);
   return -1;
 }
 
-int message_get(message_queue_t *queue, void **data, int *size, int *priority) {
+int message_get(message_queue_t *queue, void **data, int *priority) {
   message_t *m;
   struct lfds700_misc_prng_state ls;
   
@@ -111,10 +113,15 @@ int message_get(message_queue_t *queue, void **data, int *size, int *priority) {
   }
 
   *data = m->data;
-  *size = m->size;
+  const int size = m->size;
   *priority = m->priority;
   free(m);
-  return 0;
+  return size;
+}
+
+void message_get_unlock(message_queue_t *queue) {
+  /* don't do anything, this function exists to unlock a message_queue but is
+   * not needed in the case of the ringbuffer_queue */
 }
 
 void destroy_message_queue(message_queue_t *queue) {
diff --git a/openair2/UTIL/ASYNC_IF/ringbuffer_queue.h b/openair2/UTIL/ASYNC_IF/ringbuffer_queue.h
index 04414cbbb2b9618379ad1284a056943e04539c23..bb65612e6bfcfbee4f76ec79737158c268801a11 100644
--- a/openair2/UTIL/ASYNC_IF/ringbuffer_queue.h
+++ b/openair2/UTIL/ASYNC_IF/ringbuffer_queue.h
@@ -47,7 +47,8 @@ typedef struct {
 
 message_queue_t * new_message_queue(int size);
 int message_put(message_queue_t *queue, void *data, int size, int priority);
-int message_get(message_queue_t *queue, void **data, int *size, int *priority);
+int message_get(message_queue_t *queue, void **data, int *priority);
+void message_get_unlock(message_queue_t *queue);
 void destroy_message_queue(message_queue_t *queue);
 
 #endif /* RINGBUFFER_QUEUE_H */
diff --git a/openair2/UTIL/ASYNC_IF/socket_link.c b/openair2/UTIL/ASYNC_IF/socket_link.c
index edfa2bde81948b29df2bf7c3cbce808db3f5843e..e40fba4a04da35bce9fd12ff173b65d0e9f286c3 100644
--- a/openair2/UTIL/ASYNC_IF/socket_link.c
+++ b/openair2/UTIL/ASYNC_IF/socket_link.c
@@ -51,6 +51,7 @@ socket_link_t *new_link_server(int port)
   socklen_t          addrlen;
   int                socket_server = -1;
   int no_delay;
+
   
   ret = calloc(1, sizeof(socket_link_t));
   if (ret == NULL) {
@@ -59,22 +60,26 @@ socket_link_t *new_link_server(int port)
   }
   ret->socket_fd = -1;
 
-  LOG_D(MAC, "create a new link server socket at port %d\n", port);
+
+  //printf("MAC create a new link server socket at port %d\n", port);
 
   socket_server = socket(AF_INET, SOCK_STREAM, 0);
   if (socket_server == -1) {
     LOG_E(MAC, "%s:%d: socket: %s\n", __FILE__, __LINE__, strerror(errno));
     goto error;
   }
+  ret->type = SOCK_STREAM;
 
   reuse = 1;
   if (setsockopt(socket_server, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) == -1) {
+
     LOG_E(MAC, "%s:%d: setsockopt: %s\n", __FILE__, __LINE__, strerror(errno));
     goto error;
   }
 
   no_delay = 1;
   if (setsockopt(socket_server, IPPROTO_TCP, TCP_NODELAY, &no_delay, sizeof(no_delay)) == -1) {
+
     LOG_E(MAC, "%s:%d: setsockopt: %s\n", __FILE__, __LINE__, strerror(errno));
     goto error;
   }
@@ -99,20 +104,19 @@ socket_link_t *new_link_server(int port)
     goto error;
   }
 
-  close(socket_server);
-
-  LOG_D(MAC, "connection from %s:%d\n", inet_ntoa(addr.sin_addr), ntohs(addr.sin_port));
+  //printf("MAC connection from %s:%d\n", inet_ntoa(addr.sin_addr), ntohs(addr.sin_port));
   return ret;
 
 error:
   close(socket_server);
   if (ret != NULL) close(ret->socket_fd);
   free(ret);
+
   LOG_E(MAC, "ERROR in new_link_server (see above), returning NULL\n");
   return NULL;
 }
 
-socket_link_t *new_link_client(char *server, int port)
+socket_link_t *new_link_client(const char *server, int port)
 {
   socket_link_t      *ret = NULL;
   struct sockaddr_in addr;
@@ -132,6 +136,7 @@ socket_link_t *new_link_client(char *server, int port)
     LOG_E(MAC, "%s:%d: socket: %s\n", __FILE__, __LINE__, strerror(errno));
     goto error;
   }
+  ret->type = SOCK_STREAM;
 
   no_delay = 1;
   if (setsockopt(ret->socket_fd, SOL_TCP, TCP_NODELAY, &no_delay, sizeof(no_delay)) == -1) {
@@ -160,6 +165,263 @@ error:
   return NULL;
 }
 
+socket_link_t *new_link_udp_server(const char *bind_addr, int bind_port)
+{
+  socket_link_t  *ret = NULL;
+
+  struct sockaddr_in si_me;
+  int socket_server = -1;
+
+  ret = calloc(1, sizeof(socket_link_t));
+  if (ret == NULL) {
+    LOG_D(PROTO_AGENT, "%s:%d: out of memory\n", __FILE__, __LINE__);
+    goto error;
+  }
+  ret->socket_fd = -1;
+
+  //printf("PROTO_AGENT: create a new udp link server socket at port %d\n", port);
+
+  //create a UDP socket
+  if ((socket_server=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) {
+    goto error;
+  }
+  ret->type = SOCK_DGRAM;
+
+  // zero out the structure
+  memset((char *) &si_me, 0, sizeof(si_me));
+
+  si_me.sin_family = AF_INET;
+  si_me.sin_port = htons(bind_port);
+  if (bind_addr) {
+    if (!inet_aton(bind_addr, &si_me.sin_addr))
+      goto error;
+  } else {
+    si_me.sin_addr.s_addr = INADDR_ANY;
+  }
+
+  //bind socket to port
+  if( bind(socket_server , (struct sockaddr*)&si_me, sizeof(si_me) ) == -1) {
+    fprintf(stderr, "could not bind to address %s: %s\n", bind_addr, strerror(errno));
+    goto error;
+  }
+  ret->socket_fd = socket_server;
+  return ret;
+  
+error:
+  if (socket_server != -1) close(socket_server);
+  if (ret != NULL) close(ret->socket_fd);
+  free(ret);
+  //printf("\n\n\nERROR PROTO_AGENT: ERROR in new_link_udp_server (see above), returning NULL\n");
+  return NULL;
+}
+
+
+socket_link_t *new_link_udp_client(const char *server, int port){
+
+  socket_link_t      *ret = NULL;
+  ret = calloc(1, sizeof(socket_link_t));
+  if (ret == NULL) {
+    LOG_E(MAC, "%s:%d: out of memory\n", __FILE__, __LINE__);
+    goto error;
+  }
+  ret->socket_fd = -1;
+
+  struct sockaddr_in si_other;
+  int s;
+  socklen_t slen;
+ 
+  if ( (s=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1){
+        goto error;
+  }
+  ret->type = SOCK_DGRAM;
+ 
+  memset((char *) &si_other, 0, sizeof(si_other));
+  si_other.sin_family = AF_INET;
+  si_other.sin_port = 0; //htons(port);
+  
+
+  
+  if (inet_aton(server, &si_other.sin_addr) == 0){
+        fprintf(stderr, "inet_aton() failed\n");
+        goto error;
+  }
+  connect(s, (struct sockaddr *)&si_other, sizeof(si_other)); 
+  
+  getsockname(s, (struct sockaddr *)&si_other, &slen);
+
+  ret->socket_fd = s;
+ 
+  return ret;
+error:
+  if (ret != NULL) {
+    close(ret->socket_fd);
+    free(ret);
+  }
+  LOG_E(MAC, "ERROR in new_link_udp_client (see above), returning NULL\n");
+  return NULL;
+}
+
+
+socket_link_t *new_link_sctp_server(int port)
+{
+
+  socket_link_t  *ret = NULL;
+
+  int listenSock = -1, temp;
+  struct sockaddr_in servaddr;
+ 
+  listenSock = socket (AF_INET, SOCK_STREAM, IPPROTO_SCTP);
+  if(listenSock == -1)
+  {
+      perror("socket()");
+      exit(1);
+  }
+ 
+  bzero ((void *) &servaddr, sizeof (servaddr));
+  servaddr.sin_family = AF_INET;
+  servaddr.sin_addr.s_addr = INADDR_ANY;
+  servaddr.sin_port = htons(port);
+ 
+  temp = bind (listenSock, (struct sockaddr *) &servaddr, sizeof (servaddr));
+ 
+  if(temp == -1 )
+  {
+      perror("bind()");
+      close(listenSock);
+      exit(1);
+  }
+ 
+  temp = listen (listenSock, 5);
+    if(temp == -1 )
+  {
+      perror("listen()");
+      close(listenSock);
+      exit(1);
+  }
+  ret = calloc(1, sizeof(socket_link_t));
+  if (ret == NULL) {
+    LOG_D(PROTO_AGENT, "%s:%d: out of memory\n", __FILE__, __LINE__);
+    goto error;
+  }
+  ret->socket_fd = -1;
+
+  ret->socket_fd = accept (listenSock, NULL, NULL);
+  ret->type = SOCK_STREAM;
+  
+  return ret;
+
+error:
+  if (listenSock != -1) close(listenSock);
+  if (ret != NULL) close(ret->socket_fd);
+  free(ret);
+  LOG_E(MAC,"ERROR in new_link_sctp_server (see above), returning NULL\n");
+  return NULL;
+}
+
+socket_link_t *new_link_sctp_client(const char *server, int port)
+{
+
+  socket_link_t      *ret = NULL;
+  ret = calloc(1, sizeof(socket_link_t));
+  if (ret == NULL) {
+    LOG_D(PROTO_AGENT, "%s:%d: out of memory\n", __FILE__, __LINE__);
+    goto error;
+  }
+  ret->socket_fd = -1;
+
+  int temp;
+  struct sockaddr_in servaddr;
+    
+  ret->socket_fd = socket (AF_INET, SOCK_STREAM, IPPROTO_SCTP);
+ 
+  if (ret->socket_fd == -1)
+  {
+      perror("socket()");
+      exit(1);
+  }
+  ret->type = SOCK_STREAM;
+ 
+  bzero ((void *) &servaddr, sizeof (servaddr));
+  servaddr.sin_family = AF_INET;
+  servaddr.sin_port = htons (port);
+
+  if (inet_aton(server, &servaddr.sin_addr) == 0) {
+    LOG_E(MAC,"invalid IP address '%s', use a.b.c.d notation\n", server);
+    goto error;
+  }
+
+  temp = connect (ret->socket_fd, (struct sockaddr *) &servaddr, sizeof (servaddr));
+ 
+  if (temp == -1)
+  {
+      perror("connect()");
+      close(ret->socket_fd);
+      exit(1);
+  }
+
+  return ret;
+
+error:
+  if (ret != NULL) close(ret->socket_fd);
+  free(ret);
+  LOG_E(MAC, "ERROR in new_link_sctp_client (see above), returning NULL\n");
+  return NULL;
+}
+
+static int socket_udp_send(int socket_fd, void *buf, int size, const char *peer_addr, int port)
+{
+  struct sockaddr_in si_other;
+  int slen = sizeof(si_other);
+  int l;
+  int my_socket;
+  
+  LOG_D(PROTO_AGENT,"UDP send\n");
+
+  my_socket = socket_fd;
+  memset((char *) &si_other, 0, sizeof(si_other));
+  si_other.sin_family = AF_INET;
+  si_other.sin_port = htons(port);
+     
+  if (inet_aton(peer_addr , &si_other.sin_addr) == 0) 
+  {
+      fprintf(stderr, "inet_aton() failed\n");
+      exit(1);
+  }
+
+  l = sendto(my_socket, buf, size, 0, (struct sockaddr *) &si_other, slen);
+  if (l == -1) goto error;
+  
+  return l;
+error:
+  LOG_E(MAC,"socket_udp_send: ERROR: %s\n", strerror(errno));
+  return -1;
+}
+
+static int socket_udp_receive(int socket_fd, void *buf, int size)
+{
+  LOG_D(PROTO_AGENT,"UDP RECEIVE\n");
+
+  struct sockaddr_in client;
+  socklen_t slen;
+  int   l;
+
+  l = recvfrom(socket_fd, buf, size, 0, (struct sockaddr *) &client, &slen);
+  //getsockname(socket_fd, (struct sockaddr *)&client, &slen);
+  if (l == -1) goto error;
+  if (l == 0) goto socket_closed;
+
+  return l;
+
+error:
+  LOG_E(MAC, "socket_udp_receive: ERROR: %s\n", strerror(errno));
+  return -1;
+
+socket_closed:
+  LOG_E(MAC, "socket_udp_receive: socket closed\n");
+  return -1;
+}
+
+
 /*
  * return -1 on error and 0 if the sending was fine
  */
@@ -213,63 +475,92 @@ socket_closed:
 /*
  * return -1 on error and 0 if the sending was fine
  */
-int link_send_packet(socket_link_t *link, void *data, int size)
+int link_send_packet(socket_link_t *link, void *data, int size, const char *peer_addr, int peer_port)
 {
   char sizebuf[4];
   int32_t s = size;
-
-  /* send the size first, maximum is 2^31 bytes */
-  sizebuf[0] = (s >> 24) & 255;
-  sizebuf[1] = (s >> 16) & 255;
-  sizebuf[2] = (s >> 8) & 255;
-  sizebuf[3] = s & 255;
-
-  if (socket_send(link->socket_fd, sizebuf, 4) == -1)
-    goto error;
-
-  link->bytes_sent += 4;
-
-  if (socket_send(link->socket_fd, data, size) == -1)
-    goto error;
+  switch (link->type) {
+  case SOCK_STREAM:
+    /* send the size first, maximum is 2^31 bytes */
+    sizebuf[0] = (s >> 24) & 255;
+    sizebuf[1] = (s >> 16) & 255;
+    sizebuf[2] = (s >> 8) & 255;
+    sizebuf[3] = s & 255;
+    if (socket_send(link->socket_fd, sizebuf, 4) == -1)
+      return -1;
+
+    link->bytes_sent += 4;
+
+    if (socket_send(link->socket_fd, data, size) == -1)
+      return -1;
+    break;
+  case SOCK_DGRAM:
+    /* UDP is connectionless -> only send the data */
+    if (socket_udp_send(link->socket_fd, data, size, peer_addr, peer_port) == -1)
+      return -1;
+    break;
+  default:
+    LOG_E(MAC, "unknown socket type %d\n", link->type);
+    return -1;
+  }
 
   link->bytes_sent += size;
   link->packets_sent++;
 
   return 0;
-
-error:
-  return -1;
 }
 
 /*
  * return -1 on error and 0 if the sending was fine
  */
+
 int link_receive_packet(socket_link_t *link, void **ret_data, int *ret_size)
 {
   unsigned char sizebuf[4];
-  int32_t       size;
+  int32_t       size = 0;
   void          *data = NULL;
-
+  
   /* received the size first, maximum is 2^31 bytes */
-  if (socket_receive(link->socket_fd, sizebuf, 4) == -1)
-    goto error;
-
-  size = (sizebuf[0] << 24) |
-         (sizebuf[1] << 16) |
-         (sizebuf[2] << 8)  |
-          sizebuf[3];
-
-  link->bytes_received += 4;
-
-  data = malloc(size);
-  if (data == NULL) {
-    LOG_E(MAC, "%s:%d: out of memory\n", __FILE__, __LINE__);
+  switch (link->type) {
+  case SOCK_STREAM:
+    if (socket_receive(link->socket_fd, sizebuf, 4) == -1)
+      goto error;
+
+    size = (sizebuf[0] << 24) |
+           (sizebuf[1] << 16) |
+           (sizebuf[2] << 8)  |
+            sizebuf[3];
+
+    link->bytes_received += 4;
+
+    data = malloc(size);
+    if (data == NULL) {
+      LOG_E(MAC, "%s:%d: out of memory\n", __FILE__, __LINE__);
+      goto error;
+    }
+
+    if (socket_receive(link->socket_fd, data, size) == -1)
+      goto error;
+    break;
+  case SOCK_DGRAM:
+    /* we get a single packet (no size, UDP could lose it). Therefore, prepare
+     * for the maximum UDP packet size */
+    size = 65535;
+    data = malloc(size);
+    if (data == NULL) {
+      LOG_E(MAC, "%s:%d: out of memory\n", __FILE__, __LINE__);
+      goto error;
+    }
+
+    size = socket_udp_receive(link->socket_fd, data, size);
+    if (size < 0)
+      goto error;
+    break;
+  default:
+    LOG_E(MAC, "unknown socket type %d\n", link->type);
     goto error;
   }
 
-  if (socket_receive(link->socket_fd, data, size) == -1)
-    goto error;
-
   link->bytes_received += size;
   link->packets_received++;
 
@@ -313,8 +604,8 @@ int main(void)
    */
   sleep(1);
   printf("... done\n");
-  if (link_send_packet(l, "hello\n", 6+1) ||
-      link_send_packet(l, "world\n", 6+1)) return 1;
+  if (link_send_packet(l, "hello\n", 6+1, NULL, 0) ||
+      link_send_packet(l, "world\n", 6+1, NULL, 0)) return 1;
   if (link_receive_packet(l, &data, &size)) return 1; printf("%s", (char *)data); free(data);
   if (link_receive_packet(l, &data, &size)) return 1; printf("%s", (char *)data); free(data);
   printf("stats:\n");
@@ -342,8 +633,8 @@ int main(void)
   printf("link is up\n");
   if (link_receive_packet(l, &data, &size)) return 1; printf("%s", (char *)data); free(data);
   if (link_receive_packet(l, &data, &size)) return 1; printf("%s", (char *)data); free(data);
-  if (link_send_packet(l, "bye\n", 4+1) ||
-      link_send_packet(l, "server\n", 7+1)) return 1;
+  if (link_send_packet(l, "bye\n", 4+1, NULL, 0) ||
+      link_send_packet(l, "server\n", 7+1, NULL, 0)) return 1;
   printf("stats:\n");
   printf("    sent packets %"PRIu64"\n", l->packets_sent);
   printf("    sent bytes %"PRIu64"\n", l->bytes_sent);
diff --git a/openair2/UTIL/ASYNC_IF/socket_link.h b/openair2/UTIL/ASYNC_IF/socket_link.h
index dbe0a6937055e53c16e7a3bedcfecc8772c0cc79..b466721e084953fd24c5cc577a35fe3f3cbcb048 100644
--- a/openair2/UTIL/ASYNC_IF/socket_link.h
+++ b/openair2/UTIL/ASYNC_IF/socket_link.h
@@ -37,8 +37,10 @@
 extern "C" {
 #endif
 
+
 typedef struct {
   int      socket_fd;
+  int      type;
   uint64_t bytes_sent;
   uint64_t packets_sent;
   uint64_t bytes_received;
@@ -46,11 +48,17 @@ typedef struct {
 } socket_link_t;
 
 socket_link_t *new_link_server(int port);
-socket_link_t *new_link_client(char *server, int port);
-int link_send_packet(socket_link_t *link, void *data, int size);
+socket_link_t *new_link_client(const char *server, int port);
+/* setting bind_addr to NULL binds server to INADDR_ANY */
+socket_link_t *new_link_udp_server(const char *bind_addr, int bind_port);
+socket_link_t *new_link_udp_client(const char *server, int port);
+socket_link_t *new_link_sctp_server(int port);
+socket_link_t *new_link_sctp_client(const char *server, int port);
+int link_send_packet(socket_link_t *link, void *data, int size, const char *peer_addr, int port);
 int link_receive_packet(socket_link_t *link, void **data, int *size);
 int close_link(socket_link_t *link);
 
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_ringbuffer/lfds700_ringbuffer_cleanup.c b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_ringbuffer/lfds700_ringbuffer_cleanup.c
index 8ab44e46b5d52040062926c2a5ea93a72b3e2387..11852859e860144c33c7460c07ec2345cd9770f2 100644
--- a/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_ringbuffer/lfds700_ringbuffer_cleanup.c
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_ringbuffer/lfds700_ringbuffer_cleanup.c
@@ -31,8 +31,6 @@ void lfds700_ringbuffer_cleanup( struct lfds700_ringbuffer_state *rs,
 
 
 /****************************************************************************/
-//#pragma warning( disable : 4100 )
-
 static void lfds700_ringbuffer_internal_queue_element_cleanup_callback( struct lfds700_queue_state *qs, struct lfds700_queue_element *qe, enum lfds700_misc_flag dummy_element_flag )
 {
   struct lfds700_ringbuffer_element
@@ -57,9 +55,6 @@ static void lfds700_ringbuffer_internal_queue_element_cleanup_callback( struct l
 //#pragma warning( default : 4100 )
 
 
-
-
-
 /****************************************************************************/
 //#pragma warning( disable : 4100 )
 
diff --git a/openair2/UTIL/LISTS/list.h b/openair2/UTIL/LISTS/list.h
index 818df2be26d0c74c4e862ceaf660fd6be8708929..b88c581deab6ecb65ee6c0e251d4abbf034184cf 100644
--- a/openair2/UTIL/LISTS/list.h
+++ b/openair2/UTIL/LISTS/list.h
@@ -112,9 +112,9 @@ typedef struct {
   size_t atomSize;
   size_t increment;
 } varArray_t;
- 
+
 static inline varArray_t * initVarArray(size_t increment, size_t atomSize) {
-    varArray_t * tmp=malloc(sizeof(varArray_t)+increment*atomSize);
+    varArray_t * tmp=(varArray_t *)malloc(sizeof(varArray_t)+increment*atomSize);
     tmp->size=0;
     tmp->atomSize=atomSize;
     tmp->mallocedSize=increment;
@@ -129,7 +129,7 @@ static inline void * dataArray(varArray_t * input) {
 static inline void appendVarArray(varArray_t * input, void* data) {
   if (input->size>=input->mallocedSize) {
      input->mallocedSize+=input->increment;
-     input=realloc(input,sizeof(varArray_t)+input->mallocedSize*input->atomSize);
+     input=(varArray_t *)realloc(input,sizeof(varArray_t)+input->mallocedSize*input->atomSize);
   }
   memcpy((uint8_t*)(input+1)+input->atomSize*input->size++, data, input->atomSize);
 }
diff --git a/openair2/UTIL/LOG/log.c b/openair2/UTIL/LOG/log.c
new file mode 100644
index 0000000000000000000000000000000000000000..faff4fcfb964de838392eee955903ed614322681
--- /dev/null
+++ b/openair2/UTIL/LOG/log.c
@@ -0,0 +1,1832 @@
+/*
+ * 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
+ */
+
+/*! \file log.c
+* \brief log implementaion
+* \author Navid Nikaein
+* \date 2009 - 2014
+* \version 0.5
+* @ingroup util
+
+*/
+
+#define _GNU_SOURCE  /* required for pthread_getname_np */
+//#define LOG_TEST 1
+
+#define COMPONENT_LOG
+#define COMPONENT_LOG_IF
+#include <ctype.h>
+#define LOG_MAIN
+#include "log.h"
+#include "vcd_signal_dumper.h"
+#include "assertions.h"
+
+#if defined(ENABLE_ITTI)
+# include "intertask_interface.h"
+#endif
+
+# include <pthread.h>
+# include <string.h>
+#include "common/config/config_userapi.h"
+// main log variables
+
+
+mapping log_level_names[] = {
+  {"emerg", LOG_EMERG},
+  {"alert", LOG_ALERT},
+  {"crit", LOG_CRIT},
+  {"error", LOG_ERR},
+  {"warn", LOG_WARNING},
+  {"notice", LOG_NOTICE},
+  {"info", LOG_INFO},
+  {"debug", LOG_DEBUG},
+  {"file", LOG_FILE},
+  {"trace", LOG_TRACE},
+  {NULL, -1}
+};
+mapping log_verbosity_names[] = {
+  {"none", 0x0},
+  {"low", 0x5},
+  {"medium", 0x15},
+  {"high", 0x35},
+  {"full", 0x75},
+  {NULL, -1}
+};
+
+// vars for the log thread
+LOG_params log_list[2000];
+int log_list_tail = 0;
+int log_list_nb_elements = 0;
+
+pthread_mutex_t log_lock;
+pthread_cond_t log_notify;
+
+
+#if !defined(LOG_NO_THREAD)
+int log_list_head = 0;
+int log_shutdown;
+#endif
+
+static int gfd;
+
+static char *log_level_highlight_start[] = {LOG_RED, LOG_RED, LOG_RED, LOG_RED, LOG_ORANGE, LOG_BLUE, "", ""};  /*!< \brief Optional start-format strings for highlighting */
+static char *log_level_highlight_end[]   = {LOG_RESET, LOG_RESET, LOG_RESET, LOG_RESET, LOG_RESET,LOG_RESET,  "",""};   /*!< \brief Optional end-format strings for highlighting */
+
+#if defined(ENABLE_ITTI)
+static log_instance_type_t log_instance_type;
+#endif
+
+/* get log parameters from configuration file */
+void  log_getconfig(log_t *g_log) {
+  char *gloglevel = NULL;
+  char *glogverbo = NULL;
+  int level,verbosity;
+  paramdef_t logparams_defaults[] = LOG_GLOBALPARAMS_DESC;
+  paramdef_t logparams_level[MAX_LOG_COMPONENTS];
+  paramdef_t logparams_verbosity[MAX_LOG_COMPONENTS];
+  paramdef_t logparams_logfile[MAX_LOG_COMPONENTS];
+  
+  int ret = config_get( logparams_defaults,sizeof(logparams_defaults)/sizeof(paramdef_t),CONFIG_STRING_LOG_PREFIX);
+  if (ret <0) {
+       fprintf(stderr,"[LOG] init aborted, configuration couldn't be performed");
+       return;
+  } 
+  memset(logparams_level,    0, sizeof(paramdef_t)*MAX_LOG_COMPONENTS);
+  memset(logparams_verbosity,0, sizeof(paramdef_t)*MAX_LOG_COMPONENTS);
+  memset(logparams_logfile,  0, sizeof(paramdef_t)*MAX_LOG_COMPONENTS);
+  for (int i=MIN_LOG_COMPONENTS; i < MAX_LOG_COMPONENTS; i++) {
+    if(g_log->log_component[i].name == NULL) {
+       g_log->log_component[i].name = malloc(16);
+       sprintf((char *)g_log->log_component[i].name,"comp%i?",i);
+       logparams_logfile[i].paramflags = PARAMFLAG_DONOTREAD;
+       logparams_level[i].paramflags = PARAMFLAG_DONOTREAD;
+       logparams_verbosity[i].paramflags = PARAMFLAG_DONOTREAD;
+    }
+    sprintf(logparams_level[i].optname,    LOG_CONFIG_LEVEL_FORMAT,       g_log->log_component[i].name);
+    sprintf(logparams_verbosity[i].optname,LOG_CONFIG_VERBOSITY_FORMAT,   g_log->log_component[i].name);
+    sprintf(logparams_logfile[i].optname,  LOG_CONFIG_LOGFILE_FORMAT,     g_log->log_component[i].name);
+/* workaround: all log options in existing configuration files use lower case component names
+   where component names include uppercase char in log.h....                                */ 
+    for (int j=0 ; j<strlen(logparams_level[i].optname); j++) 
+          logparams_level[i].optname[j] = tolower(logparams_level[i].optname[j]);
+    for (int j=0 ; j<strlen(logparams_level[i].optname); j++) 
+          logparams_verbosity[i].optname[j] = tolower(logparams_verbosity[i].optname[j]);
+    for (int j=0 ; j<strlen(logparams_level[i].optname); j++) 
+          logparams_logfile[i].optname[j] = tolower(logparams_logfile[i].optname[j]);
+/* */
+    logparams_level[i].defstrval     = gloglevel;
+    logparams_verbosity[i].defstrval = glogverbo; 
+
+    logparams_level[i].type          = TYPE_STRING;
+    logparams_verbosity[i].type      = TYPE_STRING;
+    logparams_logfile[i].type        = TYPE_UINT;
+
+    logparams_logfile[i].paramflags  = logparams_logfile[i].paramflags|PARAMFLAG_BOOL;
+    }
+  config_get( logparams_level,    MAX_LOG_COMPONENTS,CONFIG_STRING_LOG_PREFIX); 
+  config_get( logparams_verbosity,MAX_LOG_COMPONENTS,CONFIG_STRING_LOG_PREFIX); 
+  config_get( logparams_logfile,  MAX_LOG_COMPONENTS,CONFIG_STRING_LOG_PREFIX); 
+  for (int i=MIN_LOG_COMPONENTS; i < MAX_LOG_COMPONENTS; i++) {
+    verbosity = map_str_to_int(log_verbosity_names,*(logparams_verbosity[i].strptr));
+    level     = map_str_to_int(log_level_names,    *(logparams_level[i].strptr));
+    set_comp_log(i, level,verbosity,1);
+    set_component_filelog(*(logparams_logfile[i].uptr));
+    }
+}
+
+
+int logInit (void)
+{
+  int i;
+  g_log = calloc(1, sizeof(log_t));
+
+  if (g_log == NULL) {
+    perror ("cannot allocated memory for log generation module \n");
+    exit(EXIT_FAILURE);
+  }
+
+
+#if ! defined(CN_BUILD)
+  g_log->log_component[PHY].name = "PHY";
+  g_log->log_component[PHY].level = LOG_EMERG;
+  g_log->log_component[PHY].flag =  LOG_MED;
+  g_log->log_component[PHY].interval =  1;
+  g_log->log_component[PHY].fd = 0;
+  g_log->log_component[PHY].filelog = 0;
+  g_log->log_component[PHY].filelog_name = "/tmp/phy.log";
+
+  g_log->log_component[MAC].name = "MAC";
+  g_log->log_component[MAC].level = LOG_EMERG;
+  g_log->log_component[MAC].flag =  LOG_MED;
+  g_log->log_component[MAC].interval =  1;
+  g_log->log_component[MAC].fd = 0;
+  g_log->log_component[MAC].filelog = 0;
+  g_log->log_component[MAC].filelog_name = "/tmp/mac.log";
+
+  g_log->log_component[OPT].name = "OPT";
+  g_log->log_component[OPT].level = LOG_EMERG;
+  g_log->log_component[OPT].flag = LOG_MED;
+  g_log->log_component[OPT].interval =  1;
+  g_log->log_component[OPT].fd = 0;
+  g_log->log_component[OPT].filelog = 0;
+  g_log->log_component[OPT].filelog_name = "";
+
+  g_log->log_component[RLC].name = "RLC";
+  g_log->log_component[RLC].level = LOG_INFO;
+  g_log->log_component[RLC].flag = LOG_MED;
+  g_log->log_component[RLC].interval =  1;
+  g_log->log_component[RLC].fd = 0;
+  g_log->log_component[RLC].filelog = 0;
+  g_log->log_component[RLC].filelog_name = "/tmp/rlc.log";
+
+  g_log->log_component[PDCP].name = "PDCP";
+  g_log->log_component[PDCP].level = LOG_INFO;
+  g_log->log_component[PDCP].flag = LOG_MED;
+  g_log->log_component[PDCP].interval =  1;
+  g_log->log_component[PDCP].fd = 0;
+  g_log->log_component[PDCP].filelog = 0;
+  g_log->log_component[PDCP].filelog_name = "/tmp/pdcp.log";
+
+  g_log->log_component[RRC].name = "RRC";
+  g_log->log_component[RRC].level = LOG_TRACE;
+  g_log->log_component[RRC].flag = LOG_MED;
+  g_log->log_component[RRC].interval =  1;
+  g_log->log_component[RRC].fd = 0;
+  g_log->log_component[RRC].filelog = 0;
+  g_log->log_component[RRC].filelog_name = "/tmp/rrc.log";
+
+  g_log->log_component[EMU].name = "EMU";
+  g_log->log_component[EMU].level = LOG_EMERG;
+  g_log->log_component[EMU].flag =  LOG_MED;
+  g_log->log_component[EMU].interval =  1;
+  g_log->log_component[EMU].fd = 0;
+  g_log->log_component[EMU].filelog = 0;
+  g_log->log_component[EMU].filelog_name = "";
+
+  g_log->log_component[OMG].name = "OMG";
+  g_log->log_component[OMG].level = LOG_EMERG;
+  g_log->log_component[OMG].flag =  LOG_MED;
+  g_log->log_component[OMG].interval =  1;
+  g_log->log_component[OMG].fd = 0;
+  g_log->log_component[OMG].filelog = 0;
+  g_log->log_component[OMG].filelog_name = "/tmp/omg.csv";
+
+  g_log->log_component[OTG].name = "OTG";
+  g_log->log_component[OTG].level = LOG_EMERG;
+  g_log->log_component[OTG].flag =  LOG_MED;
+  g_log->log_component[OTG].interval =  1;
+  g_log->log_component[OTG].fd = 0;
+  g_log->log_component[OTG].filelog = 0;
+  g_log->log_component[OTG].filelog_name = "/tmp/otg.log";
+
+  g_log->log_component[OTG_LATENCY].name = "OTG_LATENCY";
+  g_log->log_component[OTG_LATENCY].level = LOG_EMERG;
+  g_log->log_component[OTG_LATENCY].flag =  LOG_MED;
+  g_log->log_component[OTG_LATENCY].interval =  1;
+  g_log->log_component[OTG_LATENCY].fd = 0;
+  g_log->log_component[OTG_LATENCY].filelog = 0;
+  g_log->log_component[OTG_LATENCY].filelog_name = "/tmp/otg_latency.dat";
+
+  g_log->log_component[OTG_LATENCY_BG].name = "OTG_LATENCY_BG";
+  g_log->log_component[OTG_LATENCY_BG].level = LOG_EMERG;
+  g_log->log_component[OTG_LATENCY_BG].flag =  LOG_MED;
+  g_log->log_component[OTG_LATENCY_BG].interval =  1;
+  g_log->log_component[OTG_LATENCY_BG].fd = 0;
+  g_log->log_component[OTG_LATENCY_BG].filelog = 0;
+  g_log->log_component[OTG_LATENCY_BG].filelog_name = "/tmp/otg_latency_bg.dat";
+
+  g_log->log_component[OTG_GP].name = "OTG_GP";
+  g_log->log_component[OTG_GP].level = LOG_EMERG;
+  g_log->log_component[OTG_GP].flag =  LOG_MED;
+  g_log->log_component[OTG_GP].interval =  1;
+  g_log->log_component[OTG_GP].fd = 0;
+  g_log->log_component[OTG_GP].filelog = 0;
+  g_log->log_component[OTG_GP].filelog_name = "/tmp/otg_goodput.dat";
+
+  g_log->log_component[OTG_GP_BG].name = "OTG_GP_BG";
+  g_log->log_component[OTG_GP_BG].level = LOG_EMERG;
+  g_log->log_component[OTG_GP_BG].flag =  LOG_MED;
+  g_log->log_component[OTG_GP_BG].interval =  1;
+  g_log->log_component[OTG_GP_BG].fd = 0;
+  g_log->log_component[OTG_GP_BG].filelog = 0;
+  g_log->log_component[OTG_GP_BG].filelog_name = "/tmp/otg_goodput_bg.dat";
+
+  g_log->log_component[OTG_JITTER].name = "OTG_JITTER";
+  g_log->log_component[OTG_JITTER].level = LOG_EMERG;
+  g_log->log_component[OTG_JITTER].flag =  LOG_MED;
+  g_log->log_component[OTG_JITTER].interval =  1;
+  g_log->log_component[OTG_JITTER].fd = 0;
+  g_log->log_component[OTG_JITTER].filelog = 0;
+  g_log->log_component[OTG_JITTER].filelog_name = "/tmp/otg_jitter.dat";
+
+  g_log->log_component[OCG].name = "OCG";
+  g_log->log_component[OCG].level = LOG_EMERG;
+  g_log->log_component[OCG].flag =  LOG_MED;
+  g_log->log_component[OCG].interval =  1;
+  g_log->log_component[OCG].fd = 0;
+  g_log->log_component[OCG].filelog = 0;
+  g_log->log_component[OCG].filelog_name = "";
+
+  g_log->log_component[PERF].name = "PERF";
+  g_log->log_component[PERF].level = LOG_EMERG;
+  g_log->log_component[PERF].flag =  LOG_MED;
+  g_log->log_component[PERF].interval =  1;
+  g_log->log_component[PERF].fd = 0;
+  g_log->log_component[PERF].filelog = 0;
+  g_log->log_component[PERF].filelog_name = "";
+
+  g_log->log_component[OIP].name = "OIP";
+  g_log->log_component[OIP].level = LOG_EMERG;
+  g_log->log_component[OIP].flag =  LOG_MED;
+  g_log->log_component[OIP].interval =  1;
+  g_log->log_component[OIP].fd = 0;
+  g_log->log_component[OIP].filelog = 0;
+  g_log->log_component[OIP].filelog_name = "";
+
+  g_log->log_component[CLI].name = "CLI";
+  g_log->log_component[CLI].level = LOG_EMERG;
+  g_log->log_component[CLI].flag =  LOG_MED;
+  g_log->log_component[CLI].interval =  1;
+  g_log->log_component[CLI].fd = 0;
+  g_log->log_component[CLI].filelog =  0;
+  g_log->log_component[CLI].filelog_name = "";
+
+  g_log->log_component[MSC].name = "MSC";
+  g_log->log_component[MSC].level = LOG_EMERG;
+  g_log->log_component[MSC].flag =  LOG_MED;
+  g_log->log_component[MSC].interval =  1;
+  g_log->log_component[MSC].fd = 0;
+  g_log->log_component[MSC].filelog =  0;
+  g_log->log_component[MSC].filelog_name = "/tmp/msc.log";
+
+  g_log->log_component[PROTO_AGENT].name = "PROTO_AGENT";
+  g_log->log_component[PROTO_AGENT].level = LOG_EMERG;
+  g_log->log_component[PROTO_AGENT].flag =  LOG_MED;
+  g_log->log_component[PROTO_AGENT].interval =  1;
+  g_log->log_component[PROTO_AGENT].fd = 0;
+  g_log->log_component[PROTO_AGENT].filelog =  0;
+  g_log->log_component[PROTO_AGENT].filelog_name = "/tmp/proto_agent.log";
+
+
+
+  g_log->log_component[PROTO_AGENT].name = "PROTO_AGENT";
+  g_log->log_component[PROTO_AGENT].level = LOG_EMERG;
+  g_log->log_component[PROTO_AGENT].flag =  LOG_MED;
+  g_log->log_component[PROTO_AGENT].interval =  1;
+  g_log->log_component[PROTO_AGENT].fd = 0;
+  g_log->log_component[PROTO_AGENT].filelog =  0;
+  g_log->log_component[PROTO_AGENT].filelog_name = "/tmp/proto_agent.log";
+
+  g_log->log_component[F1U].name = "F1U";
+  g_log->log_component[F1U].level = LOG_EMERG;
+  g_log->log_component[F1U].flag =  LOG_MED;
+  g_log->log_component[F1U].interval =  1;
+  g_log->log_component[F1U].fd = 0;
+  g_log->log_component[F1U].filelog =  0;
+  g_log->log_component[F1U].filelog_name = "/tmp/f1u.log";
+
+  g_log->log_component[OCM].name = "OCM";
+  g_log->log_component[OCM].level = LOG_EMERG;
+  g_log->log_component[OCM].flag =  LOG_MED;
+  g_log->log_component[OCM].interval =  1;
+  g_log->log_component[OCM].fd = 0;
+  g_log->log_component[OCM].filelog =  0;
+  g_log->log_component[OCM].filelog_name = "/tmp/ocm.log";
+
+  g_log->log_component[HW].name = "HW";
+  g_log->log_component[HW].level = LOG_EMERG;
+  g_log->log_component[HW].flag = LOG_MED;
+  g_log->log_component[HW].interval = 1;
+  g_log->log_component[HW].fd = 0;
+  g_log->log_component[HW].filelog = 0;
+  g_log->log_component[HW].filelog_name = "";
+
+  g_log->log_component[OSA].name = "OSA";
+  g_log->log_component[OSA].level = LOG_EMERG;
+  g_log->log_component[OSA].flag = LOG_MED;
+  g_log->log_component[OSA].interval = 1;
+  g_log->log_component[OSA].fd = 0;
+  g_log->log_component[OSA].filelog = 0;
+  g_log->log_component[OSA].filelog_name = "";
+
+  g_log->log_component[RAL_ENB].name = "eRAL";
+  g_log->log_component[RAL_ENB].level = LOG_EMERG;
+  g_log->log_component[RAL_ENB].flag = LOG_MED;
+  g_log->log_component[RAL_ENB].interval = 1;
+  g_log->log_component[RAL_ENB].fd = 0;
+  g_log->log_component[RAL_ENB].filelog = 0;
+  g_log->log_component[RAL_ENB].filelog_name = "";
+
+  g_log->log_component[RAL_UE].name = "mRAL";
+  g_log->log_component[RAL_UE].level = LOG_EMERG;
+  g_log->log_component[RAL_UE].flag = LOG_MED;
+  g_log->log_component[RAL_UE].interval = 1;
+  g_log->log_component[RAL_UE].fd = 0;
+  g_log->log_component[RAL_UE].filelog = 0;
+  g_log->log_component[RAL_UE].filelog_name = "";
+
+  g_log->log_component[ENB_APP].name = "ENB_APP";
+  g_log->log_component[ENB_APP].level = LOG_EMERG;
+  g_log->log_component[ENB_APP].flag = LOG_MED;
+  g_log->log_component[ENB_APP].interval = 1;
+  g_log->log_component[ENB_APP].fd = 0;
+  g_log->log_component[ENB_APP].filelog = 0;
+  g_log->log_component[ENB_APP].filelog_name = "";
+
+  g_log->log_component[FLEXRAN_AGENT].name = "FLEXRAN_AGENT";
+  g_log->log_component[FLEXRAN_AGENT].level = LOG_DEBUG;
+  g_log->log_component[FLEXRAN_AGENT].flag = LOG_MED;
+  g_log->log_component[FLEXRAN_AGENT].interval = 1;
+  g_log->log_component[FLEXRAN_AGENT].fd = 0;
+  g_log->log_component[FLEXRAN_AGENT].filelog = 0;
+  g_log->log_component[FLEXRAN_AGENT].filelog_name = "";
+  
+  g_log->log_component[TMR].name = "TMR";
+  g_log->log_component[TMR].level = LOG_EMERG;
+  g_log->log_component[TMR].flag = LOG_MED;
+  g_log->log_component[TMR].interval = 1;
+  g_log->log_component[TMR].fd = 0;
+  g_log->log_component[TMR].filelog = 0;
+  g_log->log_component[TMR].filelog_name = "";
+
+  g_log->log_component[USIM].name = "USIM";
+  g_log->log_component[USIM].level = LOG_DEBUG;
+  g_log->log_component[USIM].flag = LOG_NONE;
+  g_log->log_component[USIM].interval = 1;
+  g_log->log_component[USIM].fd = 0;
+  g_log->log_component[USIM].filelog = 0;
+  g_log->log_component[USIM].filelog_name = "/tmp/usim.txt";
+
+  /* following log component are used for the localization*/
+  g_log->log_component[LOCALIZE].name = "LOCALIZE";
+  g_log->log_component[LOCALIZE].level = LOG_EMERG;
+  g_log->log_component[LOCALIZE].flag =  LOG_MED;
+  g_log->log_component[LOCALIZE].interval =  1;
+  g_log->log_component[LOCALIZE].fd = 0;
+  g_log->log_component[LOCALIZE].filelog = 0;
+  g_log->log_component[LOCALIZE].filelog_name = "/tmp/localize.log";
+#endif // ! defined(CN_BUILD)
+
+  g_log->log_component[NAS].name = "NAS";
+  g_log->log_component[NAS].level = LOG_TRACE;
+  g_log->log_component[NAS].flag = LOG_MED;
+  g_log->log_component[NAS].interval =  1;
+  g_log->log_component[NAS].fd = 0;
+  g_log->log_component[NAS].filelog = 0;
+  g_log->log_component[NAS].filelog_name = "/tmp/nas.log";
+
+  g_log->log_component[UDP_].name = "UDP";
+  g_log->log_component[UDP_].level = LOG_EMERG;
+  g_log->log_component[UDP_].flag = LOG_FULL;
+  g_log->log_component[UDP_].interval = 1;
+  g_log->log_component[UDP_].fd = 0;
+  g_log->log_component[UDP_].filelog = 0;
+  g_log->log_component[UDP_].filelog_name = "";
+
+  g_log->log_component[GTPU].name = "GTPV1U";
+  g_log->log_component[GTPU].level = LOG_EMERG;
+  g_log->log_component[GTPU].flag = LOG_FULL;
+  g_log->log_component[GTPU].interval = 1;
+  g_log->log_component[GTPU].fd = 0;
+  g_log->log_component[GTPU].filelog = 0;
+  g_log->log_component[GTPU].filelog_name = "";
+
+  g_log->log_component[S1AP].name = "S1AP";
+  g_log->log_component[S1AP].level = LOG_EMERG;
+  g_log->log_component[S1AP].flag = LOG_FULL;
+  g_log->log_component[S1AP].interval = 1;
+  g_log->log_component[S1AP].fd = 0;
+  g_log->log_component[S1AP].filelog = 0;
+  g_log->log_component[S1AP].filelog_name = "";
+
+  g_log->log_component[SCTP].name = "SCTP";
+  g_log->log_component[SCTP].level = LOG_EMERG;
+  g_log->log_component[SCTP].flag = LOG_MED;
+  g_log->log_component[SCTP].interval = 1;
+  g_log->log_component[SCTP].fd = 0;
+  g_log->log_component[SCTP].filelog = 0;
+  g_log->log_component[SCTP].filelog_name = "";
+ 
+  g_log->log_component[RRH].name = "RRH";
+  g_log->log_component[RRH].level = LOG_EMERG;
+  g_log->log_component[RRH].flag = LOG_MED;
+  g_log->log_component[RRH].interval = 1;
+  g_log->log_component[RRH].fd = 0;
+  g_log->log_component[RRH].filelog = 0;
+  g_log->log_component[RRH].filelog_name = "";
+  
+  g_log->level2string[LOG_EMERG]         = "G"; //EMERG
+  g_log->level2string[LOG_ALERT]         = "A"; // ALERT
+  g_log->level2string[LOG_CRIT]          = "C"; // CRITIC
+  g_log->level2string[LOG_ERR]           = "E"; // ERROR
+  g_log->level2string[LOG_WARNING]       = "W"; // WARNING
+  g_log->level2string[LOG_NOTICE]        = "N"; // NOTICE
+  g_log->level2string[LOG_INFO]          = "I"; //INFO
+  g_log->level2string[LOG_DEBUG]         = "D"; // DEBUG
+  g_log->level2string[LOG_FILE]          = "F"; // file
+  g_log->level2string[LOG_TRACE]         = "T"; // TRACE
+
+  g_log->onlinelog = 1; //online log file
+  g_log->syslog = 0;
+  g_log->filelog   = 0;
+  g_log->level  = LOG_TRACE;
+  g_log->flag   = LOG_LOW;
+
+  g_log->config.remote_ip      = 0;
+  g_log->config.remote_level   = LOG_EMERG;
+  g_log->config.facility       = LOG_LOCAL7;
+  g_log->config.audit_ip       = 0;
+  g_log->config.audit_facility = LOG_LOCAL6;
+  g_log->config.format         = 0x00; // online debug inactive
+
+  g_log->filelog_name = "/tmp/openair.log";
+
+  if (g_log->syslog) {
+#if ! defined(CN_BUILD)
+    openlog(g_log->log_component[EMU].name, LOG_PID, g_log->config.facility);
+#endif // ! defined(CN_BUILD)
+  }
+  log_getconfig(g_log);
+  if (g_log->filelog) {
+    gfd = open(g_log->filelog_name, O_WRONLY | O_CREAT, 0666);
+  }
+
+  // could put a loop here to check for all comps
+  for (i=MIN_LOG_COMPONENTS; i < MAX_LOG_COMPONENTS; i++) {
+    if (g_log->log_component[i].filelog == 1 ) {
+      g_log->log_component[i].fd = open(g_log->log_component[i].filelog_name,
+                                        O_WRONLY | O_CREAT | O_APPEND, 0666);
+    }
+  }
+
+  printf("log init done\n");
+
+  return 0;
+}
+
+void nfapi_log(char *file, char *func, int line, int comp, int level, const char* format, va_list args)
+{
+  //logRecord_mt(file,func,line, pthread_self(), comp, level, format, ##args)
+  int len = 0;
+  log_component_t *c;
+  char *log_start;
+  char *log_end;
+  /* The main difference with the version above is the use of this local log_buffer.
+   * The other difference is the return value of snprintf which was not used
+   * correctly. It was not a big problem because in practice MAX_LOG_TOTAL is
+   * big enough so that the buffer is never full.
+   */
+  char log_buffer[MAX_LOG_TOTAL];
+
+  /* for no gcc warnings */
+  (void)log_start;
+  (void)log_end;
+
+  c = &g_log->log_component[comp];
+
+  // do not apply filtering for LOG_F
+  // only log messages which are enabled and are below the global log level and component's level threshold
+  if ((level != LOG_FILE) && ((level > c->level) || (level > g_log->level))) {
+    /* if ((level != LOG_FILE) &&
+          ((level > c->level) ||
+           (level > g_log->level) ||
+           ( c->level > g_log->level))) {
+    */
+    return;
+  }
+
+  //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_LOG_RECORD, VCD_FUNCTION_IN);
+
+  // adjust syslog level for TRACE messages
+  if (g_log->syslog) {
+    if (g_log->level > LOG_DEBUG) {
+      g_log->level = LOG_DEBUG;
+    }
+  }
+
+  // make sure that for log trace the extra info is only printed once, reset when the level changes
+  if ((level == LOG_FILE) || (c->flag == LOG_NONE) || (level == LOG_TRACE)) {
+    log_start = log_buffer;
+    len = vsnprintf(log_buffer, MAX_LOG_TOTAL, format, args);
+    if (len > MAX_LOG_TOTAL) len = MAX_LOG_TOTAL;
+    log_end = log_buffer + len;
+  } else {
+    if ( (g_log->flag & FLAG_COLOR) || (c->flag & FLAG_COLOR) ) {
+      len += snprintf(&log_buffer[len], MAX_LOG_TOTAL - len, "%s",
+                      log_level_highlight_start[level]);
+      if (len > MAX_LOG_TOTAL) len = MAX_LOG_TOTAL;
+    }
+
+    log_start = log_buffer + len;
+
+    if ( (g_log->flag & FLAG_COMP) || (c->flag & FLAG_COMP) ) {
+      len += snprintf(&log_buffer[len], MAX_LOG_TOTAL - len, "[%s]",
+                      g_log->log_component[comp].name);
+      if (len > MAX_LOG_TOTAL) len = MAX_LOG_TOTAL;
+    }
+
+    if ( (g_log->flag & FLAG_LEVEL) || (c->flag & FLAG_LEVEL) ) {
+      len += snprintf(&log_buffer[len], MAX_LOG_TOTAL - len, "[%s]",
+                      g_log->level2string[level]);
+      if (len > MAX_LOG_TOTAL) len = MAX_LOG_TOTAL;
+    }
+
+    if ( (g_log->flag & FLAG_THREAD) || (c->flag & FLAG_THREAD) ) {
+#     define THREAD_NAME_LEN 128
+      char threadname[THREAD_NAME_LEN];
+      if (pthread_getname_np(pthread_self(), threadname, THREAD_NAME_LEN) != 0)
+      {
+        perror("pthread_getname_np : ");
+      } else {
+        len += snprintf(&log_buffer[len], MAX_LOG_TOTAL - len, "[%s]", threadname);
+        if (len > MAX_LOG_TOTAL) len = MAX_LOG_TOTAL;
+      }
+#     undef THREAD_NAME_LEN
+    }
+
+    if ( (g_log->flag & FLAG_FUNCT) || (c->flag & FLAG_FUNCT) ) {
+      len += snprintf(&log_buffer[len], MAX_LOG_TOTAL - len, "[%s] ",
+                      func);
+      if (len > MAX_LOG_TOTAL) len = MAX_LOG_TOTAL;
+    }
+
+    if ( (g_log->flag & FLAG_FILE_LINE) || (c->flag & FLAG_FILE_LINE) ) {
+      len += snprintf(&log_buffer[len], MAX_LOG_TOTAL - len, "[%s:%d]",
+                      file, line);
+      if (len > MAX_LOG_TOTAL) len = MAX_LOG_TOTAL;
+    }
+
+    //len += snprintf(&log_buffer[len], MAX_LOG_TOTAL - len, "[%08lx]", thread_id);
+    //if (len > MAX_LOG_TOTAL) len = MAX_LOG_TOTAL;
+
+    len += vsnprintf(&log_buffer[len], MAX_LOG_TOTAL - len, format, args);
+    if (len > MAX_LOG_TOTAL) len = MAX_LOG_TOTAL;
+    log_end = log_buffer + len;
+
+    if ( (g_log->flag & FLAG_COLOR) || (c->flag & FLAG_COLOR) ) {
+      len += snprintf(&log_buffer[len], MAX_LOG_TOTAL - len, "%s",
+          log_level_highlight_end[level]);
+      if (len > MAX_LOG_TOTAL) len = MAX_LOG_TOTAL;
+    }
+  }
+
+  va_end(args);
+
+  // OAI printf compatibility
+  if ((g_log->onlinelog == 1) && (level != LOG_FILE))
+#ifdef RTAI
+    if (len > MAX_LOG_TOTAL) {
+      rt_printk ("[OPENAIR] FIFO_PRINTF WROTE OUTSIDE ITS MEMORY BOUNDARY : ERRORS WILL OCCUR\n");
+    }
+
+  if (len > 0) {
+    rtf_put (FIFO_PRINTF_NO, log_buffer, len);
+  }
+
+#else
+  fwrite(log_buffer, len, 1, stdout);
+#endif
+
+#ifndef RTAI
+
+  if (g_log->syslog) {
+    syslog(g_log->level, "%s", log_buffer);
+  }
+
+  if (g_log->filelog) {
+    if (write(gfd, log_buffer, len) < len) {
+      // TODO assert ?
+    }
+  }
+
+  if ((g_log->log_component[comp].filelog) && (level == LOG_FILE)) {
+    if (write(g_log->log_component[comp].fd, log_buffer, len) < len) {
+      // TODO assert ?
+    }
+  }
+
+#else
+
+  // online print messges
+  if ((g_log->log_component[comp].filelog) && (level == LOG_FILE)) {
+    printf(log_buffer);
+  }
+
+#endif
+
+#if defined(ENABLE_ITTI)
+
+  if (level <= LOG_DEBUG) {
+    task_id_t origin_task_id = TASK_UNKNOWN;
+    MessagesIds messages_id;
+    MessageDef *message_p;
+    size_t      message_string_size;
+    char       *message_msg_p;
+
+    message_string_size = log_end - log_start;
+
+#if !defined(DISABLE_ITTI_DETECT_SUB_TASK_ID)
+
+    /* Try to identify sub task ID from log information (comp, log_instance_type) */
+    switch (comp) {
+    case PHY:
+      switch (log_instance_type) {
+      case LOG_INSTANCE_ENB:
+        origin_task_id = TASK_PHY_ENB;
+        break;
+
+      case LOG_INSTANCE_UE:
+        origin_task_id = TASK_PHY_UE;
+        break;
+
+      default:
+        break;
+      }
+
+      break;
+
+    case MAC:
+      switch (log_instance_type) {
+      case LOG_INSTANCE_ENB:
+        origin_task_id = TASK_MAC_ENB;
+        break;
+
+      case LOG_INSTANCE_UE:
+        origin_task_id = TASK_MAC_UE;
+
+      default:
+        break;
+      }
+
+      break;
+
+    case RLC:
+      switch (log_instance_type) {
+      case LOG_INSTANCE_ENB:
+        origin_task_id = TASK_RLC_ENB;
+        break;
+
+      case LOG_INSTANCE_UE:
+        origin_task_id = TASK_RLC_UE;
+
+      default:
+        break;
+      }
+
+      break;
+
+    case PDCP:
+      switch (log_instance_type) {
+      case LOG_INSTANCE_ENB:
+        origin_task_id = TASK_PDCP_ENB;
+        break;
+
+      case LOG_INSTANCE_UE:
+        origin_task_id = TASK_PDCP_UE;
+
+      default:
+        break;
+      }
+
+      break;
+
+    default:
+      break;
+    }
+
+#endif
+
+    switch (level) {
+    case LOG_EMERG:
+    case LOG_ALERT:
+    case LOG_CRIT:
+    case LOG_ERR:
+      messages_id = ERROR_LOG;
+      break;
+
+    case LOG_WARNING:
+      messages_id = WARNING_LOG;
+      break;
+
+    case LOG_NOTICE:
+      messages_id = NOTICE_LOG;
+      break;
+
+    case LOG_INFO:
+      messages_id = INFO_LOG;
+      break;
+
+    default:
+      messages_id = DEBUG_LOG;
+      break;
+    }
+
+    message_p = itti_alloc_new_message_sized(origin_task_id, messages_id, message_string_size);
+
+    switch (level) {
+    case LOG_EMERG:
+    case LOG_ALERT:
+    case LOG_CRIT:
+    case LOG_ERR:
+      message_msg_p = (char *) &message_p->ittiMsg.error_log;
+      break;
+
+    case LOG_WARNING:
+      message_msg_p = (char *) &message_p->ittiMsg.warning_log;
+      break;
+
+    case LOG_NOTICE:
+      message_msg_p = (char *) &message_p->ittiMsg.notice_log;
+      break;
+
+    case LOG_INFO:
+      message_msg_p = (char *) &message_p->ittiMsg.info_log;
+      break;
+
+    default:
+      message_msg_p = (char *) &message_p->ittiMsg.debug_log;
+      break;
+    }
+
+    memcpy(message_msg_p, log_start, message_string_size);
+
+    itti_send_msg_to_task(TASK_UNKNOWN, INSTANCE_DEFAULT, message_p);
+  }
+
+#endif
+#if 0
+  LOG_params log_params;
+  int        len;
+
+  len = vsnprintf(log_params.l_buff_info, MAX_LOG_INFO-1, format, args);
+
+  //2 first parameters must be passed as 'const' to the thread function
+  log_params.file = strdup(file);
+  log_params.func = strdup(func);
+  log_params.line = line;
+  log_params.comp = PHY;//comp;
+  log_params.level = 6; // INFO - level;
+  log_params.format = format;
+  log_params.len = len;
+
+  if (pthread_mutex_lock(&log_lock) != 0) {
+    return;
+  }
+
+  log_list_tail++;
+  log_list[log_list_tail - 1] = log_params;
+
+  if (log_list_tail >= 1000) {
+    log_list_tail = 0;
+  }
+
+  if (log_list_nb_elements < 1000) {
+    log_list_nb_elements++;
+  }
+
+  if(pthread_cond_signal(&log_notify) != 0) {
+    pthread_mutex_unlock(&log_lock);
+    return;
+  }
+
+  if(pthread_mutex_unlock(&log_lock) != 0) {
+    return;
+  }
+
+#endif
+}
+
+//log record: add to a list
+void logRecord(const char *file, const char *func, int line,  int comp,
+               int level, const char *format, ...)
+{
+  va_list    args;
+  LOG_params log_params;
+  int        len;
+
+  va_start(args, format);
+  len = vsnprintf(log_params.l_buff_info, MAX_LOG_INFO-1, format, args);
+  va_end(args);
+
+  //2 first parameters must be passed as 'const' to the thread function
+  log_params.file = strdup(file);
+  log_params.func = strdup(func);
+  log_params.line = line;
+  log_params.comp = comp;
+  log_params.level = level;
+  log_params.format = format;
+  log_params.len = len;
+
+  if (pthread_mutex_lock(&log_lock) != 0) {
+    return;
+  }
+
+  log_list_tail++;
+  log_list[log_list_tail - 1] = log_params;
+
+  if (log_list_tail >= 1000) {
+    log_list_tail = 0;
+  }
+
+  if (log_list_nb_elements < 1000) {
+    log_list_nb_elements++;
+  }
+
+  if(pthread_cond_signal(&log_notify) != 0) {
+    pthread_mutex_unlock(&log_lock);
+    return;
+  }
+
+  if(pthread_mutex_unlock(&log_lock) != 0) {
+    return;
+  }
+
+  //log = malloc(sizeof(LOG_elt));
+  //log->next = NULL;
+  //log->log_params = log_params;
+  /* Add log task to queue */
+  //log_list_add_tail_eurecom(log, &log_list);
+
+}
+
+void logRecord_thread_safe(const char *file, const char *func,
+                           int line,  int comp, int level,
+                           int len, const char *params_string)
+{
+  log_component_t *c;
+  int total_len = 0;
+  char log_buffer[MAX_LOG_TOTAL];
+
+  c = &g_log->log_component[comp];
+
+  // do not apply filtering for LOG_F
+  // only log messages which are enabled and are below the global log level and component's level threshold
+  if ((level != LOG_FILE) && ((c->level > g_log->level) ||
+                              (level > c->level) || (level > g_log->level))) {
+    return;
+  }
+
+
+  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_LOG_RECORD,
+                                          VCD_FUNCTION_IN);
+
+  // adjust syslog level for TRACE messages
+  if (g_log->syslog) {
+    if (g_log->level > LOG_DEBUG) {
+      g_log->level = LOG_DEBUG;
+    }
+  }
+
+  // make sure that for log trace the extra info is only printed once, reset when the level changes
+  if ((level == LOG_FILE) ||  (c->flag == LOG_NONE)  || (level ==LOG_TRACE )) {
+    total_len = snprintf(&log_buffer[total_len], MAX_LOG_TOTAL - 1, "%s",
+                         params_string);
+  } else {
+    if ((g_log->flag & FLAG_COLOR) || (c->flag & FLAG_COLOR)) {
+      total_len += snprintf(&log_buffer[total_len], MAX_LOG_TOTAL - total_len, "%s",
+                            log_level_highlight_start[level]);
+    }
+
+    if ((g_log->flag & FLAG_COMP) || (c->flag & FLAG_COMP) ) {
+      total_len += snprintf(&log_buffer[total_len], MAX_LOG_TOTAL - total_len, "[%s]",
+                            g_log->log_component[comp].name);
+    }
+
+    if ((g_log->flag & FLAG_LEVEL) || (c->flag & FLAG_LEVEL)) {
+      total_len += snprintf(&log_buffer[total_len], MAX_LOG_TOTAL - total_len, "[%s]",
+                            g_log->level2string[level]);
+    }
+
+    if ((g_log->flag & FLAG_FUNCT) || (c->flag & FLAG_FUNCT)) {
+      total_len += snprintf(&log_buffer[total_len], MAX_LOG_TOTAL - total_len, "[%s] ",
+                            func);
+    }
+
+    if ((g_log->flag & FLAG_FILE_LINE) || (c->flag & FLAG_FILE_LINE) )  {
+      total_len += snprintf(&log_buffer[total_len], MAX_LOG_TOTAL - total_len, "[%s:%d]",
+                            file, line);
+    }
+
+    len += snprintf(&log_buffer[total_len], MAX_LOG_TOTAL - len, "%s",
+                    params_string);
+
+    if ((g_log->flag & FLAG_COLOR) || (c->flag & FLAG_COLOR)) {
+      total_len += snprintf(&log_buffer[total_len], MAX_LOG_TOTAL - total_len, "%s",
+                            log_level_highlight_end[level]);
+    }
+  }
+
+  // OAI printf compatibility
+  if ((g_log->onlinelog == 1) && (level != LOG_FILE)) {
+    fprintf(stdout, "%s", log_buffer);
+  }
+
+  if (g_log->syslog) {
+    syslog(g_log->level, "%s", log_buffer);
+  }
+
+  if (g_log->filelog) {
+    if (write(gfd, log_buffer, total_len) < total_len) {
+      // TODO assert ?
+    }
+  }
+
+  if ((g_log->log_component[comp].filelog) && (level == LOG_FILE)) {
+    if (write(g_log->log_component[comp].fd, log_buffer, total_len) < total_len) {
+      // TODO assert ?
+    }
+  }
+
+  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_LOG_RECORD,
+                                          VCD_FUNCTION_OUT);
+}
+
+#if !defined(LOG_NO_THREAD)
+void *log_thread_function(void *list)
+{
+
+  LOG_params log_params;
+
+  for(;;) {
+
+    //log_elt = NULL;
+
+    /* Lock must be taken to wait on conditional variable */
+    pthread_mutex_lock(&log_lock);
+
+    /* Wait on condition variable, check for spurious wakeups.
+       When returning from pthread_cond_wait(), we own the lock. */
+
+    // sleep
+    while((log_list_nb_elements == 0) && (log_shutdown == 0)) {
+      pthread_cond_wait(&log_notify, &log_lock);
+    }
+
+    // exit
+    if ((log_shutdown==1) && (log_list_nb_elements == 0)) {
+      break;
+    }
+
+    /* Grab our task */
+    //log_elt = log_list_remove_head(&log_list);
+    log_params = log_list[log_list_head];
+    log_list_head++;
+    log_list_nb_elements--;
+
+    if (log_list_head >= 1000) {
+      log_list_head = 0;
+    }
+
+
+    /* Unlock */
+    pthread_mutex_unlock(&log_lock);
+
+    /* Get to work */
+    logRecord_thread_safe(log_params.file,
+                          log_params.func,
+                          log_params.line,
+                          log_params.comp,
+                          log_params.level,
+                          log_params.len,
+                          log_params.l_buff_info);
+
+    //free(log_elt);
+  }
+}
+#endif
+
+#if 0
+/* This function does not work. When multiple threads call it at the same time
+ * for the same component, both threads end up using the same buffer.
+ * The output is the completely messed up/wrong.
+ * Kept in case the fix below is not correct or acceptable.
+ */
+//log record, format, and print:  executed in the main thread (mt)
+void logRecord_mt(const char *file, const char *func, int line, int comp,
+                  int level, const char *format, ...)
+{
+  int len = 0;
+  va_list args;
+  log_component_t *c;
+  char *log_start;
+  char *log_end;
+
+  /* for no gcc warnings */
+  (void)log_start;
+  (void)log_end;
+
+  c = &g_log->log_component[comp];
+
+  // do not apply filtering for LOG_F
+  // only log messages which are enabled and are below the global log level and component's level threshold
+  if ((level != LOG_FILE) && ((level > c->level) || (level > g_log->level))) {
+    /* if ((level != LOG_FILE) &&
+          ((level > c->level) ||
+           (level > g_log->level) ||
+           ( c->level > g_log->level))) {
+    */
+    return;
+  }
+
+  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_LOG_RECORD,
+                                          VCD_FUNCTION_IN);
+
+  va_start(args, format);
+
+  // adjust syslog level for TRACE messages
+  if (g_log->syslog) {
+    if (g_log->level > LOG_DEBUG) {
+      g_log->level = LOG_DEBUG;
+    }
+  }
+
+  // make sure that for log trace the extra info is only printed once, reset when the level changes
+  if ((level == LOG_FILE) || (c->flag == LOG_NONE) || (level == LOG_TRACE)) {
+    log_start = c->log_buffer;
+    len = vsnprintf(c->log_buffer, MAX_LOG_TOTAL-1, format, args);
+    log_end = c->log_buffer + len;
+  } else {
+    if ( (g_log->flag & FLAG_COLOR) || (c->flag & FLAG_COLOR) ) {
+      len += snprintf(&c->log_buffer[len], MAX_LOG_TOTAL - len, "%s",
+                      log_level_highlight_start[level]);
+    }
+
+    log_start = c->log_buffer + len;
+
+    if ( (g_log->flag & FLAG_COMP) || (c->flag & FLAG_COMP) ) {
+      len += snprintf(&c->log_buffer[len], MAX_LOG_TOTAL - len, "[%s]",
+                      g_log->log_component[comp].name);
+    }
+
+    if ( (g_log->flag & FLAG_LEVEL) || (c->flag & FLAG_LEVEL) ) {
+      len += snprintf(&c->log_buffer[len], MAX_LOG_TOTAL - len, "[%s]",
+                      g_log->level2string[level]);
+    }
+
+    if ( (g_log->flag & FLAG_FUNCT) || (c->flag & FLAG_FUNCT) ) {
+      len += snprintf(&c->log_buffer[len], MAX_LOG_TOTAL - len, "[%s] ",
+                      func);
+    }
+
+    if ( (g_log->flag & FLAG_FILE_LINE) || (c->flag & FLAG_FILE_LINE) ) {
+      len += snprintf(&c->log_buffer[len], MAX_LOG_TOTAL - len, "[%s:%d]",
+                      file, line);
+    }
+
+    len += vsnprintf(&c->log_buffer[len], MAX_LOG_TOTAL - len, format, args);
+    log_end = c->log_buffer + len;
+
+    if ( (g_log->flag & FLAG_COLOR) || (c->flag & FLAG_COLOR) ) {
+      len += snprintf(&c->log_buffer[len], MAX_LOG_TOTAL - len, "%s",
+                      log_level_highlight_end[level]);
+    }
+  }
+
+  va_end(args);
+
+  // OAI printf compatibility
+  if ((g_log->onlinelog == 1) && (level != LOG_FILE))
+    fwrite(c->log_buffer, len, 1, stdout);
+
+  if (g_log->syslog) {
+    syslog(g_log->level, "%s", c->log_buffer);
+  }
+
+  if (g_log->filelog) {
+    if (write(gfd, c->log_buffer, len) < len) {
+      // TODO assert ?
+    }
+  }
+
+  if ((g_log->log_component[comp].filelog) && (level == LOG_FILE)) {
+    if (write(g_log->log_component[comp].fd, c->log_buffer, len) < len) {
+      // TODO assert ?
+    }
+  }
+
+#if defined(ENABLE_ITTI)
+
+  if (level <= LOG_DEBUG) {
+    task_id_t origin_task_id = TASK_UNKNOWN;
+    MessagesIds messages_id;
+    MessageDef *message_p;
+    size_t      message_string_size;
+    char       *message_msg_p;
+
+    message_string_size = log_end - log_start;
+
+#if !defined(DISABLE_ITTI_DETECT_SUB_TASK_ID)
+
+    /* Try to identify sub task ID from log information (comp, log_instance_type) */
+    switch (comp) {
+    case PHY:
+      switch (log_instance_type) {
+      case LOG_INSTANCE_ENB:
+        origin_task_id = TASK_PHY_ENB;
+        break;
+
+      case LOG_INSTANCE_UE:
+        origin_task_id = TASK_PHY_UE;
+        break;
+
+      default:
+        break;
+      }
+
+      break;
+
+    case MAC:
+      switch (log_instance_type) {
+      case LOG_INSTANCE_ENB:
+        origin_task_id = TASK_MAC_ENB;
+        break;
+
+      case LOG_INSTANCE_UE:
+        origin_task_id = TASK_MAC_UE;
+
+      default:
+        break;
+      }
+
+      break;
+
+    case RLC:
+      switch (log_instance_type) {
+      case LOG_INSTANCE_ENB:
+        origin_task_id = TASK_RLC_ENB;
+        break;
+
+      case LOG_INSTANCE_UE:
+        origin_task_id = TASK_RLC_UE;
+
+      default:
+        break;
+      }
+
+      break;
+
+    case PDCP:
+      switch (log_instance_type) {
+      case LOG_INSTANCE_ENB:
+        origin_task_id = TASK_PDCP_ENB;
+        break;
+
+      case LOG_INSTANCE_UE:
+        origin_task_id = TASK_PDCP_UE;
+
+      default:
+        break;
+      }
+
+      break;
+
+    default:
+      break;
+    }
+
+#endif
+
+    switch (level) {
+    case LOG_EMERG:
+    case LOG_ALERT:
+    case LOG_CRIT:
+    case LOG_ERR:
+      messages_id = ERROR_LOG;
+      break;
+
+    case LOG_WARNING:
+      messages_id = WARNING_LOG;
+      break;
+
+    case LOG_NOTICE:
+      messages_id = NOTICE_LOG;
+      break;
+
+    case LOG_INFO:
+      messages_id = INFO_LOG;
+      break;
+
+    default:
+      messages_id = DEBUG_LOG;
+      break;
+    }
+
+    message_p = itti_alloc_new_message_sized(origin_task_id, messages_id, message_string_size);
+
+    switch (level) {
+    case LOG_EMERG:
+    case LOG_ALERT:
+    case LOG_CRIT:
+    case LOG_ERR:
+      message_msg_p = (char *) &message_p->ittiMsg.error_log;
+      break;
+
+    case LOG_WARNING:
+      message_msg_p = (char *) &message_p->ittiMsg.warning_log;
+      break;
+
+    case LOG_NOTICE:
+      message_msg_p = (char *) &message_p->ittiMsg.notice_log;
+      break;
+
+    case LOG_INFO:
+      message_msg_p = (char *) &message_p->ittiMsg.info_log;
+      break;
+
+    default:
+      message_msg_p = (char *) &message_p->ittiMsg.debug_log;
+      break;
+    }
+
+    memcpy(message_msg_p, log_start, message_string_size);
+
+    itti_send_msg_to_task(TASK_UNKNOWN, INSTANCE_DEFAULT, message_p);
+  }
+
+#endif
+
+  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_LOG_RECORD,
+                                          VCD_FUNCTION_OUT);
+}
+#endif /* #if 0 */
+
+//log record, format, and print:  executed in the main thread (mt)
+void logRecord_mt(const char *file, const char *func, int line, int comp,
+                  int level, const char *format, ...)
+{
+  int len = 0;
+  va_list args;
+  log_component_t *c;
+  char *log_start;
+  char *log_end;
+  /* The main difference with the version above is the use of this local log_buffer.
+   * The other difference is the return value of snprintf which was not used
+   * correctly. It was not a big problem because in practice MAX_LOG_TOTAL is
+   * big enough so that the buffer is never full.
+   */
+  char log_buffer[MAX_LOG_TOTAL];
+
+  /* for no gcc warnings */
+  (void)log_start;
+  (void)log_end;
+
+  c = &g_log->log_component[comp];
+
+  // do not apply filtering for LOG_F
+  // only log messages which are enabled and are below the global log level and component's level threshold
+  if ((level != LOG_FILE) && ((level > c->level) || (level > g_log->level))) {
+    /* if ((level != LOG_FILE) &&
+          ((level > c->level) ||
+           (level > g_log->level) ||
+           ( c->level > g_log->level))) {
+    */
+    return;
+  }
+
+  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_LOG_RECORD,
+                                          VCD_FUNCTION_IN);
+
+  va_start(args, format);
+
+  // adjust syslog level for TRACE messages
+  if (g_log->syslog) {
+    if (g_log->level > LOG_DEBUG) {
+      g_log->level = LOG_DEBUG;
+    }
+  }
+
+  // make sure that for log trace the extra info is only printed once, reset when the level changes
+  if ((level == LOG_FILE) || (c->flag == LOG_NONE) || (level == LOG_TRACE)) {
+    log_start = log_buffer;
+    len = vsnprintf(log_buffer, MAX_LOG_TOTAL, format, args);
+    if (len > MAX_LOG_TOTAL) len = MAX_LOG_TOTAL;
+    log_end = log_buffer + len;
+  } else {
+    if ( (g_log->flag & FLAG_COLOR) || (c->flag & FLAG_COLOR) ) {
+      len += snprintf(&log_buffer[len], MAX_LOG_TOTAL - len, "%s",
+                      log_level_highlight_start[level]);
+      if (len > MAX_LOG_TOTAL) len = MAX_LOG_TOTAL;
+    }
+
+    log_start = log_buffer + len;
+
+    if ( (g_log->flag & FLAG_COMP) || (c->flag & FLAG_COMP) ) {
+      len += snprintf(&log_buffer[len], MAX_LOG_TOTAL - len, "[%s]",
+                      g_log->log_component[comp].name);
+      if (len > MAX_LOG_TOTAL) len = MAX_LOG_TOTAL;
+    }
+
+    if ( (g_log->flag & FLAG_LEVEL) || (c->flag & FLAG_LEVEL) ) {
+      len += snprintf(&log_buffer[len], MAX_LOG_TOTAL - len, "[%s]",
+                      g_log->level2string[level]);
+      if (len > MAX_LOG_TOTAL) len = MAX_LOG_TOTAL;
+    }
+
+    if ( (g_log->flag & FLAG_THREAD) || (c->flag & FLAG_THREAD) ) {
+#     define THREAD_NAME_LEN 128
+      char threadname[THREAD_NAME_LEN];
+      if (pthread_getname_np(pthread_self(), threadname, THREAD_NAME_LEN) != 0)
+      {
+        perror("pthread_getname_np : ");
+      } else {
+        len += snprintf(&log_buffer[len], MAX_LOG_TOTAL - len, "[%s]", threadname);
+        if (len > MAX_LOG_TOTAL) len = MAX_LOG_TOTAL;
+      }
+#     undef THREAD_NAME_LEN
+    }
+
+    if ( (g_log->flag & FLAG_FUNCT) || (c->flag & FLAG_FUNCT) ) {
+      len += snprintf(&log_buffer[len], MAX_LOG_TOTAL - len, "[%s] ",
+                      func);
+      if (len > MAX_LOG_TOTAL) len = MAX_LOG_TOTAL;
+    }
+
+    if ( (g_log->flag & FLAG_FILE_LINE) || (c->flag & FLAG_FILE_LINE) ) {
+      len += snprintf(&log_buffer[len], MAX_LOG_TOTAL - len, "[%s:%d]",
+                      file, line);
+      if (len > MAX_LOG_TOTAL) len = MAX_LOG_TOTAL;
+    }
+
+    len += vsnprintf(&log_buffer[len], MAX_LOG_TOTAL - len, format, args);
+    if (len > MAX_LOG_TOTAL) len = MAX_LOG_TOTAL;
+    log_end = log_buffer + len;
+
+    if ( (g_log->flag & FLAG_COLOR) || (c->flag & FLAG_COLOR) ) {
+      len += snprintf(&log_buffer[len], MAX_LOG_TOTAL - len, "%s",
+                      log_level_highlight_end[level]);
+      if (len > MAX_LOG_TOTAL) len = MAX_LOG_TOTAL;
+    }
+  }
+
+  va_end(args);
+
+  // OAI printf compatibility
+  if ((g_log->onlinelog == 1) && (level != LOG_FILE))
+    fwrite(log_buffer, len, 1, stdout);
+
+  if (g_log->syslog) {
+    syslog(g_log->level, "%s", log_buffer);
+  }
+
+  if (g_log->filelog) {
+    if (write(gfd, log_buffer, len) < len) {
+      // TODO assert ?
+    }
+  }
+
+  if ((g_log->log_component[comp].filelog) && (level == LOG_FILE)) {
+    if (write(g_log->log_component[comp].fd, log_buffer, len) < len) {
+      // TODO assert ?
+    }
+  }
+
+#if defined(ENABLE_ITTI)
+
+  if (level <= LOG_DEBUG) {
+    task_id_t origin_task_id = TASK_UNKNOWN;
+    MessagesIds messages_id;
+    MessageDef *message_p;
+    size_t      message_string_size;
+    char       *message_msg_p;
+
+    message_string_size = log_end - log_start;
+
+#if !defined(DISABLE_ITTI_DETECT_SUB_TASK_ID)
+
+    /* Try to identify sub task ID from log information (comp, log_instance_type) */
+    switch (comp) {
+    case PHY:
+      switch (log_instance_type) {
+      case LOG_INSTANCE_ENB:
+        origin_task_id = TASK_PHY_ENB;
+        break;
+
+      case LOG_INSTANCE_UE:
+        origin_task_id = TASK_PHY_UE;
+        break;
+
+      default:
+        break;
+      }
+
+      break;
+
+    case MAC:
+      switch (log_instance_type) {
+      case LOG_INSTANCE_ENB:
+        origin_task_id = TASK_MAC_ENB;
+        break;
+
+      case LOG_INSTANCE_UE:
+        origin_task_id = TASK_MAC_UE;
+
+      default:
+        break;
+      }
+
+      break;
+
+    case RLC:
+      switch (log_instance_type) {
+      case LOG_INSTANCE_ENB:
+        origin_task_id = TASK_RLC_ENB;
+        break;
+
+      case LOG_INSTANCE_UE:
+        origin_task_id = TASK_RLC_UE;
+
+      default:
+        break;
+      }
+
+      break;
+
+    case PDCP:
+      switch (log_instance_type) {
+      case LOG_INSTANCE_ENB:
+        origin_task_id = TASK_PDCP_ENB;
+        break;
+
+      case LOG_INSTANCE_UE:
+        origin_task_id = TASK_PDCP_UE;
+
+      default:
+        break;
+      }
+
+      break;
+
+    default:
+      break;
+    }
+
+#endif
+
+    switch (level) {
+    case LOG_EMERG:
+    case LOG_ALERT:
+    case LOG_CRIT:
+    case LOG_ERR:
+      messages_id = ERROR_LOG;
+      break;
+
+    case LOG_WARNING:
+      messages_id = WARNING_LOG;
+      break;
+
+    case LOG_NOTICE:
+      messages_id = NOTICE_LOG;
+      break;
+
+    case LOG_INFO:
+      messages_id = INFO_LOG;
+      break;
+
+    default:
+      messages_id = DEBUG_LOG;
+      break;
+    }
+
+    message_p = itti_alloc_new_message_sized(origin_task_id, messages_id, message_string_size);
+
+    switch (level) {
+    case LOG_EMERG:
+    case LOG_ALERT:
+    case LOG_CRIT:
+    case LOG_ERR:
+      message_msg_p = (char *) &message_p->ittiMsg.error_log;
+      break;
+
+    case LOG_WARNING:
+      message_msg_p = (char *) &message_p->ittiMsg.warning_log;
+      break;
+
+    case LOG_NOTICE:
+      message_msg_p = (char *) &message_p->ittiMsg.notice_log;
+      break;
+
+    case LOG_INFO:
+      message_msg_p = (char *) &message_p->ittiMsg.info_log;
+      break;
+
+    default:
+      message_msg_p = (char *) &message_p->ittiMsg.debug_log;
+      break;
+    }
+
+    memcpy(message_msg_p, log_start, message_string_size);
+
+    itti_send_msg_to_task(TASK_UNKNOWN, INSTANCE_DEFAULT, message_p);
+  }
+
+#endif
+
+  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_LOG_RECORD,
+                                          VCD_FUNCTION_OUT);
+}
+
+int set_log(int component, int level, int interval)
+{
+  /* Checking parameters */
+  DevCheck((component >= MIN_LOG_COMPONENTS) && (component < MAX_LOG_COMPONENTS),
+           component, MIN_LOG_COMPONENTS, MAX_LOG_COMPONENTS);
+  DevCheck((level <= LOG_TRACE) && (level >= LOG_EMERG), level, LOG_TRACE,
+           LOG_EMERG);
+  DevCheck((interval >= 0) && (interval <= 0xFF), interval, 0, 0xFF);
+
+  g_log->log_component[component].level = level;
+
+  switch (level) {
+  case LOG_TRACE:
+    g_log->log_component[component].flag = LOG_MED ;
+    break;
+
+  case LOG_DEBUG:
+    g_log->log_component[component].flag = LOG_MED ;
+    break;
+
+  case LOG_INFO:
+    g_log->log_component[component].flag = LOG_LOW ;
+    break;
+
+  default:
+    g_log->log_component[component].flag = LOG_NONE ;
+    break;
+  }
+
+  g_log->log_component[component].interval = interval;
+
+  return 0;
+}
+
+int set_comp_log(int component, int level, int verbosity, int interval)
+{
+  /* Checking parameters */
+  DevCheck((component >= MIN_LOG_COMPONENTS) && (component < MAX_LOG_COMPONENTS),
+           component, MIN_LOG_COMPONENTS, MAX_LOG_COMPONENTS);
+  DevCheck((level <= LOG_TRACE) && (level >= LOG_EMERG), level, LOG_TRACE,
+           LOG_EMERG);
+  DevCheck((interval >= 0) && (interval <= 0xFF), interval, 0, 0xFF);
+
+#if 0
+  if ((verbosity == LOG_NONE) || (verbosity == LOG_LOW) ||
+      (verbosity == LOG_MED) || (verbosity == LOG_FULL) ||
+      (verbosity == LOG_HIGH)) {
+    g_log->log_component[component].flag = verbosity;
+  }
+#else
+  g_log->log_component[component].flag = verbosity;
+#endif
+
+  g_log->log_component[component].level = level;
+  g_log->log_component[component].interval = interval;
+
+  return 0;
+}
+
+void set_glog(int level, int verbosity)
+{
+  if( g_log->level >= 0) g_log->level = level;
+  if( g_log->flag >= 0)  g_log->flag = verbosity;
+}
+void set_glog_syslog(int enable)
+{
+  g_log->syslog = enable;
+}
+void set_glog_onlinelog(int enable)
+{
+  g_log->onlinelog = enable;
+}
+void set_glog_filelog(int enable)
+{
+  g_log->filelog = enable;
+}
+
+void set_component_filelog(int comp)
+{
+  if (g_log->log_component[comp].filelog ==  0) {
+    g_log->log_component[comp].filelog =  1;
+
+    if (g_log->log_component[comp].fd == 0) {
+      g_log->log_component[comp].fd = open(g_log->log_component[comp].filelog_name,
+                                           O_WRONLY | O_CREAT | O_TRUNC, 0666);
+    }
+  }
+}
+
+/*
+ * for the two functions below, the passed array must have a final entry
+ * with string value NULL
+ */
+/* map a string to an int. Takes a mapping array and a string as arg */
+int map_str_to_int(mapping *map, const char *str)
+{
+  while (1) {
+    if (map->name == NULL) {
+      return(-1);
+    }
+
+    if (!strcmp(map->name, str)) {
+      return(map->value);
+    }
+
+    map++;
+  }
+}
+
+/* map an int to a string. Takes a mapping array and a value */
+char *map_int_to_str(mapping *map, int val)
+{
+  while (1) {
+    if (map->name == NULL) {
+      return NULL;
+    }
+
+    if (map->value == val) {
+      return map->name;
+    }
+
+    map++;
+  }
+}
+
+int is_newline( char *str, int size)
+{
+  int i;
+
+  for (  i = 0; i < size; i++ ) {
+    if ( str[i] == '\n' ) {
+      return 1;
+    }
+  }
+
+  /* if we get all the way to here, there must not have been a newline! */
+  return 0;
+}
+
+void logClean (void)
+{
+  int i;
+
+  if (g_log->syslog) {
+    closelog();
+  }
+
+  if (g_log->filelog) {
+    close(gfd);
+  }
+
+  for (i=MIN_LOG_COMPONENTS; i < MAX_LOG_COMPONENTS; i++) {
+    if (g_log->log_component[i].filelog) {
+      close(g_log->log_component[i].fd);
+    }
+  }
+}
+
+#if defined(ENABLE_ITTI)
+void log_set_instance_type (log_instance_type_t instance)
+{
+  log_instance_type = instance;
+}
+#endif
+
+#ifdef LOG_TEST
+
+int main(int argc, char *argv[])
+{
+
+  logInit();
+
+  //set_log_syslog(1);
+  test_log();
+
+  return 1;
+}
+
+int test_log(void)
+{
+  LOG_ENTER(MAC); // because the default level is DEBUG
+  LOG_I(EMU, "1 Starting OAI logs version %s Build date: %s on %s\n",
+        BUILD_VERSION, BUILD_DATE, BUILD_HOST);
+  LOG_D(MAC, "1 debug  MAC \n");
+  LOG_N(MAC, "1 notice MAC \n");
+  LOG_W(MAC, "1 warning MAC \n");
+
+  set_comp_log(EMU, LOG_INFO, FLAG_ONLINE);
+  set_comp_log(MAC, LOG_WARNING, 0);
+
+  LOG_I(EMU, "2 Starting OAI logs version %s Build date: %s on %s\n",
+        BUILD_VERSION, BUILD_DATE, BUILD_HOST);
+  LOG_E(MAC, "2 emerge MAC\n");
+  LOG_D(MAC, "2 debug  MAC \n");
+  LOG_N(MAC, "2 notice MAC \n");
+  LOG_W(MAC, "2 warning MAC \n");
+  LOG_I(MAC, "2 info MAC \n");
+
+
+  set_comp_log(MAC, LOG_NOTICE, 1);
+
+  LOG_ENTER(MAC);
+  LOG_I(EMU, "3 Starting OAI logs version %s Build date: %s on %s\n",
+        BUILD_VERSION, BUILD_DATE, BUILD_HOST);
+  LOG_D(MAC, "3 debug  MAC \n");
+  LOG_N(MAC, "3 notice MAC \n");
+  LOG_W(MAC, "3 warning MAC \n");
+  LOG_I(MAC, "3 info MAC \n");
+
+  set_comp_log(MAC, LOG_DEBUG,1);
+  set_comp_log(EMU, LOG_DEBUG,1);
+
+  LOG_ENTER(MAC);
+  LOG_I(EMU, "4 Starting OAI logs version %s Build date: %s on %s\n",
+        BUILD_VERSION, BUILD_DATE, BUILD_HOST);
+  LOG_D(MAC, "4 debug  MAC \n");
+  LOG_N(MAC, "4 notice MAC \n");
+  LOG_W(MAC, "4 warning MAC \n");
+  LOG_I(MAC, "4 info MAC \n");
+
+
+  set_comp_log(MAC, LOG_DEBUG,0);
+  set_comp_log(EMU, LOG_DEBUG,0);
+
+  LOG_I(LOG, "5 Starting OAI logs version %s Build date: %s on %s\n",
+        BUILD_VERSION, BUILD_DATE, BUILD_HOST);
+  LOG_D(MAC, "5 debug  MAC \n");
+  LOG_N(MAC, "5 notice MAC \n");
+  LOG_W(MAC, "5 warning MAC \n");
+  LOG_I(MAC, "5 info MAC \n");
+
+
+  set_comp_log(MAC, LOG_TRACE,0X07F);
+  set_comp_log(EMU, LOG_TRACE,0X07F);
+
+  LOG_ENTER(MAC);
+  LOG_I(LOG, "6 Starting OAI logs version %s Build date: %s on %s\n",
+        BUILD_VERSION, BUILD_DATE, BUILD_HOST);
+  LOG_D(MAC, "6 debug  MAC \n");
+  LOG_N(MAC, "6 notice MAC \n");
+  LOG_W(MAC, "6 warning MAC \n");
+  LOG_I(MAC, "6 info MAC \n");
+  LOG_EXIT(MAC);
+
+  return 0;
+}
+#endif
diff --git a/openair2/UTIL/MEM/mem_block.h b/openair2/UTIL/MEM/mem_block.h
index 18ded1a5990da3297c9abde96dc8615443fe329c..4d8ed4e89bc9e881ca0a6a346a3f2d97f36e0b61 100644
--- a/openair2/UTIL/MEM/mem_block.h
+++ b/openair2/UTIL/MEM/mem_block.h
@@ -130,6 +130,8 @@ void        check_free_mem_block (mem_block_t * leP);
 #    define MEM_MNGT_MB12_BLOCK_SIZE    MEM_MNGT_MB0_BLOCK_SIZE*4096
 // 262144
 #    define MEM_MNGT_MB12_NB_BLOCKS     32 * MEM_SCALE
+//#    define MEM_MNGT_MB12_NB_BLOCKS     4096 * MEM_SCALE
+
 #    define MEM_MNGT_POOL_ID12          12
 
 
diff --git a/openair2/UTIL/OTG/otg_tx_socket.c b/openair2/UTIL/OTG/otg_tx_socket.c
index 83b8476e9f7baeddca6a57e0ead3c8e8e27ff906..073b9b6ddd83f1fb22579ffea539ca6a823f1e34 100644
--- a/openair2/UTIL/OTG/otg_tx_socket.c
+++ b/openair2/UTIL/OTG/otg_tx_socket.c
@@ -231,7 +231,7 @@ void client_socket_udp_ip4(int src, int dst, int state,int ctime) {
       //
 
       free(payload);
-      free(tx_buffer);      
+      free(tx_buffer);
     }
 
     if(udp_send == -1) {
diff --git a/openair2/X2AP/x2ap_eNB_decoder.h b/openair2/X2AP/x2ap_eNB_decoder.h
index 7919c785554aef8eeaa5c156225c9cdac5d155b4..e3fa8b44e88ad15393ea103b687efec6be5d7f32 100644
--- a/openair2/X2AP/x2ap_eNB_decoder.h
+++ b/openair2/X2AP/x2ap_eNB_decoder.h
@@ -33,4 +33,3 @@ int x2ap_eNB_decode_pdu(X2AP_X2AP_PDU_t *pdu, const uint8_t *const buffer, uint3
 __attribute__ ((warn_unused_result));
 
 #endif /* X2AP_ENB_DECODER_H_ */
-
diff --git a/openair2/X2AP/x2ap_eNB_defs.h b/openair2/X2AP/x2ap_eNB_defs.h
index cd6a7e1385690884b1565001ce53f7fb8de397a9..e1a8b506bcabeea022da333856c3b0a03626b481 100644
--- a/openair2/X2AP/x2ap_eNB_defs.h
+++ b/openair2/X2AP/x2ap_eNB_defs.h
@@ -44,22 +44,22 @@
 typedef enum {
   /* Disconnected state: initial state for any association. */
   X2AP_ENB_STATE_DISCONNECTED = 0x0,
-  
+
   /* State waiting for x2 Setup response message if the target eNB accepts or
    * X2 Setup failure if rejects the eNB.
    */
   X2AP_ENB_STATE_WAITING     = 0x1,
-  
+
   /* The eNB is successfully connected to another eNB. */
   X2AP_ENB_STATE_CONNECTED   = 0x2,
-  
+
   /* X2AP is ready, and the eNB is successfully connected to another eNB. */
   X2AP_ENB_STATE_READY             = 0x3,
 
   X2AP_ENB_STATE_OVERLOAD          = 0x4,
 
   X2AP_ENB_STATE_RESETTING         = 0x5,
-  
+
   /* Max number of states available */
   X2AP_ENB_STATE_MAX,
 } x2ap_eNB_state_t;
@@ -93,13 +93,13 @@ typedef struct x2ap_eNB_data_s {
 
   /* This is the optional name provided by the MME */
   char *eNB_name;
-  
-  /*  target eNB ID */ 
+
+  /*  target eNB ID */
   uint32_t eNB_id;
-  
+
   /* Current eNB load information (if any). */
   //x2ap_load_state_t overload_state;
-  
+
   /* Current eNB->eNB X2AP association state */
   x2ap_eNB_state_t state;
 
@@ -208,4 +208,3 @@ RB_PROTOTYPE(x2ap_eNB_map, x2ap_eNB_data_s, entry, x2ap_eNB_compare_assoc_id);
 
 
 #endif /* X2AP_ENB_DEFS_H_ */
-
diff --git a/openair2/X2AP/x2ap_eNB_generate_messages.h b/openair2/X2AP/x2ap_eNB_generate_messages.h
index 659966fff68810fe327915b0e4e7ec93d9601a45..1fcdf31f121e033f08e08b16e13af5bf044170e2 100644
--- a/openair2/X2AP/x2ap_eNB_generate_messages.h
+++ b/openair2/X2AP/x2ap_eNB_generate_messages.h
@@ -61,4 +61,3 @@ int x2ap_eNB_generate_x2_handover_cancel (x2ap_eNB_instance_t *instance_p, x2ap_
                                           x2ap_handover_cancel_cause_t cause);
 
 #endif /*  X2AP_ENB_GENERATE_MESSAGES_H_ */
-
diff --git a/openair2/X2AP/x2ap_eNB_handler.h b/openair2/X2AP/x2ap_eNB_handler.h
index 402212f62d78e453777d4bfa40d5fda7dbd0a741..65f411895fbb823a9c523826d06bdb15130821cb 100644
--- a/openair2/X2AP/x2ap_eNB_handler.h
+++ b/openair2/X2AP/x2ap_eNB_handler.h
@@ -37,4 +37,3 @@ int x2ap_eNB_handle_message(instance_t instance, uint32_t assoc_id, int32_t stre
                             const uint8_t * const data, const uint32_t data_length);
 
 #endif /* X2AP_ENB_HANDLERS_H_ */
-
diff --git a/openair2/X2AP/x2ap_eNB_itti_messaging.c b/openair2/X2AP/x2ap_eNB_itti_messaging.c
index 1896e3949c6adf86c9ae91a4f606b1a1b69583f8..7573d9be898a8bd0643b9e5ffa4be85c9052ae89 100644
--- a/openair2/X2AP/x2ap_eNB_itti_messaging.c
+++ b/openair2/X2AP/x2ap_eNB_itti_messaging.c
@@ -60,4 +60,3 @@ void x2ap_eNB_itti_send_sctp_close_association(instance_t instance, int32_t asso
 
   itti_send_msg_to_task(TASK_SCTP, instance, message_p);
 }
-
diff --git a/openair2/X2AP/x2ap_eNB_management_procedures.c b/openair2/X2AP/x2ap_eNB_management_procedures.c
index 137bad40add81872cb8641270131f0f0f97cb345..986ca10902ba678c30a1578c95a1aa0881dfd309 100644
--- a/openair2/X2AP/x2ap_eNB_management_procedures.c
+++ b/openair2/X2AP/x2ap_eNB_management_procedures.c
@@ -45,7 +45,7 @@
 #  define X2AP_eNB_LIST_OUT(x, args...) X2AP_DEBUG("[eNB]%*s"x"\n", 4*indent, "", ##args)
 #else
 #  define X2AP_eNB_LIST_OUT(x, args...)
-#endif 
+#endif
 
 static int                  indent = 0;
 
@@ -123,7 +123,7 @@ printf("---------------------------------------------\n");
 }
 
 struct x2ap_eNB_data_s *x2ap_get_eNB(x2ap_eNB_instance_t *instance_p,
-				     int32_t assoc_id, 
+				     int32_t assoc_id,
 				     uint16_t cnx_id)
 {
   struct x2ap_eNB_data_s  temp;
@@ -169,7 +169,7 @@ x2ap_eNB_instance_t *x2ap_eNB_get_instance(instance_t instance)
   return NULL;
 }
 
-/// utility functions 
+/// utility functions
 
 void x2ap_dump_eNB (x2ap_eNB_data_t  * eNB_ref);
 
@@ -178,9 +178,9 @@ x2ap_dump_eNB_list (void) {
    x2ap_eNB_instance_t *inst = NULL;
    struct x2ap_eNB_data_s *found = NULL;
    struct x2ap_eNB_data_s temp;
-  
+
    memset(&temp, 0, sizeof(struct x2ap_eNB_data_s));
-   
+
   STAILQ_FOREACH (inst, &x2ap_eNB_internal_data.x2ap_eNB_instances_head,  x2ap_eNB_entries) {
     found = RB_FIND(x2ap_enb_map, &inst->x2ap_enb_head, &temp);
     x2ap_dump_eNB (found);
@@ -192,12 +192,12 @@ void x2ap_dump_eNB (x2ap_eNB_data_t  * eNB_ref) {
   if (eNB_ref == NULL) {
     return;
   }
-  
+
   X2AP_eNB_LIST_OUT ("");
   X2AP_eNB_LIST_OUT ("eNB name:          %s", eNB_ref->eNB_name == NULL ? "not present" : eNB_ref->eNB_name);
   X2AP_eNB_LIST_OUT ("eNB STATE:         %07x", eNB_ref->state);
   X2AP_eNB_LIST_OUT ("eNB ID:            %07x", eNB_ref->eNB_id);
-  indent++; 
+  indent++;
   X2AP_eNB_LIST_OUT ("SCTP cnx id:     %d", eNB_ref->cnx_id);
   X2AP_eNB_LIST_OUT ("SCTP assoc id:     %d", eNB_ref->assoc_id);
   X2AP_eNB_LIST_OUT ("SCTP instreams:    %d", eNB_ref->in_streams);
@@ -255,4 +255,3 @@ x2ap_eNB_data_t  * x2ap_is_eNB_assoc_id_in_list (const uint32_t sctp_assoc_id)
   }
   return NULL;
 }
-
diff --git a/openair2/X2AP/x2ap_eNB_management_procedures.h b/openair2/X2AP/x2ap_eNB_management_procedures.h
index bcad728aaaf328fd7b15965c229c6392eabb83b5..c5217341c514818f8abe81231cfd9b9600e03821 100644
--- a/openair2/X2AP/x2ap_eNB_management_procedures.h
+++ b/openair2/X2AP/x2ap_eNB_management_procedures.h
@@ -52,4 +52,3 @@ struct x2ap_eNB_data_s *x2ap_get_eNB(x2ap_eNB_instance_t *instance_p,
                                      uint16_t cnx_id);
 
 #endif /* X2AP_ENB_MANAGEMENT_PROCEDURES_H_ */
-
diff --git a/openair3/COMMON/messages_types.h b/openair3/COMMON/messages_types.h
index 47d9d32f2b689a99aea9c0dc8d6de983a4061af1..56a16da554b7a0b34e583df2f1a7c48d210016c1 100644
--- a/openair3/COMMON/messages_types.h
+++ b/openair3/COMMON/messages_types.h
@@ -31,6 +31,7 @@
 #include "ip_forward_messages_types.h"
 #include "s11_messages_types.h"
 #include "s1ap_messages_types.h"
+#include "f1ap_messages_types.h"
 #include "nas_messages_types.h"
 #include "s6a_messages_types.h"
 #include "sctp_messages_types.h"
diff --git a/openair3/GTPV1-U/nw-gtpv1u/src/NwGtpv1uMsg.c b/openair3/GTPV1-U/nw-gtpv1u/src/NwGtpv1uMsg.c
index 535ab8f1faf62f9b3e13f43391fab1a464f78ae5..365d6d23a5ff124b2ade204f940534c82aa7eb34 100644
--- a/openair3/GTPV1-U/nw-gtpv1u/src/NwGtpv1uMsg.c
+++ b/openair3/GTPV1-U/nw-gtpv1u/src/NwGtpv1uMsg.c
@@ -144,7 +144,7 @@ nwGtpv1uGpduMsgNew( NW_IN NwGtpv1uStackHandleT hGtpuStackHandle,
     AssertFatal((msgExtraLen + NW_GTPV1U_EPC_MIN_HEADER_SIZE) <= tpduOffset,
                 "Mismatch GTPU len, msgExtraLen %u tpduOffset %u",
                 msgExtraLen,
-                tpduOffset);
+                (uint32_t) tpduOffset);
     pMsg->msgBuf       = tpdu;
     pMsg->msgBufLen    = tpduLength + msgExtraLen + NW_GTPV1U_EPC_MIN_HEADER_SIZE;
     pMsg->msgBufOffset = tpduOffset - (msgExtraLen + NW_GTPV1U_EPC_MIN_HEADER_SIZE);
diff --git a/openair3/S1AP/MESSAGES/ASN1/asn1tostruct.py b/openair3/S1AP/MESSAGES/ASN1/asn1tostruct.py
index 4603e869a658e1f9e83ecfdd768aea47c81c4d41..b5a141349ba0fe694aa97d3bbcc74595c2b1ce29 100644
--- a/openair3/S1AP/MESSAGES/ASN1/asn1tostruct.py
+++ b/openair3/S1AP/MESSAGES/ASN1/asn1tostruct.py
@@ -253,15 +253,6 @@ for key in iesDefs:
         f.write("    %s_t *%s,\n" % (re.sub('-', '_', key), lowerFirstCamelWord(re.sub('-', '_', key))))
     f.write("    ANY_t *any_p);\n\n")
 
-    f.write("/* %s in iesDefs not in ieofielist.values()  */\n" % (key))
-    f.write("/** \\brief Compare function for %s ies.\n" % (key))
-    f.write(" *  \\param %s Pointer to the ASN1 structure.\n" % (firstlower))
-    f.write(" *  \\param %s Pointer to the ASN1 structure.\n" % (firstlower))
-    f.write(" **/\n")
-    f.write("asn_comp_rval_t *  %s_compare_%s(\n" % (fileprefix, keylowerunderscore))
-    f.write("    %s_t *%s1,\n" % (re.sub('-', '_', key), lowerFirstCamelWord(re.sub('-', '_', key))))
-    f.write("    %s_t *%s2);\n\n" % (re.sub('-', '_', key), lowerFirstCamelWord(re.sub('-', '_', key))))
-
     if len(iesDefs[key]["ies"]) == 0:
         continue
 
@@ -298,13 +289,6 @@ for key in iesDefs:
     f.write("int %s_decode_%s(\n" % (fileprefix, firstlower.lower()))
     f.write("    %sIEs_t *%sIEs,\n" % (asn1cStruct, firstlower))
     f.write("    %s_t *%s);\n\n" % (asn1cStruct, lowerFirstCamelWord(asn1cStruct)))
-    f.write("/** \\brief Compare function for %s ies.\n" % (key))
-    f.write(" *  \\param %s Pointer to the IES structure.\n" % (firstlower))
-    f.write(" *  \\param %s Pointer to the IES structure.\n" % (firstlower))
-    f.write(" **/\n")
-    f.write("asn_comp_rval_t *  %s_compare_%s(\n" % (fileprefix, firstlower.lower()))
-    f.write("    %sIEs_t *%s1,\n"    % (asn1cStruct, firstlower))
-    f.write("    %sIEs_t *%s2);\n\n" % (asn1cStruct, firstlower))
 
 
 
@@ -634,19 +618,19 @@ xer_encode_local(asn_TYPE_descriptor_t *td, void *sptr,
     mname = td->xml_tag;
     mlen = strlen(mname);
 
-    _i_ASN_TEXT_INDENT(0, indent);
-    _ASN_CALLBACK3("<", 1, mname, mlen, ">", 1);
+    ASN__TEXT_INDENT(0, indent);
+    ASN__CALLBACK3("<", 1, mname, mlen, ">", 1);
 
-    tmper = td->xer_encoder(td, sptr, indent + 1, XER_F_BASIC, cb, app_key);
+    tmper = td->op->xer_encoder(td, sptr, indent + 1, XER_F_BASIC, cb, app_key);
     if(tmper.encoded == -1) return tmper;
 
-    _ASN_CALLBACK3("</", 2, mname, mlen, ">\\n", xcan);
+    ASN__CALLBACK3("</", 2, mname, mlen, ">\\n", xcan);
 
     er.encoded = 4 + xcan + (2 * mlen) + tmper.encoded;
 
-    _ASN_ENCODED_OK(er);
+    ASN__ENCODED_OK(er);
 cb_failed:
-    _ASN_ENCODE_FAILED;
+    ASN__ENCODE_FAILED;
 }
 """)
 
@@ -714,7 +698,7 @@ for (key, value) in iesDefs.items():
         f.write("    cb(\"    </%s>\\n\", %d, app_key);\n" % (key, len("    </%s>\n" % (key))))
         f.write("    cb(\"</%s-PDU>\\n\", %d, app_key);\n" % (key, len("</%s-PDU>\n" % (key))))
 
-    f.write("    _ASN_ENCODED_OK(er);\n")
+    f.write("    ASN__ENCODED_OK(er);\n")
     #if key not in ieofielist.values():
         #f.write("cb_failed:\n")
         #f.write("    return er;\n")
@@ -731,119 +715,6 @@ f.write("#include \"%s_common.h\"\n#include \"%s_ies_defs.h\"\n" % (fileprefix,
 f.write("#include \"%s-ProtocolIE-ID.h\"\n\n" % (fileprefix_first_upper))
 
 
-for key in iesDefs:
-    if key in ieofielist.values():
-        continue
-    structName = re.sub('ies', '', key)
-    asn1cStruct = re.sub('-', '_', re.sub('IEs', '', key))
-    asn1cStruct = re.sub('Item', 'List', asn1cStruct)
-    if asn1cStruct.rfind('_') == len(asn1cStruct) - 1:
-        asn1cStruct = asn1cStruct[:-1]
-    asn1cStructfirstlower = asn1cStruct[:1].lower() + asn1cStruct[1:]
-    firstwordlower = re.sub('Item', 'List', re.sub('enb', 'eNB', lowerFirstCamelWord(asn1cStruct)))
-
-    iesaccess = ""
-    if key not in ieofielist.values():
-        iesaccess = "%s_ies." % (firstwordlower)
-
-    keyName = re.sub('-', '_', key)
-    keyupperunderscore = keyName.upper()
-    # No IE to encode...
-    if len(iesDefs[key]["ies"]) == 0:
-        continue
-
-    f.write("asn_comp_rval_t * %s_compare_%s(\n" % (fileprefix, re.sub('-', '_', structName.lower())))
-    f.write("    %s_t *%s1,\n" % (re.sub('-', '_', key), lowerFirstCamelWord(re.sub('-', '_', key))))
-    f.write("    %s_t *%s2) {\n\n" % (re.sub('-', '_', key), lowerFirstCamelWord(re.sub('-', '_', key))))
-
-    f.write("    asn_comp_rval_t *rv = NULL;\n\n")
-    f.write("    asn_comp_rval_t *rv2 = NULL;\n\n")
-
-    f.write("    assert(%s1 != NULL);\n" % (lowerFirstCamelWord(re.sub('-', '_', key))));
-    f.write("    assert(%s2 != NULL);\n" % (lowerFirstCamelWord(re.sub('-', '_', key))));
-
-    loop = 0
-    for ie in iesDefs[key]["ies"]:
-        iename = re.sub('-', '_', re.sub('id-', '', ie[0]))
-        ienameunderscore = re.sub('-', '_', iename)
-        ienamefirstwordlower = lowerFirstCamelWord(iename)
-        ieupperunderscore = re.sub('-', '_', re.sub('id-', '', ie[0])).upper()
-        ietypeunderscore = re.sub('-', '_', ie[2])
-
-        if ie[3] != "mandatory":
-
-            loop = loop + 1
-            if loop == 1:
-                #f.write("    %s_IE_t *ie1 = NULL;\n" % (fileprefix_first_upper))
-                #f.write("    %s_IE_t *ie2 = NULL;\n" % (fileprefix_first_upper))
-                f.write("    if (%s1->presenceMask != %s2->presenceMask) {rv=calloc(1,sizeof(asn_comp_rval_t));rv->name = asn_DEF_%s.name;rv->structure1 = %s1;rv->structure2 = %s2;rv->err_code = COMPARE_ERR_CODE_VALUE_NULL; return rv;}\n" % (lowerFirstCamelWord(re.sub('-', '_', key)), lowerFirstCamelWord(re.sub('-', '_', key)), ietypeunderscore, lowerFirstCamelWord(re.sub('-', '_', key)), lowerFirstCamelWord(re.sub('-', '_', key))))
-
-            if ie[3] == "optional":
-                f.write("    /* Optional field */\n")
-            elif ie[3] == "conditional":
-                f.write("    /* Conditional field */\n")
-            f.write("    if (%s1->presenceMask & %s_%s_PRESENT) {\n" % (lowerFirstCamelWord(re.sub('-', '_', key)), keyupperunderscore, ieupperunderscore))
-
-
-            if ie[2] in ieofielist.keys():
-                f.write("        /* collection field */\n")
-                f.write("        rv2 = %s_compare_%s(&%s1->%s, &%s2->%s);\n" % (fileprefix, ietypeunderscore.lower(), lowerFirstCamelWord(re.sub('-', '_', key)), ienamefirstwordlower, lowerFirstCamelWord(re.sub('-', '_', key)), ienamefirstwordlower ))
-                f.write("        if(rv2) {")
-                f.write("          if (NULL == rv) {")
-                f.write("            rv = rv2;")
-                f.write("          } else {")
-                f.write("            rv2->next = rv;")
-                f.write("            rv = rv2;")
-                f.write("          }")
-                f.write("          rv2 = NULL;")
-                f.write("        }")
-            else:
-                f.write("        /* simple field */\n")
-                f.write("        rv2 = asn_DEF_%s.compare(&asn_DEF_%s, &%s1->%s, &asn_DEF_%s, &%s2->%s); \n" % (ietypeunderscore, ietypeunderscore, lowerFirstCamelWord(re.sub('-', '_', key)), ienamefirstwordlower, ietypeunderscore, lowerFirstCamelWord(re.sub('-', '_', key)), ienamefirstwordlower ))
-                f.write("        if (rv2) {")
-                f.write("          if (NULL == rv) {")
-                f.write("            rv = rv2;")
-                f.write("          } else {")
-                f.write("            rv2->next = rv;")
-                f.write("            rv = rv2;")
-                f.write("          }")
-                f.write("          rv2 = NULL;")
-                f.write("          if (!rv->name) rv->name = asn_DEF_%s.name;" % (ietypeunderscore))
-                f.write("        }")
-
-            f.write("        assert(0);\n");
-            f.write("    }\n\n")
-
-        else:
-            if ie[2] in ieofielist.keys():
-                f.write("    /* Mandatory collection field */\n")
-                f.write("    rv2 = %s_compare_%s(&%s1->%s, &%s2->%s);\n" % (fileprefix, ietypeunderscore.lower(), lowerFirstCamelWord(re.sub('-', '_', key)), ienamefirstwordlower, lowerFirstCamelWord(re.sub('-', '_', key)), ienamefirstwordlower ))
-                f.write("    if (rv2) {\n")
-                f.write("      if (NULL == rv) {\n")
-                f.write("        rv = rv2;\n")
-                f.write("      } else {\n")
-                f.write("        rv2->next = rv;\n")
-                f.write("        rv = rv2;\n")
-                f.write("      }\n")
-                f.write("      rv2 = NULL;\n")
-                f.write("    }\n")
-
-            else:
-                f.write("    /* Mandatory simple field */\n")
-                f.write("    rv2 = asn_DEF_%s.compare(&asn_DEF_%s, &%s1->%s, &asn_DEF_%s, &%s2->%s);\n" % (ietypeunderscore, ietypeunderscore, lowerFirstCamelWord(re.sub('-', '_', key)), ienamefirstwordlower, ietypeunderscore, lowerFirstCamelWord(re.sub('-', '_', key)), ienamefirstwordlower ))
-                f.write("    if(rv2) {\n")
-                f.write("      if (NULL == rv) {\n")
-                f.write("        rv = rv2;\n")
-                f.write("      } else {\n")
-                f.write("        rv2->next = rv;\n")
-                f.write("        rv = rv2;\n")
-                f.write("      }\n")
-                f.write("      rv2 = NULL;\n")
-                f.write("      if (!rv->name) rv->name = asn_DEF_%s.name;\n" % (ietypeunderscore))
-                f.write("    }\n")
-    f.write("    return rv;\n")
-    f.write("}\n\n")
-
 for (key, value) in iesDefs.items():
     if key not in ieofielist.values():
         continue
@@ -859,30 +730,3 @@ for (key, value) in iesDefs.items():
             break
 
     f.write("extern asn_TYPE_descriptor_t asn_DEF_%s;\n" % (ietypeunderscore))
-
-    f.write("asn_comp_rval_t * %s_compare_%s(\n" % (fileprefix, re.sub('-', '_', i).lower()))
-    f.write("    %sIEs_t *%sIEs1,\n" % (re.sub('-', '_', i), lowerFirstCamelWord(re.sub('-', '_', i))))
-    f.write("    %sIEs_t *%sIEs2) {\n\n" % (re.sub('-', '_', i), lowerFirstCamelWord(re.sub('-', '_', i))))
-    f.write("    int i;\n")
-    f.write("    asn_comp_rval_t *rv = NULL;\n\n")
-    f.write("    asn_comp_rval_t *rv2 = NULL;\n\n")
-
-
-    f.write("    assert(%sIEs1 != NULL);\n" % (lowerFirstCamelWord(re.sub('-', '_', i))));
-    f.write("    assert(%sIEs2 != NULL);\n\n" % (lowerFirstCamelWord(re.sub('-', '_', i))));
-
-    f.write("    for (i = 0; i < %sIEs1->%s.count; i++) {\n" % (lowerFirstCamelWord(re.sub('-', '_', i)), re.sub('IEs', '', lowerFirstCamelWord(re.sub('-', '_', key)))))
-    f.write("        rv2 = asn_DEF_%s.compare(&asn_DEF_%s, %sIEs1->%s.array[i], &asn_DEF_%s, %sIEs2->%s.array[i]);\n" % (ietypeunderscore, ietypeunderscore, lowerFirstCamelWord(re.sub('-', '_', i)), re.sub('IEs', '', lowerFirstCamelWord(re.sub('-', '_', key))), ietypeunderscore, lowerFirstCamelWord(re.sub('-', '_', i)), re.sub('IEs', '', lowerFirstCamelWord(re.sub('-', '_', key)))))
-    f.write("        if(rv2) {")
-    f.write("          if (NULL == rv) {")
-    f.write("            rv = rv2;")
-    f.write("          } else {")
-    f.write("            rv2->next = rv;")
-    f.write("            rv = rv2;")
-    f.write("          }")
-    f.write("          rv2 = NULL;")
-    f.write("        }")
-    f.write("    }\n")
-    f.write("    return rv;\n")
-    f.write("}\n\n")
-
diff --git a/openair3/S1AP/s1ap_common.h b/openair3/S1AP/s1ap_common.h
index fc872564c57d51a34936523c86833b107ef20996..77d03f4ae4b099471155dc774a208e432303d888 100644
--- a/openair3/S1AP/s1ap_common.h
+++ b/openair3/S1AP/s1ap_common.h
@@ -105,8 +105,8 @@ extern int asn1_xer_print;
     } \
     if (ie == NULL ) { \
       S1AP_ERROR("S1AP_FIND_PROTOCOLIE_BY_ID: %s %d: ie is NULL\n",__FILE__,__LINE__);\
-      if (mandatory)  _Assert_Exit_ \
     } \
+    if (mandatory)  DevAssert(ie != NULL); \
   } while(0)
 /** \brief Function callback prototype.
  **/
diff --git a/openair3/S1AP/s1ap_eNB_handlers.c b/openair3/S1AP/s1ap_eNB_handlers.c
index 98bdbeb54db898d154703c102d668975d2bb2c62..0c3b1ee25b152c06cd76d464169e8afe95cb2494 100644
--- a/openair3/S1AP/s1ap_eNB_handlers.c
+++ b/openair3/S1AP/s1ap_eNB_handlers.c
@@ -272,15 +272,11 @@ int s1ap_eNB_handle_s1_setup_failure(uint32_t               assoc_id,
   S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_S1SetupFailureIEs_t, ie, container,
                              S1AP_ProtocolIE_ID_id_Cause,true);
 
-  if (ie != NULL) { /* checked by macro but cppcheck doesn't see it */
-    if ((ie->value.choice.Cause.present == S1AP_Cause_PR_misc) &&
-        (ie->value.choice.Cause.choice.misc == S1AP_CauseMisc_unspecified)) {
-      S1AP_WARN("Received s1 setup failure for MME... MME is not ready\n");
-    } else {
-      S1AP_ERROR("Received s1 setup failure for MME... please check your parameters\n");
-    }
+  if ((ie->value.choice.Cause.present == S1AP_Cause_PR_misc) &&
+      (ie->value.choice.Cause.choice.misc == S1AP_CauseMisc_unspecified)) {
+    S1AP_WARN("Received s1 setup failure for MME... MME is not ready\n");
   } else {
-    return -1;
+    S1AP_ERROR("Received s1 setup failure for MME... please check your parameters\n");
   }
 
   mme_desc_p->state = S1AP_ENB_STATE_WAITING;
@@ -318,68 +314,60 @@ int s1ap_eNB_handle_s1_setup_response(uint32_t               assoc_id,
   /* The list of served gummei can contain at most 8 elements.
    * LTE related gummei is the first element in the list, i.e with an id of 0.
    */
-  if (ie != NULL) { /* checked by macro but cppcheck doesn't see it */
-    S1AP_DEBUG("servedGUMMEIs.list.count %d\n", ie->value.choice.ServedGUMMEIs.list.count);
-    DevAssert(ie->value.choice.ServedGUMMEIs.list.count > 0);
-    DevAssert(ie->value.choice.ServedGUMMEIs.list.count <= S1AP_maxnoofRATs);
-
-    for (i = 0; i < ie->value.choice.ServedGUMMEIs.list.count; i++) {
-      S1AP_ServedGUMMEIsItem_t *gummei_item_p;
-      struct served_gummei_s   *new_gummei_p;
-      int j;
-      gummei_item_p = ie->value.choice.ServedGUMMEIs.list.array[i];
-      new_gummei_p = calloc(1, sizeof(struct served_gummei_s));
-      STAILQ_INIT(&new_gummei_p->served_plmns);
-      STAILQ_INIT(&new_gummei_p->served_group_ids);
-      STAILQ_INIT(&new_gummei_p->mme_codes);
-      S1AP_DEBUG("servedPLMNs.list.count %d\n", gummei_item_p->servedPLMNs.list.count);
-
-      for (j = 0; j < gummei_item_p->servedPLMNs.list.count; j++) {
-        S1AP_PLMNidentity_t *plmn_identity_p;
-        struct plmn_identity_s *new_plmn_identity_p;
-        plmn_identity_p = gummei_item_p->servedPLMNs.list.array[j];
-        new_plmn_identity_p = calloc(1, sizeof(struct plmn_identity_s));
-        TBCD_TO_MCC_MNC(plmn_identity_p, new_plmn_identity_p->mcc,
-                        new_plmn_identity_p->mnc, new_plmn_identity_p->mnc_digit_length);
-        STAILQ_INSERT_TAIL(&new_gummei_p->served_plmns, new_plmn_identity_p, next);
-        new_gummei_p->nb_served_plmns++;
-      }
-
-      for (j = 0; j < gummei_item_p->servedGroupIDs.list.count; j++) {
-        S1AP_MME_Group_ID_t       *mme_group_id_p;
-        struct served_group_id_s *new_group_id_p;
-        mme_group_id_p = gummei_item_p->servedGroupIDs.list.array[j];
-        new_group_id_p = calloc(1, sizeof(struct served_group_id_s));
-        OCTET_STRING_TO_INT16(mme_group_id_p, new_group_id_p->mme_group_id);
-        STAILQ_INSERT_TAIL(&new_gummei_p->served_group_ids, new_group_id_p, next);
-        new_gummei_p->nb_group_id++;
-      }
+  S1AP_DEBUG("servedGUMMEIs.list.count %d\n", ie->value.choice.ServedGUMMEIs.list.count);
+  DevAssert(ie->value.choice.ServedGUMMEIs.list.count > 0);
+  DevAssert(ie->value.choice.ServedGUMMEIs.list.count <= S1AP_maxnoofRATs);
+
+  for (i = 0; i < ie->value.choice.ServedGUMMEIs.list.count; i++) {
+    S1AP_ServedGUMMEIsItem_t *gummei_item_p;
+    struct served_gummei_s   *new_gummei_p;
+    int j;
+    gummei_item_p = ie->value.choice.ServedGUMMEIs.list.array[i];
+    new_gummei_p = calloc(1, sizeof(struct served_gummei_s));
+    STAILQ_INIT(&new_gummei_p->served_plmns);
+    STAILQ_INIT(&new_gummei_p->served_group_ids);
+    STAILQ_INIT(&new_gummei_p->mme_codes);
+    S1AP_DEBUG("servedPLMNs.list.count %d\n", gummei_item_p->servedPLMNs.list.count);
+
+    for (j = 0; j < gummei_item_p->servedPLMNs.list.count; j++) {
+      S1AP_PLMNidentity_t *plmn_identity_p;
+      struct plmn_identity_s *new_plmn_identity_p;
+      plmn_identity_p = gummei_item_p->servedPLMNs.list.array[j];
+      new_plmn_identity_p = calloc(1, sizeof(struct plmn_identity_s));
+      TBCD_TO_MCC_MNC(plmn_identity_p, new_plmn_identity_p->mcc,
+                      new_plmn_identity_p->mnc, new_plmn_identity_p->mnc_digit_length);
+      STAILQ_INSERT_TAIL(&new_gummei_p->served_plmns, new_plmn_identity_p, next);
+      new_gummei_p->nb_served_plmns++;
+    }
 
-      for (j = 0; j < gummei_item_p->servedMMECs.list.count; j++) {
-        S1AP_MME_Code_t        *mme_code_p;
-        struct mme_code_s *new_mme_code_p;
-        mme_code_p = gummei_item_p->servedMMECs.list.array[j];
-        new_mme_code_p = calloc(1, sizeof(struct mme_code_s));
-        OCTET_STRING_TO_INT8(mme_code_p, new_mme_code_p->mme_code);
-        STAILQ_INSERT_TAIL(&new_gummei_p->mme_codes, new_mme_code_p, next);
-        new_gummei_p->nb_mme_code++;
-      }
+    for (j = 0; j < gummei_item_p->servedGroupIDs.list.count; j++) {
+      S1AP_MME_Group_ID_t       *mme_group_id_p;
+      struct served_group_id_s *new_group_id_p;
+      mme_group_id_p = gummei_item_p->servedGroupIDs.list.array[j];
+      new_group_id_p = calloc(1, sizeof(struct served_group_id_s));
+      OCTET_STRING_TO_INT16(mme_group_id_p, new_group_id_p->mme_group_id);
+      STAILQ_INSERT_TAIL(&new_gummei_p->served_group_ids, new_group_id_p, next);
+      new_gummei_p->nb_group_id++;
+    }
 
-      STAILQ_INSERT_TAIL(&mme_desc_p->served_gummei, new_gummei_p, next);
+    for (j = 0; j < gummei_item_p->servedMMECs.list.count; j++) {
+      S1AP_MME_Code_t        *mme_code_p;
+      struct mme_code_s *new_mme_code_p;
+      mme_code_p = gummei_item_p->servedMMECs.list.array[j];
+      new_mme_code_p = calloc(1, sizeof(struct mme_code_s));
+      OCTET_STRING_TO_INT8(mme_code_p, new_mme_code_p->mme_code);
+      STAILQ_INSERT_TAIL(&new_gummei_p->mme_codes, new_mme_code_p, next);
+      new_gummei_p->nb_mme_code++;
     }
-  } else {
-    return -1;
+
+    STAILQ_INSERT_TAIL(&mme_desc_p->served_gummei, new_gummei_p, next);
   }
 
   /* Set the capacity of this MME */
   S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_S1SetupResponseIEs_t, ie, container,
                              S1AP_ProtocolIE_ID_id_RelativeMMECapacity, true);
 
-  if (ie != NULL) { /* checked by macro but cppcheck doesn't see it */
-    mme_desc_p->relative_mme_capacity = ie->value.choice.RelativeMMECapacity;
-  } else {
-    return -1;
-  }
+  mme_desc_p->relative_mme_capacity = ie->value.choice.RelativeMMECapacity;
 
   /* Optionaly set the mme name */
   S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_S1SetupResponseIEs_t, ie, container,
diff --git a/openair3/S1AP/s1ap_eNB_nas_procedures.c b/openair3/S1AP/s1ap_eNB_nas_procedures.c
index 6652ca0447b10ea8a0f573e1cacd5e68beacc34f..bd0fd13208158aba2bcb1078f56a7f63eee7b154 100644
--- a/openair3/S1AP/s1ap_eNB_nas_procedures.c
+++ b/openair3/S1AP/s1ap_eNB_nas_procedures.c
@@ -501,18 +501,12 @@ int s1ap_eNB_handle_nas_downlink(uint32_t         assoc_id,
     container = &pdu->choice.initiatingMessage.value.choice.DownlinkNASTransport;
     S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_DownlinkNASTransport_IEs_t, ie, container,
                                S1AP_ProtocolIE_ID_id_MME_UE_S1AP_ID, true);
-    if (ie == NULL) { /* checked by macro, but cppcheck doesn't see it */
-        return -1;
-    } else {
-        mme_ue_s1ap_id = ie->value.choice.MME_UE_S1AP_ID;
-    }
+    mme_ue_s1ap_id = ie->value.choice.MME_UE_S1AP_ID;
+
     S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_DownlinkNASTransport_IEs_t, ie, container,
                                S1AP_ProtocolIE_ID_id_eNB_UE_S1AP_ID, true);
-    if (ie == NULL) { /* checked by macro, but cppcheck doesn't see it */
-        return -1;
-    } else {
-        enb_ue_s1ap_id = ie->value.choice.ENB_UE_S1AP_ID;
-    }
+    enb_ue_s1ap_id = ie->value.choice.ENB_UE_S1AP_ID;
+
     if ((ue_desc_p = s1ap_eNB_get_ue_context(s1ap_eNB_instance,
                      enb_ue_s1ap_id)) == NULL) {
         MSC_LOG_RX_DISCARDED_MESSAGE(
@@ -566,15 +560,11 @@ int s1ap_eNB_handle_nas_downlink(uint32_t         assoc_id,
     S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_DownlinkNASTransport_IEs_t, ie, container,
                                S1AP_ProtocolIE_ID_id_NAS_PDU, true);
     /* Forward the NAS PDU to RRC */
-    if (ie != NULL) { /* checked by macro, but cppcheck doesn't see it */
-        s1ap_eNB_itti_send_nas_downlink_ind(s1ap_eNB_instance->instance,
-                                            ue_desc_p->ue_initial_id,
-                                            ue_desc_p->eNB_ue_s1ap_id,
-                                            ie->value.choice.NAS_PDU.buf,
-                                            ie->value.choice.NAS_PDU.size);
-    } else {
-        return -1;
-    }
+    s1ap_eNB_itti_send_nas_downlink_ind(s1ap_eNB_instance->instance,
+                                        ue_desc_p->ue_initial_id,
+                                        ue_desc_p->eNB_ue_s1ap_id,
+                                        ie->value.choice.NAS_PDU.buf,
+                                        ie->value.choice.NAS_PDU.size);
     return 0;
 }
 
diff --git a/openair3/S1AP/s1ap_eNB_trace.c b/openair3/S1AP/s1ap_eNB_trace.c
index 543ea9c511884d4dc952a39f6232a7941441e30f..19f50592386843fb774cf8bc3adbbd35b728cfb1 100644
--- a/openair3/S1AP/s1ap_eNB_trace.c
+++ b/openair3/S1AP/s1ap_eNB_trace.c
@@ -121,7 +121,7 @@ int s1ap_eNB_handle_trace_start(uint32_t         assoc_id,
   if (ie != NULL) {
     ue_desc_p = s1ap_eNB_get_ue_context(mme_ref_p->s1ap_eNB_instance,
                                         ie->value.choice.ENB_UE_S1AP_ID);
-  } 
+  }
     if (ue_desc_p == NULL) {
         /* Could not find context associated with this eNB_ue_s1ap_id -> generate
          * trace failure indication.
diff --git a/openair3/SCTP/sctp_eNB_itti_messaging.c b/openair3/SCTP/sctp_eNB_itti_messaging.c
index 9c24da73706a2331d00280371d94d6437ae1fafb..789af3f8edf564b34e4630d0ba5f5d02d06591e4 100644
--- a/openair3/SCTP/sctp_eNB_itti_messaging.c
+++ b/openair3/SCTP/sctp_eNB_itti_messaging.c
@@ -38,7 +38,8 @@ int sctp_itti_send_init_msg_multi_cnf(task_id_t task_id, instance_t instance, in
   return itti_send_msg_to_task(task_id, instance, message_p);
 }
 
-int sctp_itti_send_new_message_ind(task_id_t task_id, instance_t instance, uint32_t assoc_id, uint8_t *buffer,
+int sctp_itti_send_new_message_ind(task_id_t task_id, instance_t instance,
+                                   uint32_t assoc_id, uint8_t *buffer,
                                    uint32_t buffer_length, uint16_t stream)
 {
   MessageDef      *message_p;
diff --git a/openair3/SCTP/sctp_eNB_itti_messaging.h b/openair3/SCTP/sctp_eNB_itti_messaging.h
index b4f1a0ee692ce858ca7ca464cc08a4c8429645f8..a35dc2219a35431cf6976b6d3f3a693270c5c6f9 100644
--- a/openair3/SCTP/sctp_eNB_itti_messaging.h
+++ b/openair3/SCTP/sctp_eNB_itti_messaging.h
@@ -24,7 +24,8 @@
 
 int sctp_itti_send_init_msg_multi_cnf(task_id_t task_id, instance_t instance, int multi_sd);
 
-int sctp_itti_send_new_message_ind(task_id_t task_id, instance_t instance, uint32_t assoc_id, uint8_t *buffer,
+int sctp_itti_send_new_message_ind(task_id_t task_id, instance_t instance,
+                                   uint32_t assoc_id, uint8_t *buffer,
                                    uint32_t buffer_length, uint16_t stream);
 
 int sctp_itti_send_association_resp(task_id_t task_id, instance_t instance,
diff --git a/openair3/SCTP/sctp_eNB_task.c b/openair3/SCTP/sctp_eNB_task.c
index 68fa34f810d98aa2c1bf2dbf4b9a42432d106ff9..4b0945f5eaaccedacf4b45810900e1a8cc35987a 100644
--- a/openair3/SCTP/sctp_eNB_task.c
+++ b/openair3/SCTP/sctp_eNB_task.c
@@ -1008,9 +1008,12 @@ sctp_eNB_read_from_socket(
                    sinfo.sinfo_assoc_id, sctp_cnx->sd, n, ntohs(addr.sin_port),
                    sinfo.sinfo_stream, ntohl(sinfo.sinfo_ppid));
 
-        sctp_itti_send_new_message_ind(sctp_cnx->task_id, sctp_cnx->instance,
+        sctp_itti_send_new_message_ind(sctp_cnx->task_id,
+                                       sctp_cnx->instance,
                                        sinfo.sinfo_assoc_id,
-                                       buffer, n, sinfo.sinfo_stream);
+                                       buffer,
+                                       n,
+                                       sinfo.sinfo_stream);
     }
 }
 
diff --git a/openair3/TEST/EPC_TEST/generate_scenario.c b/openair3/TEST/EPC_TEST/generate_scenario.c
index b1a3297866078ea11efe7243d485c32cb102ef67..a8a359094518ae62b32f9dac52f5d40bc3539647 100644
--- a/openair3/TEST/EPC_TEST/generate_scenario.c
+++ b/openair3/TEST/EPC_TEST/generate_scenario.c
@@ -353,7 +353,7 @@ void enb_config_init(const  char const * lib_config_file_name_pP)
       setting_enb   = config_setting_get_elem(setting, i);
       active_enb[i] = config_setting_get_string (setting_enb);
       AssertFatal (active_enb[i] != NULL,
-                   "Failed to parse config file %s, %uth attribute %s \n",
+                   "Failed to parse config file %s, %dth attribute %s \n",
                    lib_config_file_name_pP, i, ENB_CONFIG_STRING_ACTIVE_ENBS);
       active_enb[i] = strdup(active_enb[i]);
       num_enb_properties += 1;
@@ -393,7 +393,7 @@ void enb_config_init(const  char const * lib_config_file_name_pP)
             )
         ) {
         AssertError (0, parse_errors ++,
-                     "Failed to parse eNB configuration file %s, %u th enb\n",
+                     "Failed to parse eNB configuration file %s, %d th enb\n",
                      lib_config_file_name_pP, i);
         continue; // FIXME this prevents segfaults below, not sure what happens after function exit
       }
@@ -441,7 +441,7 @@ void enb_config_init(const  char const * lib_config_file_name_pP)
                  )
               ) {
               AssertError (0, parse_errors ++,
-                           "Failed to parse eNB configuration file %s, %u th enb %u th mme address !\n",
+                           "Failed to parse eNB configuration file %s, %d th enb %d th mme address !\n",
                            lib_config_file_name_pP, i, j);
               continue; // FIXME will prevent segfaults below, not sure what happens at function exit...
             }
diff --git a/openair3/TEST/EPC_TEST/play_scenario.c b/openair3/TEST/EPC_TEST/play_scenario.c
index a50eac95cffc8048994d3e19ff510269eea4b466..3af47f21a8551c1381c3a4f78d4898b6d119c92a 100644
--- a/openair3/TEST/EPC_TEST/play_scenario.c
+++ b/openair3/TEST/EPC_TEST/play_scenario.c
@@ -473,7 +473,7 @@ void et_enb_config_init(const  char const * lib_config_file_name_pP)
       setting_enb   = config_setting_get_elem(setting, i);
       active_enb[i] = config_setting_get_string (setting_enb);
       AssertFatal (active_enb[i] != NULL,
-                   "Failed to parse config file %s, %uth attribute %s \n",
+                   "Failed to parse config file %s, %dth attribute %s \n",
                    lib_config_file_name_pP, i, ENB_CONFIG_STRING_ACTIVE_ENBS);
       active_enb[i] = strdup(active_enb[i]);
       num_enb_properties += 1;
@@ -513,7 +513,7 @@ void et_enb_config_init(const  char const * lib_config_file_name_pP)
             )
         ) {
         AssertError (0, parse_errors ++,
-                     "Failed to parse eNB configuration file %s, %u th enb\n",
+                     "Failed to parse eNB configuration file %s, %d th enb\n",
                      lib_config_file_name_pP, i);
         continue; // FIXME this prevents segfaults below, not sure what happens after function exit
       }
@@ -561,7 +561,7 @@ void et_enb_config_init(const  char const * lib_config_file_name_pP)
                  )
               ) {
               AssertError (0, parse_errors ++,
-                           "Failed to parse eNB configuration file %s, %u th enb %u th mme address !\n",
+                           "Failed to parse eNB configuration file %s, %d th enb %d th mme address !\n",
                            lib_config_file_name_pP, i, j);
               continue; // FIXME will prevent segfaults below, not sure what happens at function exit...
             }
diff --git a/openair3/TEST/EPC_TEST/play_scenario_parse.c b/openair3/TEST/EPC_TEST/play_scenario_parse.c
index d24fddddec342acc284a01f5233e16ed4b4a3560..607ec34dfc25daa20d14e13343f67c5a24ecb449 100644
--- a/openair3/TEST/EPC_TEST/play_scenario_parse.c
+++ b/openair3/TEST/EPC_TEST/play_scenario_parse.c
@@ -104,7 +104,7 @@ void et_parse_s1ap(xmlDocPtr doc, const xmlNode const *s1ap_node, et_s1ap_t * co
               rc = et_hex2data( &s1ap->binary_stream[s1ap->binary_stream_pos], xml_char, xmlStrlen(xml_char));
               s1ap->binary_stream_pos += xmlStrlen(xml_char)/2;
               //et_display_node(cur_node, 0);
-              AssertFatal (rc >= 0, "ERROR in converting hex string %s len %d size %d rc %d\n", xml_char, xmlStrlen(xml_char), size, rc);
+              AssertFatal (rc >= 0, "ERROR in converting hex string %s len %d size %u rc %d\n", xml_char, xmlStrlen(xml_char), size, rc);
               go_deeper_in_tree = 0;
               //}
               xmlFree(xml_char);
diff --git a/openair3/TEST/EPC_TEST/play_scenario_s1ap.c b/openair3/TEST/EPC_TEST/play_scenario_s1ap.c
index d2bf05c0862f8eddd958621744d08f439b836baa..acc9b18f767ddc2dcec8199e1a04b63e053e8e04 100644
--- a/openair3/TEST/EPC_TEST/play_scenario_s1ap.c
+++ b/openair3/TEST/EPC_TEST/play_scenario_s1ap.c
@@ -616,7 +616,7 @@ int et_scenario_set_packet_received(et_packet_t * const packet)
 
   if (0 != packet->timer_id) {
     rc = timer_remove(packet->timer_id);
-    AssertFatal(rc == 0, "TODO: Debug Timer on Rx packet num %d unknown", packet->packet_number);
+    AssertFatal(rc == 0, "TODO: Debug Timer on Rx packet num %u unknown", packet->packet_number);
     g_scenario->timer_count--;
     return rc;
   }
@@ -919,7 +919,7 @@ void et_s1ap_update_assoc_id_of_packets(const int32_t assoc_id,
         break;
 
       default:
-        AssertFatal(0, "Unknown chunk_type %d packet num %d", packet->sctp_hdr.chunk_type, packet->packet_number);
+        AssertFatal(0, "Unknown chunk_type %d packet num %u", packet->sctp_hdr.chunk_type, packet->packet_number);
         ;
     }
     packet = packet->next;
diff --git a/openair3/TEST/EPC_TEST/play_scenario_s1ap_compare_ie.c b/openair3/TEST/EPC_TEST/play_scenario_s1ap_compare_ie.c
index 001834fcab229ac60d4209bfeb215494e524540f..bc7ca6afbd0d1e3cd4a95b28ad8b58c221a4d651 100644
--- a/openair3/TEST/EPC_TEST/play_scenario_s1ap_compare_ie.c
+++ b/openair3/TEST/EPC_TEST/play_scenario_s1ap_compare_ie.c
@@ -122,7 +122,7 @@ void update_xpath_node_mme_ue_s1ap_id(et_s1ap_t * const s1ap, xmlNode *node, con
               hex[2] = '\0';
               end_ptr = hex;
               uli = strtoul(hex, &end_ptr, 16);
-              AssertFatal((uli != ULONG_MAX) && (end_ptr != NULL) && (*end_ptr == '\0'), "Conversion of hexstring %s failed returned %ld errno %d", hex, uli, errno);
+              AssertFatal((uli != ULONG_MAX) && (end_ptr != NULL) && (*end_ptr == '\0'), "Conversion of hexstring %s failed returned %lu errno %d", hex, uli, errno);
               s1ap->binary_stream[pos++] = (unsigned char)uli;
             } while (pos2 < (2*5));
             // update ASN1
diff --git a/openair3/UDP/udp_eNB_task.c b/openair3/UDP/udp_eNB_task.c
index fdcdeb037af62ebddb912651d620f7954e2149b5..27f754badc28af6d805eda340143c34912de03ef 100644
--- a/openair3/UDP/udp_eNB_task.c
+++ b/openair3/UDP/udp_eNB_task.c
@@ -169,7 +169,7 @@ int udp_eNB_create_socket(int port, char *ip_addr, task_id_t task_id)
 
   if ((rc = bind(sd, (struct sockaddr *)&sin, sizeof(struct sockaddr_in))) < 0) {
     close(sd);
-    AssertFatal(rc >= 0, "UDP: Failed to bind socket: (%s:%d) address %s port %u\n",
+    AssertFatal(rc >= 0, "UDP: Failed to bind socket: (%s:%d) address %s port %d\n",
                 strerror(errno), errno, ip_addr, port);
   }
 
diff --git a/openair3/UTILS/conversions.h b/openair3/UTILS/conversions.h
index f1f1d2550a146a18b1ae8dbd53dfb5dbcfc4d39f..71d57cc87d9d2bda784c2e421050f0fabf117f1d 100644
--- a/openair3/UTILS/conversions.h
+++ b/openair3/UTILS/conversions.h
@@ -187,7 +187,7 @@ do {                                    \
 
 #define OCTET_STRING_TO_INT16(aSN, x)   \
 do {                                    \
-    DevCheck((aSN)->size == 2, (aSN)->size, 0, 0);           \
+    DevCheck((aSN)->size == 2 || (aSN)->size == 3, (aSN)->size, 0, 0);           \
     BUFFER_TO_INT16((aSN)->buf, x);    \
 } while(0)
 
@@ -210,6 +210,13 @@ do {                                                                \
         ((aSN)->buf[2] << 4) | (aSN)->buf[3];                       \
 } while(0)
 
+#define BIT_STRING_TO_NR_CELL_IDENTITY(aSN, vALUE)                     \
+do {                                                                   \
+    DevCheck((aSN)->bits_unused == 4, (aSN)->bits_unused, 4, 0);       \
+    vALUE = ((aSN)->buf[0] << 28) | ((aSN)->buf[1] << 20) |            \
+        ((aSN)->buf[2] << 12) | ((aSN)->buf[3]<<4) | ((aSN)->buf[4]>>4);  \
+} while(0)
+
 #define MCC_HUNDREDS(vALUE) \
     ((vALUE) / 100)
 /* When MNC is only composed of 2 digits, set the hundreds unit to 0xf */
@@ -237,6 +244,17 @@ do {                                                                           \
     (oCTETsTRING)->size = 3;                                                   \
 } while(0)
 
+#define PLMNID_TO_MCC_MNC(oCTETsTRING, mCC, mNC, mNCdIGITlENGTH)                  \
+do {                                                                              \
+    mCC = ((oCTETsTRING)->buf[0] & 0x0F) * 100 +                                  \
+          ((oCTETsTRING)->buf[0] >> 4 & 0x0F) * 10 +                              \
+          ((oCTETsTRING)->buf[1] & 0x0F);                                         \
+    mNCdIGITlENGTH = ((oCTETsTRING)->buf[1] >> 4 & 0x0F) == 0xF ? 2 : 3;          \
+    mNC = (mNCdIGITlENGTH == 2 ? 0 : ((oCTETsTRING)->buf[1] >> 4 & 0x0F) * 100) + \
+          ((oCTETsTRING)->buf[2] & 0x0F) * 10 +                                   \
+          ((oCTETsTRING)->buf[2] >> 4 & 0x0F);                                    \
+} while (0)
+
 #define MCC_MNC_TO_TBCD(mCC, mNC, mNCdIGITlENGTH, tBCDsTRING)        \
 do {                                                                 \
     char _buf[3];                                                    \
@@ -299,6 +317,92 @@ do {                                                                    \
           + pLMN.MNCdigit2 * 10 + pLMN.MNCdigit1;                       \
 } while(0)
 
+
+/* TS 38.473 v15.2.1 section 9.3.1.32:
+ * C RNTI is BIT_STRING(16)
+ */
+#define C_RNTI_TO_BIT_STRING(mACRO, bITsTRING)          \
+do {                                                    \
+    (bITsTRING)->buf = calloc(2, sizeof(uint8_t));      \
+    (bITsTRING)->buf[0] = (mACRO) >> 8;                 \
+    (bITsTRING)->buf[1] = ((mACRO) & 0x0ff);            \
+    (bITsTRING)->size = 2;                              \
+    (bITsTRING)->bits_unused = 0;                       \
+} while(0)
+
+
+/* TS 38.473 v15.2.1 section 9.3.2.3:
+ * TRANSPORT LAYER ADDRESS for IPv4 is 32bit (TS 38.414)
+ */
+#define TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(mACRO, bITsTRING)    \
+do {                                                    \
+    (bITsTRING)->buf = calloc(4, sizeof(uint8_t));      \
+    (bITsTRING)->buf[0] = (mACRO) >> 24 & 0xFF;         \
+    (bITsTRING)->buf[1] = (mACRO) >> 16 & 0xFF;         \
+    (bITsTRING)->buf[2] = (mACRO) >> 8 & 0xFF;          \
+    (bITsTRING)->buf[3] = (mACRO) >> 4 & 0xFF;          \
+    (bITsTRING)->size = 4;                              \
+    (bITsTRING)->bits_unused = 0;                       \
+} while(0)
+
+#define BIT_STRING_TO_TRANSPORT_LAYER_ADDRESS_IPv4(bITsTRING, mACRO)    \
+do {                                                                    \
+    DevCheck((bITsTRING)->size == 4, (bITsTRING)->size, 4, 0);          \
+    DevCheck((bITsTRING)->bits_unused == 0, (bITsTRING)->bits_unused, 0, 0); \
+    mACRO = ((bITsTRING)->buf[0] << 24) +                               \
+            ((bITsTRING)->buf[1] << 16) +                               \
+            ((bITsTRING)->buf[2] << 8) +                                \
+            ((bITsTRING)->buf[3]);                                      \
+} while (0)
+
+
+/* TS 38.473 v15.1.1 section 9.3.1.12:
+ * NR CELL ID
+ */
+#define NR_CELL_ID_TO_BIT_STRING(mACRO, bITsTRING)      \
+do {                                                    \
+    (bITsTRING)->buf = calloc(5, sizeof(uint8_t));      \
+    (bITsTRING)->buf[0] = ((mACRO) >> 28) & 0xff;       \
+    (bITsTRING)->buf[1] = ((mACRO) >> 20) & 0xff;       \
+    (bITsTRING)->buf[2] = ((mACRO) >> 12) & 0xff;       \
+    (bITsTRING)->buf[3] = ((mACRO) >> 4)  & 0xff;       \
+    (bITsTRING)->buf[4] = ((mACRO) & 0x0f) << 4;        \
+    (bITsTRING)->size = 5;                              \
+    (bITsTRING)->bits_unused = 4;                       \
+} while(0)
+
+/* TS 38.473 v15.2.1 section 9.3.1.55:
+ * MaskedIMEISV is BIT_STRING(64)
+ */
+#define MaskedIMEISV_TO_BIT_STRING(mACRO, bITsTRING)    \
+do {                                                    \
+    (bITsTRING)->buf = calloc(8, sizeof(uint8_t));      \
+    (bITsTRING)->buf[0] = (mACRO) >> 56 & 0xFF;         \
+    (bITsTRING)->buf[1] = (mACRO) >> 48 & 0xFF;         \
+    (bITsTRING)->buf[2] = (mACRO) >> 40 & 0xFF;         \
+    (bITsTRING)->buf[3] = (mACRO) >> 32 & 0xFF;         \
+    (bITsTRING)->buf[4] = (mACRO) >> 24 & 0xFF;         \
+    (bITsTRING)->buf[5] = (mACRO) >> 16 & 0xFF;         \
+    (bITsTRING)->buf[6] = (mACRO) >> 8 & 0xFF;          \
+    (bITsTRING)->buf[7] = (mACRO) >> 4 & 0xFF;          \
+    (bITsTRING)->size = 8;                              \
+    (bITsTRING)->bits_unused = 0;                       \
+} while(0)
+
+#define BIT_STRING_TO_MaskedIMEISV(bITsTRING, mACRO)    \
+do {                                                                    \
+    DevCheck((bITsTRING)->size == 8, (bITsTRING)->size, 8, 0);          \
+    DevCheck((bITsTRING)->bits_unused == 0, (bITsTRING)->bits_unused, 0, 0); \
+    mACRO = ((bITsTRING)->buf[0] << 56) +                               \
+            ((bITsTRING)->buf[1] << 48) +                               \
+            ((bITsTRING)->buf[2] << 40) +                               \
+            ((bITsTRING)->buf[3] << 32) +                               \
+            ((bITsTRING)->buf[4] << 24) +                               \
+            ((bITsTRING)->buf[5] << 16) +                               \
+            ((bITsTRING)->buf[6] << 8) +                                \
+            ((bITsTRING)->buf[7]);                                      \
+} while (0)
+
 /* TS 36.413 v10.9.0 section 9.2.1.37:
  * Macro eNB ID:
  * Equal to the 20 leftmost bits of the Cell
diff --git a/targets/ARCH/EXMIMO/USERSPACE/OAI_FW_INIT/updatefw.c b/targets/ARCH/EXMIMO/USERSPACE/OAI_FW_INIT/updatefw.c
index be049e255e3929dd6a5ffb88aab096d158b4ec1a..febf221c5be715a6be12a7d89cbf0f98c737e94f 100644
--- a/targets/ARCH/EXMIMO/USERSPACE/OAI_FW_INIT/updatefw.c
+++ b/targets/ARCH/EXMIMO/USERSPACE/OAI_FW_INIT/updatefw.c
@@ -677,7 +677,7 @@ int main(int argc, char** argv) {
   } /* pflag */
 
   if (verboselevel >= VERBOSE_LEVEL_MAIN_STEPS) printf("Info: action #5 done.\n");
-  
+
   fclose(p_elfimage);
 
   /* Did we pretend ? */
diff --git a/targets/ARCH/IRIS/USERSPACE/LIB/Makefile.inc b/targets/ARCH/IRIS/USERSPACE/LIB/Makefile.inc
index 79d0a5b7a8447b457cbdc8255e6db434bba76045..b79e3cec746031f7e72e56af734d170bb0ce7da7 100644
--- a/targets/ARCH/IRIS/USERSPACE/LIB/Makefile.inc
+++ b/targets/ARCH/IRIS/USERSPACE/LIB/Makefile.inc
@@ -1,4 +1,3 @@
 IRIS_OBJ += $(OPENAIR_TARGETS)/ARCH/IRIS/USERSPACE/LIB/iris_lib.o
 IRIS_FILE_OBJ += $(OPENAIR_TARGETS)/ARCH/IRIS/USERSPACE/LIB/iris_lib.cpp
 IRIS_CFLAGS += -I$(OPENAIR_TARGETS)/ARCH/COMMON -I$(OPENAIR_TARGETS)/ARCH/IRIS/USERSPACE/LIB/ -I$(OPENAIR_TARGETS)/COMMON
-
diff --git a/targets/ARCH/IRIS/USERSPACE/LIB/iris_lib.cpp b/targets/ARCH/IRIS/USERSPACE/LIB/iris_lib.cpp
index 34a694a4d556a03cf56e18d4a7a527cfcf28d98b..5b20d8a8c71be4ba9ea850ff25474e1d8798abd8 100644
--- a/targets/ARCH/IRIS/USERSPACE/LIB/iris_lib.cpp
+++ b/targets/ARCH/IRIS/USERSPACE/LIB/iris_lib.cpp
@@ -335,8 +335,8 @@ static int trx_iris_read(openair0_device *device, openair0_timestamp *ptimestamp
             ((__m256i *)buff[i])[j] = _mm256_srai_epi16(buff_tmp[i][j],4);
 #else
             ((__m128i *)buff[i])[j] = _mm_srai_epi16(buff_tmp[i][j],4);
-#endif  
-#endif  
+#endif
+#endif
           }
         }
     }
@@ -534,7 +534,7 @@ int device_init(openair0_device *device, openair0_config_t *openair0_cfg) {
     args["driver"] = "iris";
     char *iris_addrs = device->openair0_cfg[0].sdr_addrs;
     if (iris_addrs == NULL)
-    { 
+    {
         s->iris.push_back(SoapySDR::Device::make(args));
     }
     else
@@ -695,14 +695,14 @@ int device_init(openair0_device *device, openair0_config_t *openair0_cfg) {
         }
 
 
-        
+
         printf("Actual master clock: %fMHz...\n", (s->iris[r]->getMasterClockRate() / 1e6));
 
         int tx_filt_bw = openair0_cfg[0].tx_bw;
         int rx_filt_bw = openair0_cfg[0].rx_bw;
 #ifdef MOVE_DC  //the filter is centered around the carrier, so we have to expand it if we have moved the DC tone.
-        tx_filt_bw *= 3; 
-        rx_filt_bw *= 3; 
+        tx_filt_bw *= 3;
+        rx_filt_bw *= 3;
 #endif
         /* Setting TX/RX BW */
         for (i = 0; i < s->tx_num_channels; i++) {
@@ -848,8 +848,3 @@ int device_init(openair0_device *device, openair0_config_t *openair0_cfg) {
 }
 }
 /*@}*/
-
-
-
-
-
diff --git a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp
index bfdc80f9b5462af1997933c0f7f6857359a5c100..df4cc2ff02585274d5bcfc269c27738fddeb4e87 100644
--- a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp
+++ b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp
@@ -454,7 +454,7 @@ static int trx_usrp_write(openair0_device *device, openair0_timestamp timestamp,
     nsamps2 = (nsamps+3)>>2;
     int16x8_t buff_tx[2][nsamps2];
 #else
-    #error Unsupported CPU architecture, USRP device cannot be built   
+    #error Unsupported CPU architecture, USRP device cannot be built
 #endif
 
     // bring RX data into 12 LSBs for softmodem RX
diff --git a/targets/ARCH/rfsimulator/README.md b/targets/ARCH/rfsimulator/README.md
index 89964decd50e77c4f514c3207eefd3ae7612b747..ebe7d72ee05860907e1c3b5315bb84270d0879b6 100644
--- a/targets/ARCH/rfsimulator/README.md
+++ b/targets/ARCH/rfsimulator/README.md
@@ -1,26 +1,14 @@
-#General
+## General
+
 This is a RF simulator that allows to test OAI without a RF board.
 It replaces a actual RF board driver.
 
 As much as possible, it works like a RF board, but not in realtime: it can run faster than realtime if there is enough CPU or slower (it is CPU bound instead of real time RF sampling bound)
 
-#build
-
-## From build_oai
-You can build it the same way, and together with actual RF driver
+## build
 
-Example:
-```bash
-./build_oai --ue-nas-use-tun --UE --eNB -w SIMU
-```
-It is also possible to build actual RF and use choose on each run:
-```bash
-./build_oai --ue-nas-use-tun --UE --eNB -w USRP --rfsimulator
-```
-Will build both the eNB (lte-softmodem) and the UE (lte-uesoftmodem)
-We recommend to use the option --ue-nas-use-tun that is much simpler to use than the OAI kernel driver.
+ No specific build is required, use the [oai softmodem build procedure](../../../doc/BUILD.md)
 
-## Add the rfsimulator after initial build
 After any regular build, you can compile the driver
 ```bash
 cd <the_compilation_dir_from_bouild_oai_script>/build
@@ -35,16 +23,30 @@ It should the set to "enb" in the eNB
 ## 4G case
 For the UE, it should be set to the IP address of the eNB
 example: 
+
 ```bash
-sudo RFSIMULATOR=192.168.2.200 ./lte-uesoftmodem -C 2685000000 -r 50 
+sudo RFSIMULATOR=192.168.2.200 ./lte-uesoftmodem -C 2685000000 -r 50 --rfsim
 ```
+For the eNodeB, use a valid configuration file setup for USRP board tests and start the softmodem as usual, but adding the `--rfsim` option.
+
+
+
+```bash
+sudo RFSIMULATOR=enb ./lte-softmodem -O <config file> --rfsim
+```
+
+
+
 Except this, the UE and the eNB can be used as it the RF is real
 
 If you reach 'RA not active' on UE, be careful to generate a valid SIM
 ```bash
 $OPENAIR_DIR/targets/bin/conf2uedata -c $OPENAIR_DIR/openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf -o .
 ```
+This simulator can also be used with the `--noS1` option, in this case you must run the eNodeB and the UE on different PCs. 
+
 ## 5G case
+
 After regular build, add the simulation driver
 (don't use ./build_oai -w SIMU until we merge 4G and 5G branches)
 ```bash
@@ -62,7 +64,8 @@ sudo RFSIMULATOR=127.0.0.1 ./nr-uesoftmodem --numerology 1 -r 106 -C 3510000000
 Of course, set the gNB machine IP address if the UE and the gNB are not on the same machine
 In UE, you can add "-d" to get the softscope
 
-#Caveacts
+## Caveacts
+
 Still issues in power control: txgain, rxgain are not used
 
-no S1 mode is currently broken, so we were not able to test the simulator in noS1 mode
+
diff --git a/targets/COMMON/MESSAGES/V2/flexsplit.proto b/targets/COMMON/MESSAGES/V2/flexsplit.proto
new file mode 100644
index 0000000000000000000000000000000000000000..39f1656980a7da0bcda1df2d34a461a6c1df0705
--- /dev/null
+++ b/targets/COMMON/MESSAGES/V2/flexsplit.proto
@@ -0,0 +1,163 @@
+package protocol;
+
+
+message fsp_header {
+        optional uint32 version = 1;
+        optional uint32 type = 2;
+        optional uint32 xid = 4;
+}
+
+enum fsp_type {
+     // Discovery and maintenance messages
+     FSPT_HELLO = 0;
+     FSPT_ECHO_REQUEST = 1;
+     FSPT_ECHO_REPLY = 2;
+     FSPT_RLC_DATA_REQ = 3;
+     FSPT_RLC_DATA_REQ_ACK = 4;
+     FSPT_PDCP_DATA_IND = 5;
+     FSPT_PDCP_DATA_IND_ACK = 6;
+}
+
+enum f1u_type {
+     // Discovery and maintenance messages
+     F1U_DL_DATA = 0;
+     F1U_DL_STATUS = 1;
+}
+
+
+message f1u_message{
+     optional flexsplit_direction msg_dir = 100;
+     oneof msg{
+	dl_user_data dl_data = 1;
+        dl_data_delivery_status dl_status = 2;
+     }
+}
+
+
+
+message flexsplit_message {
+     optional flexsplit_direction msg_dir = 100;
+	oneof msg {
+              fsp_hello hello_msg = 1;
+              fsp_echo_request echo_request_msg = 2;
+              fsp_echo_reply echo_reply_msg = 3;
+              fspRlcDataReq data_req_msg = 4;
+	      fspRlcDataReqAck data_req_ack = 5;
+	      fspPdcpDataInd data_ind_msg = 6;
+	      fspPdcpDataIndAck data_ind_ack = 7;
+	}
+}
+
+enum flexsplit_direction {
+     //option allow_alias = true;
+     NOT_SET = 0;
+     INITIATING_MESSAGE = 1;
+     SUCCESSFUL_OUTCOME=2;
+     UNSUCCESSFUL_OUTCOME=3;	
+}
+
+enum flexsplit_err {
+	// message errors
+	NO_ERR = 0;	
+	MSG_DEQUEUING = -1;
+	MSG_ENQUEUING = -2;
+	MSG_DECODING = -3;
+	MSG_ENCODING = -4;
+	MSG_BUILD = -5;
+	MSG_NOT_SUPPORTED = -6; 
+	MSG_NOT_HANDLED = -7;
+	MSG_NOT_VALIDATED = -8;
+	MSG_OUT_DATED = -9;
+	
+	// other erros
+	UNEXPECTED = -100;	
+}
+
+message fsp_ctxt {
+        optional uint32 fsp_mod_id = 1;
+        optional bool fsp_enb_flag = 2;
+        optional uint32 fsp_instance = 3;
+        optional uint32 fsp_rnti = 4;
+        optional uint32 fsp_frame = 5;
+        optional uint32 fsp_subframe = 6;
+        optional uint32 fsp_eNB_index = 7;
+
+}
+
+message fspRlcPdu {
+        optional bytes fsp_pdu_data = 1; // Maximum PDU to be transfered
+}
+
+message fspRlcData {
+        optional fsp_ctxt fsp_ctxt = 1;
+        optional bool fsp_srb_flag = 2;
+        optional bool fsp_mbms_flag = 3;
+        optional uint32 fsp_rb_id = 4;
+        optional uint32 fsp_muip = 5;
+        optional uint32 fsp_confirm = 6;
+        optional int32 fsp_sdu_buffer_size = 7;
+        optional fspRlcPdu fsp_pdu = 8;
+}
+
+//
+// Maintenance and discovery messages
+//
+
+message fsp_hello {
+      optional fsp_header header = 1;
+}
+
+message fsp_echo_request {
+        optional fsp_header header = 1;
+//        extensions 100 to 199;
+}
+
+
+message fsp_echo_reply {
+        optional fsp_header header = 1;
+//        extensions 100 to 199;
+}
+
+
+message fspRlcDataReq {
+        optional fsp_header header = 1;
+	optional uint32 eNB_id = 2;
+        optional fspRlcData pdcp_data = 3;
+}
+
+message fspRlcDataReqAck {
+	optional fsp_header header = 1;
+	optional uint32 result = 2;
+}
+
+message fspPdcpDataInd {
+        optional fsp_header header = 1;
+	optional uint32 eNB_id = 2;
+        optional fspRlcData rlc_data = 3;
+}
+
+message fspPdcpDataIndAck {
+        optional fsp_header header = 1;
+	optional uint32 result = 2;
+}
+
+message dl_data_header {
+        required uint32 fields = 1;
+}
+
+message dl_user_data {
+	required dl_data_header header = 1;
+	required bytes pdu = 2;
+	required uint32 frame = 3;
+	required uint32 subframe = 4;
+	required uint32 rnti = 5;
+}
+
+
+message dl_data_delivery_status {
+	required dl_data_header header = 1;
+	required bytes pdu = 2;
+	required uint32 frame = 3;
+	required uint32 subframe = 4;
+	required uint32 rnti = 5;
+}
diff --git a/targets/COMMON/create_tasks.c b/targets/COMMON/create_tasks.c
index d2dd90b2b4c86e596045a1104570eb44e19847e8..cfc2bc22155235a41d439581d71d795450e53310 100644
--- a/targets/COMMON/create_tasks.c
+++ b/targets/COMMON/create_tasks.c
@@ -23,78 +23,73 @@
 # include "create_tasks.h"
 # include "common/utils/LOG/log.h"
 # include "targets/RT/USER/lte-softmodem.h"
+# include "common/ran_context.h"
 
 #ifdef OPENAIR2
-  #include "sctp_eNB_task.h"
-  #include "x2ap_eNB.h"
-  #include "s1ap_eNB.h"
-  #include "udp_eNB_task.h"
-  #include "gtpv1u_eNB_task.h"
+    #include "sctp_eNB_task.h"
+    #include "x2ap_eNB.h"
+    #include "s1ap_eNB.h"
+    #include "udp_eNB_task.h"
+    #include "gtpv1u_eNB_task.h"
   #if ENABLE_RAL
     #include "lteRALue.h"
     #include "lteRALenb.h"
   #endif
   #include "RRC/LTE/rrc_defs.h"
 #endif
+# include "f1ap_cu_task.h"
+# include "f1ap_du_task.h"
 # include "enb_app.h"
 
+extern RAN_CONTEXT_t RC;
 
 int create_tasks(uint32_t enb_nb) {
   LOG_D(ENB_APP, "%s(enb_nb:%d\n", __FUNCTION__, enb_nb);
-  itti_wait_ready(1);
+  ngran_node_t type = RC.rrc[0]->node_type;
+  int rc;
 
-  if (enb_nb > 0) {
-    /* Last task to create, others task must be ready before its start */
-    if (itti_create_task (TASK_ENB_APP, eNB_app_task, NULL) < 0) {
-      LOG_E(ENB_APP, "Create task for eNB APP failed\n");
-      return -1;
-    }
-  }
+  if (enb_nb == 0) return 0;
 
-  if (EPC_MODE_ENABLED) {
-    if (enb_nb > 0) {
-      if (is_x2ap_enabled()) {
-        if (itti_create_task (TASK_X2AP, x2ap_task, NULL) < 0) {
-          LOG_E(X2AP, "Create task for X2AP failed\n");
-          return -1;
-        }
-      } else
-        LOG_I(X2AP, "X2AP is disabled.\n");
+  LOG_I(ENB_APP, "Creating ENB_APP eNB Task\n");
+  rc = itti_create_task (TASK_ENB_APP, eNB_app_task, NULL);
+  AssertFatal(rc >= 0, "Create task for eNB APP failed\n");
 
-      if (itti_create_task (TASK_SCTP, sctp_eNB_task, NULL) < 0) {
-        LOG_E(SCTP, "Create task for SCTP failed\n");
-        return -1;
-      }
+  LOG_I(RRC,"Creating RRC eNB Task\n");
+  rc = itti_create_task (TASK_RRC_ENB, rrc_enb_task, NULL);
+  AssertFatal(rc >= 0, "Create task for RRC eNB failed\n");
 
-      if (itti_create_task (TASK_S1AP, s1ap_eNB_task, NULL) < 0) {
-        LOG_E(S1AP, "Create task for S1AP failed\n");
-        return -1;
-      }
+  if (EPC_MODE_ENABLED) {
+    rc = itti_create_task(TASK_SCTP, sctp_eNB_task, NULL);
+    AssertFatal(rc >= 0, "Create task for SCTP failed\n");
+  }
 
-      if(!(get_softmodem_params()->emulate_rf)) {
-        if (itti_create_task (TASK_UDP, udp_eNB_task, NULL) < 0) {
-          LOG_E(UDP_, "Create task for UDP failed\n");
-          return -1;
-        }
-      }
 
-      if (itti_create_task (TASK_GTPV1_U, &gtpv1u_eNB_task, NULL) < 0) {
-        LOG_E(GTPU, "Create task for GTPV1U failed\n");
-        return -1;
-      }
+  if (EPC_MODE_ENABLED && !NODE_IS_DU(type)) {
+    rc = itti_create_task(TASK_S1AP, s1ap_eNB_task, NULL);
+    AssertFatal(rc >= 0, "Create task for S1AP failed\n");
+    if (!(get_softmodem_params()->emulate_rf)){
+      rc = itti_create_task(TASK_UDP, udp_eNB_task, NULL);
+      AssertFatal(rc >= 0, "Create task for UDP failed\n");
     }
-  } /* if (EPC_MODE_ENABLED) */
+    rc = itti_create_task(TASK_GTPV1_U, gtpv1u_eNB_task, NULL);
+    AssertFatal(rc >= 0, "Create task for GTPV1U failed\n");
+    if (is_x2ap_enabled()) {
+      rc = itti_create_task(TASK_X2AP, x2ap_task, NULL);
+      AssertFatal(rc >= 0, "Create task for X2AP failed\n");
+    } else {
+      LOG_I(X2AP, "X2AP is disabled.\n");
+    }
+  }
 
-  if (enb_nb > 0) {
-    LOG_I(RRC,"Creating RRC eNB Task\n");
+  if (NODE_IS_CU(type)) {
+    rc = itti_create_task(TASK_CU_F1, F1AP_CU_task, NULL);
+    AssertFatal(rc >= 0, "Create task for CU F1AP failed\n");
+  }
 
-    if (itti_create_task (TASK_RRC_ENB, rrc_enb_task, NULL) < 0) {
-      LOG_E(RRC, "Create task for RRC eNB failed\n");
-      return -1;
-    }
+  if (NODE_IS_DU(type)) {
+    rc = itti_create_task(TASK_DU_F1, F1AP_DU_task, NULL);
+    AssertFatal(rc >= 0, "Create task for DU F1AP failed\n");
   }
 
-  itti_wait_ready(0);
   return 0;
 }
-
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/cu.lte.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/cu.lte.conf
new file mode 100644
index 0000000000000000000000000000000000000000..38d3f5eac94756b771e33575de9969b9ce42c55b
--- /dev/null
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/cu.lte.conf
@@ -0,0 +1,221 @@
+Active_eNBs = ( "eNB-CU-Eurecom-LTEBox");
+# Asn1_verbosity, choice in: none, info, annoying
+Asn1_verbosity = "none";
+
+eNBs = (
+  {
+    ////////// Identification parameters:
+    eNB_ID    = 0xe00;
+
+    cell_type = "CELL_MACRO_ENB";
+
+    eNB_name  = "eNB-CU-Eurecom-LTEBox";
+
+    // Tracking area code, 0x0000 and 0xfffe are reserved values
+    tracking_area_code = 1;
+    plmn_list = ( { mcc = 208; mnc = 95; mnc_length = 2; } )
+
+    nr_cellid = 12345678L
+
+    tr_s_preference  = "f1"
+
+    local_s_if_name  = "lo";
+    remote_s_address = "192.168.12.4";
+    local_s_address  = "192.168.12.45";
+    local_s_portc    = 501;
+    remote_s_portc   = 500;
+    local_s_portd    = 601;
+    remote_s_portd   = 600;
+
+    ////////// Physical parameters:
+
+    component_carriers = (
+      {
+        node_function                           = "3GPP_eNodeB";
+        node_timing                             = "synch_to_ext_device";
+        node_synch_ref                          = 0;
+        frame_type                              = "FDD";
+        tdd_config                              = 3;
+        tdd_config_s                            = 0;
+        prefix_type                             = "NORMAL";
+        eutra_band                              = 7;
+        downlink_frequency                      = 2665000000L;
+        uplink_frequency_offset                 = -120000000;
+        Nid_cell                                = 0;
+        N_RB_DL                                 = 50;
+        pbch_repetition                         = "FALSE";
+        prach_root                              = 0;
+        prach_config_index                      = 0;
+        prach_high_speed                        = "DISABLE";
+        prach_zero_correlation                  = 1;
+        prach_freq_offset                       = 2;
+        pucch_delta_shift                       = 1;
+        pucch_nRB_CQI                           = 0;
+        pucch_nCS_AN                            = 0;
+        pucch_n1_AN                             = 0;
+        pdsch_referenceSignalPower              = -27;
+        pdsch_p_b                               = 0;
+        pusch_n_SB                              = 1;
+        pusch_enable64QAM                       = "DISABLE";
+        pusch_hoppingMode                       = "interSubFrame";
+        pusch_hoppingOffset                     = 0;
+        pusch_groupHoppingEnable                = "ENABLE";
+        pusch_groupAssignment                   = 0;
+        pusch_sequenceHoppingEnabled            = "DISABLE";
+        pusch_nDMRS1                            = 1;
+        phich_duration                          = "NORMAL";
+        phich_resource                          = "ONESIXTH";
+        srs_enable                              = "DISABLE";
+        /*
+        srs_BandwidthConfig                     =;
+        srs_SubframeConfig                      =;
+        srs_ackNackST                           =;
+        srs_MaxUpPts                            =;
+        */
+
+        pusch_p0_Nominal                        = -96;
+        pusch_alpha                             = "AL1";
+        pucch_p0_Nominal                        = -104;
+        msg3_delta_Preamble                     = 6;
+        pucch_deltaF_Format1                    = "deltaF2";
+        pucch_deltaF_Format1b                   = "deltaF3";
+        pucch_deltaF_Format2                    = "deltaF0";
+        pucch_deltaF_Format2a                   = "deltaF0";
+        pucch_deltaF_Format2b                   = "deltaF0";
+
+        rach_numberOfRA_Preambles               = 64;
+        rach_preamblesGroupAConfig              = "DISABLE";
+        /*
+        rach_sizeOfRA_PreamblesGroupA           = ;
+        rach_messageSizeGroupA                  = ;
+        rach_messagePowerOffsetGroupB           = ;
+        */
+        rach_powerRampingStep                   = 4;
+        rach_preambleInitialReceivedTargetPower = -108;
+        rach_preambleTransMax                   = 10;
+        rach_raResponseWindowSize               = 10;
+        rach_macContentionResolutionTimer       = 48;
+        rach_maxHARQ_Msg3Tx                     = 4;
+
+        pcch_default_PagingCycle                = 128;
+        pcch_nB                                 = "oneT";
+        bcch_modificationPeriodCoeff= 2;
+        ue_TimersAndConstants_t300              = 1000;
+        ue_TimersAndConstants_t301              = 1000;
+        ue_TimersAndConstants_t310              = 1000;
+        ue_TimersAndConstants_t311              = 10000;
+        ue_TimersAndConstants_n310              = 20;
+        ue_TimersAndConstants_n311              = 1;
+        ue_TransmissionMode                     = 1;
+
+        //Parameters for SIB18
+        rxPool_sc_CP_Len                                       = "normal";
+        rxPool_sc_Period                                       = "sf40";
+        rxPool_data_CP_Len                                     = "normal";
+        rxPool_ResourceConfig_prb_Num                          = 20;
+        rxPool_ResourceConfig_prb_Start                        = 5;
+        rxPool_ResourceConfig_prb_End                          = 44;
+        rxPool_ResourceConfig_offsetIndicator_present          = "prSmall";
+        rxPool_ResourceConfig_offsetIndicator_choice           = 0;
+        rxPool_ResourceConfig_subframeBitmap_present           = "prBs40";
+        rxPool_ResourceConfig_subframeBitmap_choice_bs_buf              = "00000000000000000000";
+        rxPool_ResourceConfig_subframeBitmap_choice_bs_size             = 5;
+        rxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused      = 0;
+        /*
+        rxPool_dataHoppingConfig_hoppingParameter                       = 0;
+        rxPool_dataHoppingConfig_numSubbands                            = "ns1";
+        rxPool_dataHoppingConfig_rbOffset                               = 0;
+        rxPool_commTxResourceUC-ReqAllowed                              = "TRUE";
+        */
+
+        // Parameters for SIB19
+        discRxPool_cp_Len                                               = "normal"
+        discRxPool_discPeriod                                           = "rf32"
+        discRxPool_numRetx                                              = 1;
+        discRxPool_numRepetition                                        = 2;
+        discRxPool_ResourceConfig_prb_Num                               = 5;
+        discRxPool_ResourceConfig_prb_Start                             = 3;
+        discRxPool_ResourceConfig_prb_End                               = 21;
+        discRxPool_ResourceConfig_offsetIndicator_present               = "prSmall";
+        discRxPool_ResourceConfig_offsetIndicator_choice                = 0;
+        discRxPool_ResourceConfig_subframeBitmap_present                = "prBs40";
+        discRxPool_ResourceConfig_subframeBitmap_choice_bs_buf          = "f0ffffffff";
+        discRxPool_ResourceConfig_subframeBitmap_choice_bs_size         = 5;
+        discRxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused  = 0;
+      }
+    );
+
+
+    srb1_parameters :
+    {
+      # timer_poll_retransmit = (ms) [5, 10, 15, 20,... 250, 300, 350, ... 500]
+      timer_poll_retransmit    = 80;
+
+      # timer_reordering = (ms) [0,5, ... 100, 110, 120, ... ,200]
+      timer_reordering         = 35;
+
+      # timer_reordering = (ms) [0,5, ... 250, 300, 350, ... ,500]
+      timer_status_prohibit    = 0;
+
+      # poll_pdu = [4, 8, 16, 32 , 64, 128, 256, infinity(>10000)]
+      poll_pdu                 =  4;
+
+      # poll_byte = (kB) [25,50,75,100,125,250,375,500,750,1000,1250,1500,2000,3000,infinity(>10000)]
+      poll_byte                =  99999;
+
+      # max_retx_threshold = [1, 2, 3, 4 , 6, 8, 16, 32]
+      max_retx_threshold       =  4;
+    }
+
+    # ------- SCTP definitions
+    SCTP :
+    {
+      # Number of streams to use in input/output
+      SCTP_INSTREAMS  = 2;
+      SCTP_OUTSTREAMS = 2;
+    };
+
+
+    ////////// MME parameters:
+    mme_ip_address  = (
+      {
+        ipv4       = "127.0.1.10";
+        ipv6       = "192:168:30::17";
+        active     = "yes";
+        preference = "ipv4";
+      }
+    );
+
+    NETWORK_INTERFACES : {
+      ENB_INTERFACE_NAME_FOR_S1_MME = "lo";
+      ENB_IPV4_ADDRESS_FOR_S1_MME   = "127.0.1.30/24";
+      ENB_INTERFACE_NAME_FOR_S1U    = "lo";
+      ENB_IPV4_ADDRESS_FOR_S1U      = "127.0.1.30/24";
+      ENB_PORT_FOR_S1U              = 2152; # Spec 2152
+      ENB_IPV4_ADDRESS_FOR_X2C      = "127.0.1.30/24";
+      ENB_PORT_FOR_X2C              = 36422; # Spec 36422
+    };
+  }
+);
+
+log_config = {
+  global_log_level            = "info";
+  global_log_verbosity        = "medium";
+  pdcp_log_level              = "info";
+  pdcp_log_verbosity          = "high";
+  rrc_log_level               = "info";
+  rrc_log_verbosity           = "medium";
+  flexran_agent_log_level     = "info";
+  flexran_agent_log_verbosity = "medium";
+  gtp_log_level               = "info";
+  gtp_log_verbosity           = "medium";
+};
+
+NETWORK_CONTROLLER : {
+  FLEXRAN_ENABLED        = "yes";
+  FLEXRAN_INTERFACE_NAME = "lo";
+  FLEXRAN_IPV4_ADDRESS   = "127.0.0.1";
+  FLEXRAN_PORT           = 2210;
+  FLEXRAN_CACHE          = "/mnt/oai_agent_cache";
+  FLEXRAN_AWAIT_RECONF   = "no";
+};
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/du.lte.band7.10MHz.if4p5.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/du.lte.band7.10MHz.if4p5.conf
new file mode 100644
index 0000000000000000000000000000000000000000..8e786be5e9427af6de083dec009e3371f8e43e7a
--- /dev/null
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/du.lte.band7.10MHz.if4p5.conf
@@ -0,0 +1,119 @@
+Active_eNBs = ( "eNB-Eurecom-DU");
+# Asn1_verbosity, choice in: none, info, annoying
+Asn1_verbosity = "none";
+
+eNBs =
+(
+  {
+    ////////// Identification parameters:
+    eNB_CU_ID = 0xe00;
+
+    eNB_name  = "eNB-Eurecom-DU";
+
+    // Tracking area code, 0x0000 and 0xfffe are reserved values
+    tracking_area_code = 1;
+    plmn_list = ( { mcc = 208; mnc = 95; mnc_length = 2; } )
+
+    nr_cellid = 12345678L
+
+    ////////// Physical parameters:
+
+    component_carriers = (
+      {
+        node_function           = "3GPP_eNODEB";
+        node_timing             = "synch_to_ext_device";
+        node_synch_ref          = 0;
+        frame_type              = "FDD";
+        tdd_config              = 3;
+        tdd_config_s            = 0;
+        prefix_type             = "NORMAL";
+        eutra_band              = 7;
+        downlink_frequency      = 2665000000L;
+        uplink_frequency_offset = -120000000;
+        Nid_cell                = 0;
+        N_RB_DL                 = 50;
+        Nid_cell_mbsfn          = 0;
+        nb_antenna_ports        = 1;
+        nb_antennas_tx          = 1;
+        nb_antennas_rx          = 1;
+        tx_gain                 = 90;
+        rx_gain                 = 125;
+
+        pucch_deltaF_Format1    = "deltaF2";
+        pucch_deltaF_Format1b   = "deltaF3";
+        pucch_deltaF_Format2    = "deltaF0";
+        pucch_deltaF_Format2a   = "deltaF0";
+        pucch_deltaF_Format2b   = "deltaF0";
+      }
+    );
+
+
+    # ------- 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";
+    remote_n_address = "127.0.0.4";
+    local_n_address  = "127.0.0.3";
+    local_n_portc    = 500;
+    remote_n_portc   = 501;
+    local_n_portd    = 600;
+    remote_n_portd   = 601;
+  }
+);
+
+L1s = (
+  {
+    num_cc = 1;
+    tr_n_preference = "local_mac";
+  }
+);
+
+RUs = (
+  {
+    local_rf                      = "yes";
+    nb_tx                         = 1;
+    nb_rx                         = 1;
+    att_tx                        = 10;
+    att_rx                        = 10;
+    bands                         = [7];
+    max_pdschReferenceSignalPower = -27;
+    max_rxgain                    = 125;
+    eNB_instances                 = [0];
+  }
+);
+
+log_config = {
+  global_log_level            = "info";
+  global_log_verbosity        = "medium";
+  hw_log_level                = "info";
+  hw_log_verbosity            = "medium";
+  phy_log_level               = "info";
+  phy_log_verbosity           = "medium";
+  mac_log_level               = "info";
+  mac_log_verbosity           = "high";
+  rlc_log_level               = "info";
+  rlc_log_verbosity           = "medium";
+  flexran_agent_log_level     = "info";
+  flexran_agent_log_verbosity = "medium";
+};
+
+NETWORK_CONTROLLER : {
+  FLEXRAN_ENABLED        = "yes";
+  FLEXRAN_INTERFACE_NAME = "lo";
+  FLEXRAN_IPV4_ADDRESS   = "127.0.0.1";
+  FLEXRAN_PORT           = 2210;
+  FLEXRAN_CACHE          = "/mnt/oai_agent_cache";
+  FLEXRAN_AWAIT_RECONF   = "no";
+};
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band13.tm1.50PRB.emtc.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band13.tm1.50PRB.emtc.conf
index ca09ea6625e7b34ef73229cfe5506b1d883849b8..1f5aeaf777100ed1818b887615c7a07e4ee3949b 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band13.tm1.50PRB.emtc.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band13.tm1.50PRB.emtc.conf
@@ -49,22 +49,22 @@ eNBs =
       prach_freq_offset                         = 1;
       pucch_delta_shift                         = 1;
       pucch_nRB_CQI                             = 0;
-      pucch_nCS_AN                              = 0;    
+      pucch_nCS_AN                              = 0;
       pucch_n1_AN                               = 0;
       pdsch_referenceSignalPower                = -27;
       pdsch_p_b                                 = 0;
       pusch_n_SB                                = 1;
       pusch_enable64QAM                         = "DISABLE";
       pusch_hoppingMode                         = "interSubFrame";
-      pusch_hoppingOffset                       = 0; 
+      pusch_hoppingOffset                       = 0;
       pusch_groupHoppingEnabled                 = "ENABLE";
       pusch_groupAssignment                     = 0;
       pusch_sequenceHoppingEnabled              = "DISABLE";
       pusch_nDMRS1                              = 1;
       phich_duration                            = "NORMAL";
       phich_resource                            = "ONESIXTH";
-      srs_enable                                = "DISABLE"; 
-      /*  srs_BandwidthConfig                   =; 
+      srs_enable                                = "DISABLE";
+      /*  srs_BandwidthConfig                   =;
       srs_SubframeConfig                        =;
       srs_ackNackST                             =;
       srs_MaxUpPts                              =;*/
@@ -73,14 +73,14 @@ eNBs =
       pusch_alpha                               = "AL1";
       pucch_p0_Nominal                          = -104;
       msg3_delta_Preamble                       = 6;
-      pucch_deltaF_Format1                      = "deltaF2";             
-      pucch_deltaF_Format1b                     = "deltaF3";            
-      pucch_deltaF_Format2                      = "deltaF0";            
-      pucch_deltaF_Format2a                     = "deltaF0";            
-      pucch_deltaF_Format2b                     = "deltaF0";            
-
-      rach_numberOfRA_Preambles                 = "n64"; #64 
-      rach_preamblesGroupAConfig                = "DISABLE"; 
+      pucch_deltaF_Format1                      = "deltaF2";
+      pucch_deltaF_Format1b                     = "deltaF3";
+      pucch_deltaF_Format2                      = "deltaF0";
+      pucch_deltaF_Format2a                     = "deltaF0";
+      pucch_deltaF_Format2b                     = "deltaF0";
+
+      rach_numberOfRA_Preambles                 = "n64"; #64
+      rach_preamblesGroupAConfig                = "DISABLE";
       /*
       rach_sizeOfRA_PreamblesGroupA             = ;
       rach_messageSizeGroupA                    = ;
@@ -105,7 +105,7 @@ eNBs =
       ue_TransmissionMode                       = "tm1";
 
       # eMTC Parameters
-      emtc_parameters : 
+      emtc_parameters :
       {
           eMTC_configured                       = 1;
           #hyperSFN_r13                               = 0;
@@ -115,7 +115,7 @@ eNBs =
           #SIB1
           schedulingInfoSIB1_BR_r13                   = 4;
 
-          #system_info_value_tag_SI = 
+          #system_info_value_tag_SI =
           #(
           #    {
           #        systemInfoValueTagSi_r13 = 0;
@@ -124,7 +124,7 @@ eNBs =
 
           cellSelectionInfoCE_r13                     = "ENABLE";
           q_RxLevMinCE_r13                            = -70;
-          bandwidthReducedAccessRelatedInfo_r13       = "ENABLE"   
+          bandwidthReducedAccessRelatedInfo_r13       = "ENABLE"
           si_WindowLength_BR_r13                      = "ms20";    #0
           si_RepetitionPattern_r13                    = "everyRF"; #0
 
@@ -136,7 +136,7 @@ eNBs =
               }
          );
 
-          fdd_DownlinkOrTddSubframeBitmapBR_r13     = "subframePattern40-r13"; 
+          fdd_DownlinkOrTddSubframeBitmapBR_r13     = "subframePattern40-r13";
           fdd_DownlinkOrTddSubframeBitmapBR_val_r13 = 0xFFFFFFFFFF;
           startSymbolBR_r13                           = 2;
           si_HoppingConfigCommon_r13                  = "off"; #1; # Note: 1==OFF !
@@ -157,14 +157,14 @@ eNBs =
 
           rach_numberOfRA_Preambles                 = 60; #14
           rach_powerRampingStep                     = 4;
-          rach_preambleInitialReceivedTargetPower   = -110;           
+          rach_preambleInitialReceivedTargetPower   = -110;
           rach_preambleTransMax                     = 10;
           rach_raResponseWindowSize                 = 10;
           rach_macContentionResolutionTimer         = 64;
           rach_maxHARQ_Msg3Tx                       = 4;
 
           # max size for this array is 4
-          rach_CE_LevelInfoList_r13 = 
+          rach_CE_LevelInfoList_r13 =
           (
               {
                   firstPreamble_r13                 = 60;
@@ -175,7 +175,7 @@ eNBs =
               }
           );
 
-          # BCCH CONFIG          
+          # BCCH CONFIG
           bcch_modificationPeriodCoeff              = 2;
 
           #PCCH Config
@@ -189,7 +189,7 @@ eNBs =
           prach_zero_correlation                    = 1;
           prach_freq_offset                         = 1;
 
-          #PDSCH Config Common          
+          #PDSCH Config Common
           pdsch_referenceSignalPower                = -27
           pdsch_p_b                                 = 0;
 
@@ -213,22 +213,22 @@ eNBs =
           pusch_p0_Nominal                          = -96;
           pusch_alpha                               = "AL1";
           pucch_p0_Nominal                          = -104;
-          pucch_deltaF_Format1                      = "deltaF0"; 
-          pucch_deltaF_Format1b                     = "deltaF3";            
-          pucch_deltaF_Format2                      = "deltaF0";           
-          pucch_deltaF_Format2a                     = "deltaF0";            
+          pucch_deltaF_Format1                      = "deltaF0";
+          pucch_deltaF_Format1b                     = "deltaF3";
+          pucch_deltaF_Format2                      = "deltaF0";
+          pucch_deltaF_Format2a                     = "deltaF0";
           pucch_deltaF_Format2b                     = "deltaF0";
 
           msg3_delta_Preamble                       = 6;
 
 
           prach_ConfigCommon_v1310                  = "ENABLE";
- 
+
           mpdcch_startSF_CSS_RA_r13                 = "fdd-r13";
           mpdcch_startSF_CSS_RA_r13_val             = "v1"; #0
           prach_HoppingOffset_r13                   = 0;
 
-         
+
           pdsch_maxNumRepetitionCEmodeA_r13         = "r16"; #0
           #pdsch_maxNumRepetitionCEmodeB_r13         = "r384"; # NULL - 2
 
@@ -245,7 +245,7 @@ eNBs =
           );
 
           # max size for this array is 4
-          prach_parameters_ce_r13 = 
+          prach_parameters_ce_r13 =
           (
               {
                   prach_config_index_br                     = 3;
@@ -255,17 +255,17 @@ eNBs =
                   numRepetitionPerPreambleAttempt_r13       = 1;  #0
                   mpdcch_NumRepetition_RA_r13               = 1;  #0
                   prach_HoppingConfig_r13                   = 0;  #1
-                  max_available_narrow_band                 = [3]; 
+                  max_available_narrow_band                 = [3];
              }
           );
 
-          n1PUCCH_AN_InfoList_r13 = 
+          n1PUCCH_AN_InfoList_r13 =
           (
               {
                   pucch_info_value = 33;
               }
           );
-          
+
 
           ue_TimersAndConstants_t300                = "ms1000";
           ue_TimersAndConstants_t301                = "ms400";
@@ -283,21 +283,21 @@ eNBs =
           }
 
 
-          pucch_NumRepetitionCE_Msg4_Level0_r13      = "n1";  #0 
+          pucch_NumRepetitionCE_Msg4_Level0_r13      = "n1";  #0
           #pucch_NumRepetitionCE_Msg4_Level1_r13     = "n2";  #1
           #pucch_NumRepetitionCE_Msg4_Level2_r13     = "n16"; #2
           #pucch_NumRepetitionCE_Msg4_Level3_r13     = "n32"; #3
 
-          sib2_freq_hoppingParameters_r13 : 
+          sib2_freq_hoppingParameters_r13 :
           {
              #sib2_mpdcch_pdsch_hoppingNB_r13                   = "nb2"; #0
              #sib2_interval_DLHoppingConfigCommonModeA_r13      = "FDD"; # choice -> (0, FDD) (1, TDD)
-             #sib2_interval_DLHoppingConfigCommonModeA_r13_val  = "int1";          
+             #sib2_interval_DLHoppingConfigCommonModeA_r13_val  = "int1";
              #sib2_interval_DLHoppingConfigCommonModeB_r13      = "FDD"; # choice -> (0, FDD) (1, TDD)
-             #sib2_interval_DLHoppingConfigCommonModeB_r13_val  = "int2";        
+             #sib2_interval_DLHoppingConfigCommonModeB_r13_val  = "int2";
 
              sib2_interval_ULHoppingConfigCommonModeA_r13      = "FDD";  # choice -> (0, FDD) (1, TDD)
-             sib2_interval_ULHoppingConfigCommonModeA_r13_val  = "int4"; #2          
+             sib2_interval_ULHoppingConfigCommonModeA_r13_val  = "int4"; #2
 #            sib2_interval_ULHoppingConfigCommonModeB_r13      = "FDD";  # choice -> (0, FDD) (1, TDD)
 #            sib2_interval_ULHoppingConfigCommonModeB_r13_val  = "int2"; #0
 
@@ -305,11 +305,11 @@ eNBs =
           }
 
           rach_preamblesGroupAConfig                = "DISABLE";
-          
+
           phich_duration                            = "NORMAL";
           phich_resource                            = "ONESIXTH";
           srs_enable                                = "DISABLE";
-          
+
       }
 
 
@@ -399,25 +399,25 @@ eNBs =
 );
 
 MACRLCs = (
-        {	
+        {
         num_cc	 = 1;
         tr_s_preference = "local_L1";
         tr_n_preference = "local_RRC";
 	phy_test_mode = 0;
         puSch10xSnr     =  200;
         puCch10xSnr     =  200;
-        }  
+        }
 );
 
 L1s = (
       {
       num_cc = 1;
       tr_n_preference = "local_mac";
-      }  
+      }
 );
 
 RUs = (
-    {     
+    {
         local_rf       = "yes"
         nb_tx          = 1
         nb_rx          = 1
@@ -428,7 +428,7 @@ RUs = (
         max_rxgain                    = 125;
         eNB_instances  = [0];
     }
-);  
+);
 
 log_config :
      {
@@ -447,4 +447,3 @@ log_config :
        rrc_log_level                         ="info";
        rrc_log_verbosity                     ="medium";
     };
-
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band38.tm1.25PRB.iris030.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band38.tm1.25PRB.iris030.conf
index 372c853b29cdd16bec3ebdaca7fe7ec2260fd60f..addd70ca712f7e25f01ea6dc01eb5f361557e14f 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band38.tm1.25PRB.iris030.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band38.tm1.25PRB.iris030.conf
@@ -205,18 +205,18 @@ MACRLCs = (
         phy_test_mode = 0;
         puSch10xSnr     =  200;
         puCch10xSnr     =  200;
-        }  
+        }
 );
 
 L1s = (
             {
         num_cc = 1;
         tr_n_preference = "local_mac";
-        }  
+        }
 );
 
 RUs = (
-    {                  
+    {
        local_rf       = "yes"
          nb_tx          = 1
          nb_rx          = 1
@@ -228,7 +228,7 @@ RUs = (
          eNB_instances  = [0];
          #sdr_addrs = "RF3C000025";
     }
-);  
+);
 
 NETWORK_CONTROLLER :
 {
@@ -266,4 +266,3 @@ THREAD_STRUCT = (
        rrc_log_level                         ="info";
        rrc_log_verbosity                     ="medium";
     };
-
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band42.tm1.25PRB.iris030.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band42.tm1.25PRB.iris030.conf
index c55c58e1a727104818c5427fed69e4f4098aa32f..201a0c1839a10abf6cdb4e0a7c2ed9772835c736 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band42.tm1.25PRB.iris030.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band42.tm1.25PRB.iris030.conf
@@ -205,18 +205,18 @@ MACRLCs = (
 	phy_test_mode = 0;
         puSch10xSnr     =  200;
         puCch10xSnr     =  200;
-        }  
+        }
 );
 
 L1s = (
-    	{
+      {
 	num_cc = 1;
 	tr_n_preference = "local_mac";
-        }  
+        }
 );
 
 RUs = (
-    {		  
+    {
        local_rf       = "yes"
          nb_tx          = 1;
          nb_rx          = 1;
@@ -228,7 +228,7 @@ RUs = (
          eNB_instances  = [0];
          #sdr_addrs = "RF3E000025";
     }
-);  
+);
 
 NETWORK_CONTROLLER :
 {
@@ -266,4 +266,3 @@ THREAD_STRUCT = (
        rrc_log_level                         ="info";
        rrc_log_verbosity                     ="medium";
     };
-
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.iris030.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.iris030.conf
index 5882c1b168015206e3a6d606500a27088c2fb3c9..3507906affeb8abd3a1d112f2029cbc987a74faa 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.iris030.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.iris030.conf
@@ -205,18 +205,18 @@ MACRLCs = (
         phy_test_mode = 0;
         puSch10xSnr     =  200;
         puCch10xSnr     =  200;
-        }  
+        }
 );
 
 L1s = (
             {
         num_cc = 1;
         tr_n_preference = "local_mac";
-        }  
+        }
 );
 
 RUs = (
-    {                  
+    {
        local_rf       = "yes"
          nb_tx          = 1
          nb_rx          = 1
@@ -228,7 +228,7 @@ RUs = (
          eNB_instances  = [0];
          sdr_addrs = "RF3E000028";
     }
-);  
+);
 
 NETWORK_CONTROLLER :
 {
@@ -266,4 +266,3 @@ THREAD_STRUCT = (
        rrc_log_level                         ="info";
        rrc_log_verbosity                     ="medium";
     };
-
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.usrpb210.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.usrpb210.conf
index 142b9625983197d6aee2e0a55d43935910382a6e..4b3ac5ffad271d03d782ce1249249fe3ad9c3f1a 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.usrpb210.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.usrpb210.conf
@@ -172,7 +172,7 @@ eNBs =
 
 
     ////////// MME parameters:
-    mme_ip_address      = ( { ipv4       = "192.168.12.26";
+    mme_ip_address      = ( { ipv4       = "10.64.93.19";
                               ipv6       = "192:168:30::17";
                               active     = "yes";
                               preference = "ipv4";
@@ -186,18 +186,47 @@ eNBs =
 
     NETWORK_INTERFACES :
     {
-        ENB_INTERFACE_NAME_FOR_S1_MME            = "eth0";
-        ENB_IPV4_ADDRESS_FOR_S1_MME              = "192.168.12.111/24";
-        ENB_INTERFACE_NAME_FOR_S1U               = "eth0";
-        ENB_IPV4_ADDRESS_FOR_S1U                 = "192.168.12.111/24";
+        ENB_INTERFACE_NAME_FOR_S1_MME            = "eno1";
+        ENB_IPV4_ADDRESS_FOR_S1_MME              = "10.64.45.62/23";
+        ENB_INTERFACE_NAME_FOR_S1U               = "eno1";
+        ENB_IPV4_ADDRESS_FOR_S1U                 = "10.64.45.62/23";
         ENB_PORT_FOR_S1U                         = 2152; # Spec 2152
 
         ENB_IPV4_ADDRESS_FOR_X2C                 = "192.168.12.111/24";
         ENB_PORT_FOR_X2C                         = 36422; # Spec 36422
-    };
+    }; 
+    
   }
 );
 
+DU = (
+    {
+	DU_INTERFACE_NAME_FOR_F1U           = "lo";
+	DU_IPV4_ADDRESS_FOR_F1U             = "127.0.0.1/16";
+	DU_PORT_FOR_F1U                     = 22100;
+	F1_U_DU_TRANSPORT_TYPE		    = "TCP";
+    }
+    );
+    
+CU = (
+    {     
+        CU_INTERFACE_NAME_FOR_F1U           = "lo";
+        CU_IPV4_ADDRESS_FOR_F1U             = "127.0.0.1";   //Address to search the DU
+        CU_PORT_FOR_F1U                     = 22100;
+        F1_U_CU_TRANSPORT_TYPE              = "TCP";	     // One of TCP/UDP/SCTP
+        DU_TYPE 			    = "LTE";
+    }//,
+//    {     
+//        CU_INTERFACE_NAME_FOR_F1U           = "eth0";
+//        CU_IPV4_ADDRESS_FOR_F1U             = "10.64.93.142";   //Address to search the DU
+//        CU_PORT_FOR_F1U                     = 2211;
+//        F1_U_CU_TRANSPORT_TYPE              = "TCP";          // One of TCP/UDP/SCTP
+//        DU_TYPE 			    = "WiFi";
+//    }
+    );
+
+    CU_BALANCING = "ALL";
+
 MACRLCs = (
 	{
 	num_cc = 1;
diff --git a/targets/RT/USER/lte-ru.c b/targets/RT/USER/lte-ru.c
index 787e630d17658b0cb76cf8abc874e8f5dc1717e5..d4c53441d64bf267f303eadf24bff417485abf3c 100644
--- a/targets/RT/USER/lte-ru.c
+++ b/targets/RT/USER/lte-ru.c
@@ -818,7 +818,6 @@ void tx_rf(RU_t *ru) {
     T_INT(0), T_BUFFER(&ru->common.txdata[0][proc->subframe_tx * fp->samples_per_tti], fp->samples_per_tti * 4));
   lte_subframe_t SF_type     = subframe_select(fp,proc->subframe_tx%10);
   lte_subframe_t prevSF_type = subframe_select(fp,(proc->subframe_tx+9)%10);
-  lte_subframe_t nextSF_type = subframe_select(fp,(proc->subframe_tx+1)%10);
   int sf_extension = 0;
 
   if ((SF_type == SF_DL) ||
@@ -826,24 +825,24 @@ void tx_rf(RU_t *ru) {
     int siglen=fp->samples_per_tti,flags=1;
 
     if (SF_type == SF_S) {
-      siglen = fp->dl_symbols_in_S_subframe*(fp->ofdm_symbol_size+fp->nb_prefix_samples0);
+      /* end_of_burst_delay is used to stop TX only "after a while".
+       * If we stop right after effective signal, with USRP B210 and
+       * B200mini, we observe a high EVM on the S subframe (on the
+       * PSS).
+       * A value of 400 (for 30.72MHz) solves this issue. This is
+       * the default.
+       */
+      siglen = (fp->ofdm_symbol_size + fp->nb_prefix_samples0)
+               + (fp->dl_symbols_in_S_subframe - 1) * (fp->ofdm_symbol_size + fp->nb_prefix_samples)
+               + ru->end_of_burst_delay;
       flags=3; // end of burst
     }
 
-    if ((fp->frame_type == TDD) &&
-        (SF_type == SF_DL)&&
-        (prevSF_type == SF_UL) &&
-        (nextSF_type == SF_DL)) {
+    if (fp->frame_type == TDD &&
+        SF_type == SF_DL &&
+        prevSF_type == SF_UL) {
       flags = 2; // start of burst
-      sf_extension = ru->N_TA_offset;
-    }
-
-    if ((fp->frame_type == TDD) &&
-        (SF_type == SF_DL)&&
-        (prevSF_type == SF_UL) &&
-        (nextSF_type == SF_UL)) {
-      flags = 4; // start of burst and end of burst (only one DL SF between two UL)
-      sf_extension = ru->N_TA_offset;
+      sf_extension = ru->sf_extension;
     }
 
 #if defined(__x86_64) || defined(__i386__)
@@ -1386,6 +1385,22 @@ int setup_RU_buffers(RU_t *ru) {
        * TODO: find a proper cleaner solution
        */
       ru->N_TA_offset = 0;
+
+    if      (frame_parms->N_RB_DL == 100) /* no scaling to do */;
+    else if (frame_parms->N_RB_DL == 50) {
+      ru->sf_extension       /= 2;
+      ru->end_of_burst_delay /= 2;
+    } else if (frame_parms->N_RB_DL == 25) {
+      ru->sf_extension       /= 4;
+      ru->end_of_burst_delay /= 4;
+    } else {
+      printf("not handled, todo\n");
+      exit(1);
+    }
+  } else {
+    ru->N_TA_offset = 0;
+    ru->sf_extension = 0;
+    ru->end_of_burst_delay = 0;
   }
 
   if (ru->openair0_cfg.mmapped_dma == 1) {
@@ -2883,6 +2898,9 @@ void RCconfig_RU(void) {
         RC.ru[j]->max_pdschReferenceSignalPower     = *(RUParamList.paramarray[j][RU_MAX_RS_EPRE_IDX].uptr);;
         RC.ru[j]->max_rxgain                        = *(RUParamList.paramarray[j][RU_MAX_RXGAIN_IDX].uptr);
         RC.ru[j]->num_bands                         = RUParamList.paramarray[j][RU_BAND_LIST_IDX].numelt;
+        /* sf_extension is in unit of samples for 30.72MHz here, has to be scaled later */
+        RC.ru[j]->sf_extension                      = *(RUParamList.paramarray[j][RU_SF_EXTENSION_IDX].uptr);
+        RC.ru[j]->end_of_burst_delay                = *(RUParamList.paramarray[j][RU_END_OF_BURST_DELAY_IDX].uptr);
 
         for (i=0; i<RC.ru[j]->num_bands; i++) RC.ru[j]->band[i] = RUParamList.paramarray[j][RU_BAND_LIST_IDX].iptr[i];
       } //strcmp(local_rf, "yes") == 0
diff --git a/targets/RT/USER/lte-softmodem.c b/targets/RT/USER/lte-softmodem.c
index 15553c0af37f956c37d930389238d9bf1bc89acc..aa8d832ed3e97f97e51c2e8bc89a0d51c359b030 100644
--- a/targets/RT/USER/lte-softmodem.c
+++ b/targets/RT/USER/lte-softmodem.c
@@ -653,87 +653,106 @@ int main( int argc, char **argv ) {
   LOG_I(HW, "Version: %s\n", PACKAGE_VERSION);
   printf("Runtime table\n");
   fill_modeled_runtime_table(runtime_phy_rx,runtime_phy_tx);
-  uint32_t pdcp_initmask = ( IS_SOFTMODEM_NOS1 )? ( PDCP_USE_NETLINK_BIT | LINK_ENB_PDCP_TO_IP_DRIVER_BIT) : LINK_ENB_PDCP_TO_GTPV1U_BIT;
-#
 
+  /* Read configuration */
+  if (RC.nb_inst > 0)
+    read_config_and_init();
+  
+  /* Start the agent. If it is turned off in the configuration, it won't start */
+  RCconfig_flexran();
+  for (i = 0; i < RC.nb_inst; i++) {
+    flexran_agent_start(i);
+  }
+
+  uint32_t pdcp_initmask = ( IS_SOFTMODEM_NOS1 )? ( PDCP_USE_NETLINK_BIT | LINK_ENB_PDCP_TO_IP_DRIVER_BIT) : LINK_ENB_PDCP_TO_GTPV1U_BIT;
   if ( IS_SOFTMODEM_NOS1)
     pdcp_initmask = pdcp_initmask | ENB_NAS_USE_TUN_BIT | SOFTMODEM_NOKRNMOD_BIT  ;
 
   pdcp_module_init(pdcp_initmask);
 
   if (RC.nb_inst > 0)  {
-    // don't create if node doesn't connect to RRC/S1/GTP
+
     if (create_tasks(1) < 0) {
       printf("cannot create ITTI tasks\n");
-      exit(-1); // need a softer mode
+      exit(-1);
     }
 
-    printf("ITTI tasks created\n");
-  } else {
+    for (int enb_id = 0; enb_id < RC.nb_inst; enb_id++) {
+      MessageDef *msg_p = itti_alloc_new_message (TASK_ENB_APP, RRC_CONFIGURATION_REQ);
+      RRC_CONFIGURATION_REQ(msg_p) = RC.rrc[enb_id]->configuration;
+      itti_send_msg_to_task (TASK_RRC_ENB, ENB_MODULE_ID_TO_INSTANCE(enb_id), msg_p);
+    }
+  }
+  else {
     printf("No ITTI, Initializing L1\n");
     RCconfig_L1();
   }
 
-  /* Start the agent. If it is turned off in the configuration, it won't start */
-  RCconfig_flexran();
-
-  for (i = 0; i < RC.nb_L1_inst; i++) {
-    flexran_agent_start(i);
+  if (RC.nb_inst > 0 && NODE_IS_CU(RC.rrc[0]->node_type)) {
+    protocol_ctxt_t ctxt;
+    ctxt.module_id = 0 ;
+    ctxt.instance = 0;
+    ctxt.rnti = 0;
+    ctxt.enb_flag = 1;
+    pdcp_run(&ctxt);
   }
 
-  // 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)*MAX_MOBILES_PER_ENB*MAX_NUM_CCs);
-  mlockall(MCL_CURRENT | MCL_FUTURE);
-  pthread_cond_init(&sync_cond,NULL);
-  pthread_mutex_init(&sync_mutex, NULL);
+  /* start threads if only L1 or not a CU */
+  if (RC.nb_inst == 0 || !NODE_IS_CU(RC.rrc[0]->node_type)) {
+    // 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)*MAX_MOBILES_PER_ENB*MAX_NUM_CCs);
+    mlockall(MCL_CURRENT | MCL_FUTURE);
+    pthread_cond_init(&sync_cond,NULL);
+    pthread_mutex_init(&sync_mutex, NULL);
+    
 #ifdef XFORMS
-  int UE_id;
-  printf("XFORMS\n");
-
-  if (get_softmodem_params()->do_forms==1) {
-    fl_initialize (&argc, argv, NULL, 0, 0);
-    form_stats_l2 = create_form_stats_form();
-    fl_show_form (form_stats_l2->stats_form, FL_PLACE_HOTSPOT, FL_FULLBORDER, "l2 stats");
-    form_stats = create_form_stats_form();
-    fl_show_form (form_stats->stats_form, FL_PLACE_HOTSPOT, FL_FULLBORDER, "stats");
-
-    for(UE_id=0; UE_id<scope_enb_num_ue; UE_id++) {
-      for(CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
-        form_enb[CC_id][UE_id] = create_lte_phy_scope_enb();
-        sprintf (title, "LTE UL SCOPE eNB for CC_id %d, UE %d",CC_id,UE_id);
-        fl_show_form (form_enb[CC_id][UE_id]->lte_phy_scope_enb, FL_PLACE_HOTSPOT, FL_FULLBORDER, title);
-
-        if (otg_enabled) {
-          fl_set_button(form_enb[CC_id][UE_id]->button_0,1);
-          fl_set_object_label(form_enb[CC_id][UE_id]->button_0,"DL Traffic ON");
-        } else {
-          fl_set_button(form_enb[CC_id][UE_id]->button_0,0);
-          fl_set_object_label(form_enb[CC_id][UE_id]->button_0,"DL Traffic OFF");
-        }
-      } // CC_id
-    } // UE_id
-
-    ret = pthread_create(&forms_thread, NULL, scope_thread, NULL);
-
-    if (ret == 0)
-      pthread_setname_np( forms_thread, "xforms" );
-
-    printf("Scope thread created, ret=%d\n",ret);
-  }
-
+    int UE_id;
+    printf("XFORMS\n");
+
+    if (get_softmodem_params()->do_forms==1) {
+      fl_initialize (&argc, argv, NULL, 0, 0);
+      form_stats_l2 = create_form_stats_form();
+      fl_show_form (form_stats_l2->stats_form, FL_PLACE_HOTSPOT, FL_FULLBORDER, "l2 stats");
+      form_stats = create_form_stats_form();
+      fl_show_form (form_stats->stats_form, FL_PLACE_HOTSPOT, FL_FULLBORDER, "stats");
+
+      for(UE_id=0; UE_id<scope_enb_num_ue; UE_id++) {
+        for(CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
+          form_enb[CC_id][UE_id] = create_lte_phy_scope_enb();
+          sprintf (title, "LTE UL SCOPE eNB for CC_id %d, UE %d",CC_id,UE_id);
+          fl_show_form (form_enb[CC_id][UE_id]->lte_phy_scope_enb, FL_PLACE_HOTSPOT, FL_FULLBORDER, title);
+
+          if (otg_enabled) {
+            fl_set_button(form_enb[CC_id][UE_id]->button_0,1);
+            fl_set_object_label(form_enb[CC_id][UE_id]->button_0,"DL Traffic ON");
+          } else {
+            fl_set_button(form_enb[CC_id][UE_id]->button_0,0);
+            fl_set_object_label(form_enb[CC_id][UE_id]->button_0,"DL Traffic OFF");
+          }
+        } // CC_id
+      } // UE_id
+
+      ret = pthread_create(&forms_thread, NULL, scope_thread, NULL);
+
+      if (ret == 0)
+        pthread_setname_np( forms_thread, "xforms" );
+
+      printf("Scope thread created, ret=%d\n",ret);
+    }
 #endif
-  rt_sleep_ns(10*100000000ULL);
+    
+    rt_sleep_ns(10*100000000ULL);
 
-  if (nfapi_mode) {
+    if (nfapi_mode) {
     LOG_I(ENB_APP,"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>";
+      pthread_cond_init(&sync_cond,NULL);
+      pthread_mutex_init(&sync_mutex, NULL);
+    }
 
-  switch(nfapi_mode) {
+    const char *nfapi_mode_str = "<UNKNOWN>";
+    
+    switch(nfapi_mode) {
     case 0:
       nfapi_mode_str = "MONOLITHIC";
       break;
@@ -749,76 +768,78 @@ int main( int argc, char **argv ) {
     default:
       nfapi_mode_str = "<UNKNOWN NFAPI MODE>";
       break;
-  }
+    }
 
-  LOG_I(ENB_APP,"NFAPI MODE:%s\n", nfapi_mode_str);
+    LOG_I(ENB_APP,"NFAPI MODE:%s\n", nfapi_mode_str);
 
-  if (nfapi_mode==2) {// VNF
+    if (nfapi_mode==2) {// VNF
 #if defined(PRE_SCD_THREAD)
-    init_ru_vnf();  // ru pointer is necessary for pre_scd.
+      init_ru_vnf();  // ru pointer is necessary for pre_scd.
 #endif
-    wait_nfapi_init("main?");
-  }
+      wait_nfapi_init("main?");
+    }
 
   LOG_I(ENB_APP,"START MAIN THREADS\n");
-  // start the main threads
-  number_of_cards = 1;
-  printf("RC.nb_L1_inst:%d\n", RC.nb_L1_inst);
-
-  if (RC.nb_L1_inst > 0) {
-    printf("Initializing eNB threads single_thread_flag:%d wait_for_sync:%d\n", get_softmodem_params()->single_thread_flag,get_softmodem_params()->wait_for_sync);
-    init_eNB(get_softmodem_params()->single_thread_flag,get_softmodem_params()->wait_for_sync);
-    //      for (inst=0;inst<RC.nb_L1_inst;inst++)
-    //  for (CC_id=0;CC_id<RC.nb_L1_CC[inst];CC_id++) phy_init_lte_eNB(RC.eNB[inst][CC_id],0,0);
-  }
+    // start the main threads
+    number_of_cards = 1;
+    printf("RC.nb_L1_inst:%d\n", RC.nb_L1_inst);
+
+    if (RC.nb_L1_inst > 0) {
+      printf("Initializing eNB threads single_thread_flag:%d wait_for_sync:%d\n", get_softmodem_params()->single_thread_flag,get_softmodem_params()->wait_for_sync);
+      init_eNB(get_softmodem_params()->single_thread_flag,get_softmodem_params()->wait_for_sync);
+      //      for (inst=0;inst<RC.nb_L1_inst;inst++)
+      //  for (CC_id=0;CC_id<RC.nb_L1_CC[inst];CC_id++) phy_init_lte_eNB(RC.eNB[inst][CC_id],0,0);
+    }
 
-  printf("wait_eNBs()\n");
-  wait_eNBs();
-  printf("About to Init RU threads RC.nb_RU:%d\n", RC.nb_RU);
+    printf("wait_eNBs()\n");
+    wait_eNBs();
+    printf("About to Init RU threads RC.nb_RU:%d\n", RC.nb_RU);
 
-  // RU thread and some L1 procedure aren't necessary in VNF or L2 FAPI simulator.
-  // but RU thread deals with pre_scd and this is necessary in VNF and simulator.
-  // some initialization is necessary and init_ru_vnf do this.
-  if (RC.nb_RU >0 && nfapi_mode != 2) {
-    printf("Initializing RU threads\n");
-    init_RU(get_softmodem_params()->rf_config_file);
+    // RU thread and some L1 procedure aren't necessary in VNF or L2 FAPI simulator.
+    // but RU thread deals with pre_scd and this is necessary in VNF and simulator.
+    // some initialization is necessary and init_ru_vnf do this.
+    if (RC.nb_RU >0 && nfapi_mode != 2) {
+      printf("Initializing RU threads\n");
+      init_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+(get_softmodem_params()->chain_offset);
+        RC.ru[ru_id]->rf_map.card=0;
+        RC.ru[ru_id]->rf_map.chain=CC_id+(get_softmodem_params()->chain_offset);
+      }
     }
-  }
 
-  config_sync_var=0;
+    config_sync_var=0;
 
-  if (nfapi_mode==1) { // PNF
-    wait_nfapi_init("main?");
-  }
+    if (nfapi_mode==1) { // PNF
+      wait_nfapi_init("main?");
+    }
 
-  printf("wait RUs\n");
-  fflush(stdout);
-  fflush(stderr);
-  wait_RUs();
+    printf("wait RUs\n");
+    fflush(stdout);
+    fflush(stderr);
+    wait_RUs();
   LOG_I(ENB_APP,"RC.nb_RU:%d\n", RC.nb_RU);
-  // once all RUs are ready intiailize the rest of the eNBs ((dependence on final RU parameters after configuration)
-  printf("ALL RUs ready - init eNBs\n");
+    // once all RUs are ready intiailize the rest of the eNBs ((dependence on final RU parameters after configuration)
+    printf("ALL RUs ready - init eNBs\n");
 
-  if (nfapi_mode != 1 && nfapi_mode != 2) {
+    if (nfapi_mode != 1 && nfapi_mode != 2) {
     LOG_I(ENB_APP,"Not NFAPI mode - call init_eNB_afterRU()\n");
-    init_eNB_afterRU();
-  } else {
+      init_eNB_afterRU();
+    } else {
     LOG_I(ENB_APP,"NFAPI mode - DO NOT call init_eNB_afterRU()\n");
-  }
+    }
 
   LOG_UI(ENB_APP,"ALL RUs ready - ALL eNBs ready\n");
-  // connect the TX/RX buffers
-  sleep(1); /* wait for thread activation */
+    // connect the TX/RX buffers
+    sleep(1); /* wait for thread activation */
   LOG_I(ENB_APP,"Sending sync to all threads\n");
-  pthread_mutex_lock(&sync_mutex);
-  sync_var=0;
-  pthread_cond_broadcast(&sync_cond);
-  pthread_mutex_unlock(&sync_mutex);
-  config_check_unknown_cmdlineopt(CONFIG_CHECKALLSECTIONS);
+    pthread_mutex_lock(&sync_mutex);
+    sync_var=0;
+    pthread_cond_broadcast(&sync_cond);
+    pthread_mutex_unlock(&sync_mutex);
+    config_check_unknown_cmdlineopt(CONFIG_CHECKALLSECTIONS);
+  }
+
   // wait for end of program
   LOG_UI(ENB_APP,"TYPE <CTRL-C> TO TERMINATE\n");
   //getchar();
@@ -826,59 +847,60 @@ int main( int argc, char **argv ) {
   oai_exit=1;
   LOG_I(ENB_APP,"oai_exit=%d\n",oai_exit);
   // stop threads
-#ifdef XFORMS
-  printf("waiting for XFORMS thread\n");
 
-  if (get_softmodem_params()->do_forms==1) {
-    pthread_join(forms_thread,&status);
-    fl_hide_form(form_stats->stats_form);
-    fl_free_form(form_stats->stats_form);
-    fl_hide_form(form_stats_l2->stats_form);
-    fl_free_form(form_stats_l2->stats_form);
 
-    for(UE_id=0; UE_id<scope_enb_num_ue; UE_id++) {
-      for(CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
-        fl_hide_form(form_enb[CC_id][UE_id]->lte_phy_scope_enb);
-        fl_free_form(form_enb[CC_id][UE_id]->lte_phy_scope_enb);
+  if (RC.nb_inst == 0 || !NODE_IS_CU(RC.rrc[0]->node_type)) {
+    int UE_id;
+#ifdef XFORMS
+    printf("waiting for XFORMS thread\n");
+
+    if (get_softmodem_params()->do_forms==1) {
+      pthread_join(forms_thread,&status);
+      fl_hide_form(form_stats->stats_form);
+      fl_free_form(form_stats->stats_form);
+      fl_hide_form(form_stats_l2->stats_form);
+      fl_free_form(form_stats_l2->stats_form);
+
+      for(UE_id=0; UE_id<scope_enb_num_ue; UE_id++) {
+        for(CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
+          fl_hide_form(form_enb[CC_id][UE_id]->lte_phy_scope_enb);
+          fl_free_form(form_enb[CC_id][UE_id]->lte_phy_scope_enb);
+        }
       }
     }
-  }
-
 #endif
-  LOG_I(ENB_APP,"stopping MODEM threads\n");
-  stop_eNB(NB_eNB_INST);
-  stop_RU(RC.nb_RU);
-
-  /* release memory used by the RU/eNB threads (incomplete), after all
-   * threads have been stopped (they partially use the same memory) */
-  for (int inst = 0; inst < NB_eNB_INST; inst++) {
-    for (int cc_id = 0; cc_id < RC.nb_CC[inst]; cc_id++) {
-      free_transport(RC.eNB[inst][cc_id]);
-      phy_free_lte_eNB(RC.eNB[inst][cc_id]);
-    }
-  }
-
-  for (int inst = 0; inst < RC.nb_RU; inst++) {
-    phy_free_RU(RC.ru[inst]);
-  }
 
-  free_lte_top();
-  end_configmodule();
-  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);
-
-  for(ru_id=0; ru_id<RC.nb_RU; ru_id++) {
-    if (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;
+    LOG_I(ENB_APP,"stopping MODEM threads\n");
+    stop_eNB(NB_eNB_INST);
+    stop_RU(RC.nb_RU);
+    /* release memory used by the RU/eNB threads (incomplete), after all
+     * threads have been stopped (they partially use the same memory) */
+    for (int inst = 0; inst < NB_eNB_INST; inst++) {
+      for (int cc_id = 0; cc_id < RC.nb_CC[inst]; cc_id++) {
+        free_transport(RC.eNB[inst][cc_id]);
+        phy_free_lte_eNB(RC.eNB[inst][cc_id]);
+      }
     }
-
-    if (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;
+    for (int inst = 0; inst < RC.nb_RU; inst++) {
+      phy_free_RU(RC.ru[inst]);
+    }
+    free_lte_top();
+    end_configmodule();
+    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);
+    
+    for(ru_id=0; ru_id<RC.nb_RU; ru_id++) {
+      if (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]->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;
+      }
     }
   }
 
diff --git a/targets/RT/USER/lte-uesoftmodem.c b/targets/RT/USER/lte-uesoftmodem.c
index f327b83cf9be31c61b32d49c80607cba563fafaf..159cde39ae2b0f9ccb5ecf7ba10a30afa08a82e8 100644
--- a/targets/RT/USER/lte-uesoftmodem.c
+++ b/targets/RT/USER/lte-uesoftmodem.c
@@ -202,7 +202,6 @@ extern void get_uethreads_params(void);
 int transmission_mode=1;
 
 
-
 char *usrp_args=NULL;
 char *usrp_clksrc=NULL;
 
@@ -446,7 +445,7 @@ static void get_options(void) {
   }
 
   UE_scan=0;
-
+   
   if (tddflag > 0) {
     for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
       frame_parms[CC_id]->frame_type = TDD;
@@ -907,14 +906,14 @@ int main( int argc, char **argv ) {
   printf("NFAPI MODE:%s\n", nfapi_mode_str);
 
   if (nfapi_mode==3) { // UE-STUB-PNF
-    config_sync_var=0;
-    wait_nfapi_init("main?");
-    //Panos: Temporarily we will be using single set of threads for multiple UEs.
-    //init_UE_stub(1,eMBMS_active,uecap_xer_in,emul_iface);
-    init_UE_stub_single_thread(NB_UE_INST,eMBMS_active,uecap_xer_in,emul_iface);
+      config_sync_var=0;
+      wait_nfapi_init("main?");
+      //Panos: Temporarily we will be using single set of threads for multiple UEs.
+      //init_UE_stub(1,eMBMS_active,uecap_xer_in,emul_iface);
+      init_UE_stub_single_thread(NB_UE_INST,eMBMS_active,uecap_xer_in,emul_iface);
   } else {
-    init_UE(NB_UE_INST,eMBMS_active,uecap_xer_in,0,get_softmodem_params()->phy_test,UE_scan,UE_scan_carrier,mode,(int)rx_gain[0][0],tx_max_power[0],
-            frame_parms[0]);
+      init_UE(NB_UE_INST,eMBMS_active,uecap_xer_in,0,get_softmodem_params()->phy_test,UE_scan,UE_scan_carrier,mode,(int)rx_gain[0][0],tx_max_power[0],
+              frame_parms[0]);
   }
 
   if (get_softmodem_params()->phy_test==0) {
@@ -924,12 +923,12 @@ int main( int argc, char **argv ) {
   }
 
   if (nfapi_mode!=3) {
-    number_of_cards = 1;
+      number_of_cards = 1;
 
-    for(CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
-      PHY_vars_UE_g[0][CC_id]->rf_map.card=0;
-      PHY_vars_UE_g[0][CC_id]->rf_map.chain=CC_id+(get_softmodem_params()->chain_offset);
-    }
+      for(CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
+              PHY_vars_UE_g[0][CC_id]->rf_map.card=0;
+              PHY_vars_UE_g[0][CC_id]->rf_map.chain=CC_id+(get_softmodem_params()->chain_offset);
+      }
   }
 
   // connect the TX/RX buffers
diff --git a/targets/RT/USER/rfsim.h b/targets/RT/USER/rfsim.h
index c5361724c92b77d37f866973c6d0c7feeeb7ea60..f263b1067c82014b70585843324f8bea1c8a56a7 100644
--- a/targets/RT/USER/rfsim.h
+++ b/targets/RT/USER/rfsim.h
@@ -31,6 +31,10 @@ void init_ocm(double snr_dB,double sinr_dB);
 
 void update_ocm(double snr_dB,double sinr_dB);
 
+//extern pthread_mutex_t async_server_lock;
+//extern pthread_cond_t async_server_notify;
+//extern int async_server_shutdown;
+
 void init_channel_vars(void);
 
 #endif