diff --git a/charts/physims/charts/dlsim/values.yaml b/charts/physims/charts/dlsim/values.yaml
index d78fbb74099a964a7d3ac65c919cdc7a15a6cf07..7f45b42f72bf374d04d81f03c43a4eb5ddcb8654 100644
--- a/charts/physims/charts/dlsim/values.yaml
+++ b/charts/physims/charts/dlsim/values.yaml
@@ -4,11 +4,11 @@
 
 replicaCount: 1
 
-namespace: "oaicicd-ran-tmp"
+namespace: "OAICICD_PROJECT"
 
 image:
   registry: local
-  repository: image-registry.openshift-image-registry.svc:5000/oaicicd-ran-tmp/oai-physim
+  repository: image-registry.openshift-image-registry.svc:5000/OAICICD_PROJECT/oai-physim
   version: temp
   # pullPolicy: IfNotPresent or Never or Always
   pullPolicy: Always
diff --git a/charts/physims/charts/ldpctest/values.yaml b/charts/physims/charts/ldpctest/values.yaml
index e2e6467923809ce3f8e3bd06e85b10c70e33ff1e..b3cc476cf86116a1616856d61d53b3a4307ed96f 100644
--- a/charts/physims/charts/ldpctest/values.yaml
+++ b/charts/physims/charts/ldpctest/values.yaml
@@ -4,11 +4,11 @@
 
 replicaCount: 1
 
-namespace: "oaicicd-ran-tmp"
+namespace: "OAICICD_PROJECT"
 
 image:
   registry: local
-  repository: image-registry.openshift-image-registry.svc:5000/oaicicd-ran-tmp/oai-physim
+  repository: image-registry.openshift-image-registry.svc:5000/OAICICD_PROJECT/oai-physim
   version: temp
   # pullPolicy: IfNotPresent or Never or Always
   pullPolicy: Always
diff --git a/charts/physims/charts/nr-dlschsim/values.yaml b/charts/physims/charts/nr-dlschsim/values.yaml
index 8944e7e7246b284d2d6a32bb74b37b305659bd02..b7ef28f47a7b8e7b969a9886cf28b4b5faf6bf1c 100644
--- a/charts/physims/charts/nr-dlschsim/values.yaml
+++ b/charts/physims/charts/nr-dlschsim/values.yaml
@@ -4,11 +4,11 @@
 
 replicaCount: 1
 
-namespace: "oaicicd-ran-tmp"
+namespace: "OAICICD_PROJECT"
 
 image:
   registry: local
-  repository: image-registry.openshift-image-registry.svc:5000/oaicicd-ran-tmp/oai-physim
+  repository: image-registry.openshift-image-registry.svc:5000/OAICICD_PROJECT/oai-physim
   version: temp
   # pullPolicy: IfNotPresent or Never or Always
   pullPolicy: Always
diff --git a/charts/physims/charts/nr-dlsim/values.yaml b/charts/physims/charts/nr-dlsim/values.yaml
index 573e8630de864cb20ea6e0f658727594668a476a..2a35912fee5ed100b80c4871b799bcc28d48f40d 100644
--- a/charts/physims/charts/nr-dlsim/values.yaml
+++ b/charts/physims/charts/nr-dlsim/values.yaml
@@ -4,11 +4,11 @@
 
 replicaCount: 1
 
-namespace: "oaicicd-ran-tmp"
+namespace: "OAICICD_PROJECT"
 
 image:
   registry: local
-  repository: image-registry.openshift-image-registry.svc:5000/oaicicd-ran-tmp/oai-physim
+  repository: image-registry.openshift-image-registry.svc:5000/OAICICD_PROJECT/oai-physim
   version: temp
   # pullPolicy: IfNotPresent or Never or Always
   pullPolicy: Always
diff --git a/charts/physims/charts/nr-pbchsim/values.yaml b/charts/physims/charts/nr-pbchsim/values.yaml
index 28c4678334ba2587fabc0d6f23eb38b06d705a7b..9a25d2810da87d0fc9f21506db974f72a4230c6c 100644
--- a/charts/physims/charts/nr-pbchsim/values.yaml
+++ b/charts/physims/charts/nr-pbchsim/values.yaml
@@ -4,11 +4,11 @@
 
 replicaCount: 1
 
-namespace: "oaicicd-ran-tmp"
+namespace: "OAICICD_PROJECT"
 
 image:
   registry: local
-  repository: image-registry.openshift-image-registry.svc:5000/oaicicd-ran-tmp/oai-physim
+  repository: image-registry.openshift-image-registry.svc:5000/OAICICD_PROJECT/oai-physim
   version: temp
   # pullPolicy: IfNotPresent or Never or Always
   pullPolicy: Always
diff --git a/charts/physims/charts/nr-prachsim/values.yaml b/charts/physims/charts/nr-prachsim/values.yaml
index 9e3c68b54d306899dbb4ba161a0b37afc3d0157d..dba6cc16c079ce9f65922e11a2082aa8ffec8baa 100644
--- a/charts/physims/charts/nr-prachsim/values.yaml
+++ b/charts/physims/charts/nr-prachsim/values.yaml
@@ -4,11 +4,11 @@
 
 replicaCount: 1
 
-namespace: "oaicicd-ran-tmp"
+namespace: "OAICICD_PROJECT"
 
 image:
   registry: local
-  repository: image-registry.openshift-image-registry.svc:5000/oaicicd-ran-tmp/oai-physim
+  repository: image-registry.openshift-image-registry.svc:5000/OAICICD_PROJECT/oai-physim
   version: temp
   # pullPolicy: IfNotPresent or Never or Always
   pullPolicy: Always
diff --git a/charts/physims/charts/nr-pucchsim/values.yaml b/charts/physims/charts/nr-pucchsim/values.yaml
index 449670f71328bf3d070f62abdabb75043ea2d2ec..77fe0963ac2dc5d939a042aceee96c46703f3232 100644
--- a/charts/physims/charts/nr-pucchsim/values.yaml
+++ b/charts/physims/charts/nr-pucchsim/values.yaml
@@ -4,11 +4,11 @@
 
 replicaCount: 1
 
-namespace: "oaicicd-ran-tmp"
+namespace: "OAICICD_PROJECT"
 
 image:
   registry: local
-  repository: image-registry.openshift-image-registry.svc:5000/oaicicd-ran-tmp/oai-physim
+  repository: image-registry.openshift-image-registry.svc:5000/OAICICD_PROJECT/oai-physim
   version: temp
   # pullPolicy: IfNotPresent or Never or Always
   pullPolicy: Always
diff --git a/charts/physims/charts/nr-ulschsim/values.yaml b/charts/physims/charts/nr-ulschsim/values.yaml
index a3afc090e84527a3471abbe80f231f95452e88db..efb011a7f6530d59c4713c2c51c3a8c776318e98 100644
--- a/charts/physims/charts/nr-ulschsim/values.yaml
+++ b/charts/physims/charts/nr-ulschsim/values.yaml
@@ -4,11 +4,11 @@
 
 replicaCount: 1
 
-namespace: "oaicicd-ran-tmp"
+namespace: "OAICICD_PROJECT"
 
 image:
   registry: local
-  repository: image-registry.openshift-image-registry.svc:5000/oaicicd-ran-tmp/oai-physim
+  repository: image-registry.openshift-image-registry.svc:5000/OAICICD_PROJECT/oai-physim
   version: temp
   # pullPolicy: IfNotPresent or Never or Always
   pullPolicy: Always
diff --git a/charts/physims/charts/nr-ulsim/values.yaml b/charts/physims/charts/nr-ulsim/values.yaml
index 2bf96498e880be7942dfa9e6bfc58e768b203208..71c455b69cc55849105891c6821681b3a72ebef1 100644
--- a/charts/physims/charts/nr-ulsim/values.yaml
+++ b/charts/physims/charts/nr-ulsim/values.yaml
@@ -4,11 +4,11 @@
 
 replicaCount: 1
 
-namespace: "oaicicd-ran-tmp"
+namespace: "OAICICD_PROJECT"
 
 image:
   registry: local
-  repository: image-registry.openshift-image-registry.svc:5000/oaicicd-ran-tmp/oai-physim
+  repository: image-registry.openshift-image-registry.svc:5000/OAICICD_PROJECT/oai-physim
   version: temp
   # pullPolicy: IfNotPresent or Never or Always
   pullPolicy: Always
diff --git a/charts/physims/charts/polartest/values.yaml b/charts/physims/charts/polartest/values.yaml
index e0a532fdd8f419fe0a6f732cd0c8ec000ccf250c..e0751e8ec48cc3798097989abb7abea4cb8f5de8 100644
--- a/charts/physims/charts/polartest/values.yaml
+++ b/charts/physims/charts/polartest/values.yaml
@@ -4,11 +4,11 @@
 
 replicaCount: 1
 
-namespace: "oaicicd-ran-tmp"
+namespace: "OAICICD_PROJECT"
 
 image:
   registry: local
-  repository: image-registry.openshift-image-registry.svc:5000/oaicicd-ran-tmp/oai-physim
+  repository: image-registry.openshift-image-registry.svc:5000/OAICICD_PROJECT/oai-physim
   version: temp
   # pullPolicy: IfNotPresent or Never or Always
   pullPolicy: Always
diff --git a/charts/physims/charts/smallblocktest/values.yaml b/charts/physims/charts/smallblocktest/values.yaml
index f2f113d9b6cc946957c44f9cc34a885992e37a87..f933a978fd20515f5226e4f1232b77cdce3cb7f0 100644
--- a/charts/physims/charts/smallblocktest/values.yaml
+++ b/charts/physims/charts/smallblocktest/values.yaml
@@ -4,11 +4,11 @@
 
 replicaCount: 1
 
-namespace: "oaicicd-ran-tmp"
+namespace: "OAICICD_PROJECT"
 
 image:
   registry: local
-  repository: image-registry.openshift-image-registry.svc:5000/oaicicd-ran-tmp/oai-physim
+  repository: image-registry.openshift-image-registry.svc:5000/OAICICD_PROJECT/oai-physim
   version: temp
   # pullPolicy: IfNotPresent or Never or Always
   pullPolicy: Always
diff --git a/charts/physims/charts/ulsim/values.yaml b/charts/physims/charts/ulsim/values.yaml
index 35dc14d596cf6cbb05b844b84710645e2743479a..d25b6fc2a5351e6208124d06532dd4377d0d913b 100644
--- a/charts/physims/charts/ulsim/values.yaml
+++ b/charts/physims/charts/ulsim/values.yaml
@@ -4,11 +4,11 @@
 
 replicaCount: 1
 
-namespace: "oaicicd-ran-tmp"
+namespace: "OAICICD_PROJECT"
 
 image:
   registry: local
-  repository: image-registry.openshift-image-registry.svc:5000/oaicicd-ran-tmp/oai-physim
+  repository: image-registry.openshift-image-registry.svc:5000/OAICICD_PROJECT/oai-physim
   version: temp
   # pullPolicy: IfNotPresent or Never or Always
   pullPolicy: Always
diff --git a/charts/physims/templates/rbac.yaml b/charts/physims/templates/rbac.yaml
index 35f956a203beaf004b75369e524147dc0afabf1b..b341744796100cc2d95fb580eac9ec60db1726df 100644
--- a/charts/physims/templates/rbac.yaml
+++ b/charts/physims/templates/rbac.yaml
@@ -1,12 +1,26 @@
-apiVersion: rbac.authorization.k8s.io/v1beta1
-kind: ClusterRoleBinding
+apiVersion: rbac.authorization.k8s.io/v1
+kind: Role
 metadata:
-  name: {{ .Chart.Name }}-{{ .Values.global.namespace }}-rbac
-roleRef:
-  apiGroup: rbac.authorization.k8s.io
-  kind: ClusterRole
-  name: cluster-admin
+  name: {{ .Chart.Name }}-{{ .Release.Namespace }}-role
+rules:
+- apiGroups:
+  - security.openshift.io
+  resourceNames:
+  - privileged
+  resources:
+  - securitycontextconstraints
+  verbs:
+  - use
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: RoleBinding
+metadata:
+  name: {{ .Chart.Name }}-{{ .Release.Namespace }}-binding
 subjects:
 - kind: ServiceAccount
   name: {{ .Values.global.serviceAccountName }}
-  namespace: {{ .Values.global.namespace }}
+  namespace: {{ .Release.Namespace }}
+roleRef:
+  kind: Role
+  name: {{ .Chart.Name }}-{{ .Release.Namespace }}-role
+  apiGroup: rbac.authorization.k8s.io
diff --git a/charts/physims/values.yaml b/charts/physims/values.yaml
index b348e822bb0e2e64ed7ae2f2c1c6e737f0afd5ec..d5253c781226742bf7dc65bfa6e8b4f82cf5aa1f 100644
--- a/charts/physims/values.yaml
+++ b/charts/physims/values.yaml
@@ -4,9 +4,9 @@
 
 global:
   serviceAccountName: oai-physim-sa
-  namespace: "oaicicd-ran-tmp"
+  namespace: "OAICICD_PROJECT"
   image:
-    repository: image-registry.openshift-image-registry.svc:5000/oaicicd-ran-tmp/oai-physim
+    repository: image-registry.openshift-image-registry.svc:5000/OAICICD_PROJECT/oai-physim
     version: TAG
 
 ## Declaring values specific to coressponding physim to overwrite
diff --git a/ci-scripts/Jenkinsfile-GitLab-Container b/ci-scripts/Jenkinsfile-GitLab-Container
index 57738a318334aad50a3d5f8a6fdee7f4a2664b96..c22e6fabec717bc8f889846ee04c4cc3bcee9916 100644
--- a/ci-scripts/Jenkinsfile-GitLab-Container
+++ b/ci-scripts/Jenkinsfile-GitLab-Container
@@ -238,6 +238,26 @@ pipeline {
             }
           }
         }
+        stage ("5G L2 Simulators") {
+          when { expression {doMandatoryTests} }
+          steps {
+            script {
+              triggerSlaveJob ('RAN-L2-Sim-Test-5G', 'Test-L2-Sim-Container-5G')
+            }
+          }
+          post {
+            always {
+              script {
+                finalizeSlaveJob('RAN-L2-Sim-Test-5G')
+              }
+            }
+            failure {
+              script {
+                currentBuild.result = 'FAILURE'
+              }
+            }
+          }
+        }
         stage ("NSA B200 Sanity Check") {
           when { expression {doMandatoryTests} }
           steps {
diff --git a/ci-scripts/Jenkinsfile-push-registry b/ci-scripts/Jenkinsfile-push-registry
index f5847ff0aab2e45adee158f8f5d8fceda735f209..bc1a80ba614fc3554e4c9c1d00bd508acd06d551 100644
--- a/ci-scripts/Jenkinsfile-push-registry
+++ b/ci-scripts/Jenkinsfile-push-registry
@@ -26,6 +26,9 @@ def nodeExecutor = params.nodeExecutor
 // Name of the phone resource
 def ciServerResource = params.serverResource
 
+// Docker Hub account to push to
+def DH_Account = "oaisoftwarealliance"
+
 pipeline {
   agent {
     label nodeExecutor
@@ -66,11 +69,11 @@ pipeline {
             def listOfImages = ["oai-enb", "oai-gnb", "oai-lte-ue", "oai-nr-ue"]
             sh "docker login -u ${DH_Username} -p ${DH_Password} > /dev/null 2>&1"
             listOfImages.eachWithIndex { item, iindex ->
-              sh "docker image tag ${item}:develop ${DH_Username}/${item}:develop"
-              sh "docker image tag ${item}:develop ${DH_Username}/${item}:${WEEK_TAG}"
-              sh "docker push --quiet ${DH_Username}/${item}:${WEEK_TAG}"
-              sh "docker push --quiet ${DH_Username}/${item}:develop"
-              sh "docker rmi ${DH_Username}/${item}:${WEEK_TAG} ${DH_Username}/${item}:develop"
+              sh "docker image tag ${item}:develop ${DH_Account}/${item}:develop"
+              sh "docker image tag ${item}:develop ${DH_Account}/${item}:${WEEK_TAG}"
+              sh "docker push --quiet ${DH_Account}/${item}:${WEEK_TAG}"
+              sh "docker push --quiet ${DH_Account}/${item}:develop"
+              sh "docker rmi ${DH_Account}/${item}:${WEEK_TAG} ${DH_Account}/${item}:develop"
             }
             sh "docker logout > /dev/null 2>&1"
           }
diff --git a/ci-scripts/as_ue/oai_ext_app.sh b/ci-scripts/as_ue/oai_ext_app.sh
new file mode 100755
index 0000000000000000000000000000000000000000..727e2b5db2d1300ad5eea99de80d01b570773735
--- /dev/null
+++ b/ci-scripts/as_ue/oai_ext_app.sh
@@ -0,0 +1,18 @@
+#!/bin/bash
+
+ue_id="$1"      # UE id
+duration="$2"   # Sim duration
+
+shift
+shift
+
+function end
+{
+    exit 0
+}
+trap end INT TERM
+
+echo "ip netns exec $ue_id $@ > /tmp/test_${ue_id}.log"
+ip netns exec $ue_id $@ > /tmp/test_$ue_id.log
+
+
diff --git a/ci-scripts/as_ue/oaicicd-3xue-noPing-SATest.cfg b/ci-scripts/as_ue/oaicicd-3xue-noPing-SATest.cfg
new file mode 100644
index 0000000000000000000000000000000000000000..a9299b67e319753e6ccd85813d8bb0305e72aa50
--- /dev/null
+++ b/ci-scripts/as_ue/oaicicd-3xue-noPing-SATest.cfg
@@ -0,0 +1,172 @@
+/* UE simulator configuration */
+
+
+/* UE simulator configuration file version 2021-06-17
+ * LTE / 5G Non StandAlone
+ * Copyright (C) 2019-2021 Amarisoft
+ */
+{
+#define N_ANTENNA_DL 1
+#define TDD 1
+#define CELL_BANDWIDTH 40
+#define UE_COUNT 3 // number of simulated UEs 208970100001127, 208970100001128, 208970100001129
+
+
+log_options: "all.level=error,all.max_size=0,nas.level=debug,nas.max_size=1,rrc.level=debug,rrc.max_size=1",
+log_filename: "/tmp/ue0.log",
+
+/* Enable remote API and Web interface */
+com_addr: "0.0.0.0:9002",
+
+include "rf_driver/1chan.cfg",
+
+/* If true, allow the simulation of several UEs at the same time and allow dynamic UE creation from remote API */
+                    
+cell_groups: [{
+    group_type: "nr",
+    multi_ue: true,
+    cells: [{
+      rf_port: 0,
+      bandwidth: CELL_BANDWIDTH,
+#if TDD == 1
+      band: 78,
+      dl_nr_arfcn:621312,
+      ssb_nr_arfcn:621312,
+
+      //band: 41,
+      //dl_nr_arfcn:517020,
+      //ssb_nr_arfcn:516990,
+#else
+      band: 7,
+      dl_nr_arfcn: 536020,
+      ssb_nr_arfcn: 535930,
+      ssb_subcarrier_spacing: 15,
+#endif
+      subcarrier_spacing: 30,
+      n_antenna_dl: N_ANTENNA_DL,
+      n_antenna_ul: 1,
+      rx_to_tx_latency:2,
+    }],
+}],
+
+    
+/* Enable it to allow sim_events to be handled remotely */
+//rue_bind_addr: "127.0.10.11",
+
+
+
+ue_list: [
+  {
+    /* UE capabilities */ 
+    /* USIM data */    
+    "ue_id" : 0,
+    "imsi": "208970100001127",
+    "K": "fec86ba6eb707ed08905757b1bb44b8f",
+    "sim_algo":"milenage",
+    "op": "1006020f0a478bf6b699f15c062e42b3",
+    as_release: 15,
+    ue_category: "nr",
+    apn:"oai",
+    attach_pdn_type:"ipv4",
+    default_nssai: [
+      {
+      sst: 1,
+      sd: 66051,
+      },
+    ],
+    default_pdu_session_snssai: {
+      sst: 1,
+      sd: 66051,
+    },
+    /* Enable it to allow sim_events to be handled remotely */
+    //rue_addr: "127.1.0.0",
+    /* Enable it to create a TUN interface for each UE PDN */
+    tun_setup_script: "ue-ifup",
+    sim_events: [
+      {
+        event: "power_on",
+        start_time: 5,
+      }, 
+      {
+        event: "power_off",
+        start_time: 30,
+      }
+    ] /*end sim events */
+  }, /*end UE object 0*/
+  {
+    /* UE capabilities */ 
+    /* USIM data */  
+    "ue_id" : 1, 
+    "imsi": "208970100001128",
+    "K": "fec86ba6eb707ed08905757b1bb44b8f",
+    "sim_algo":"milenage",
+    "op": "1006020f0a478bf6b699f15c062e42b3",
+    as_release: 15,
+    ue_category: "nr",
+    apn:"oai",
+    attach_pdn_type:"ipv4",
+    default_nssai: [
+      {
+      sst: 1,
+      sd: 66051,
+      },
+    ],
+    default_pdu_session_snssai: {
+      sst: 1,
+      sd: 66051,
+    },
+    /* Enable it to allow sim_events to be handled remotely */
+    //rue_addr: "127.1.0.0",
+    /* Enable it to create a TUN interface for each UE PDN */
+    tun_setup_script: "ue-ifup",
+    sim_events: [
+      {
+        event: "power_on",
+        start_time: 5,
+      }, 
+      {
+        event: "power_off",
+        start_time: 30,
+      }
+    ] /*end sim events */
+  }, /*end UE object 1*/
+  {
+    /* UE capabilities */
+    /* USIM data */
+    "ue_id" : 2,
+    "imsi": "208970100001129",
+    "K": "fec86ba6eb707ed08905757b1bb44b8f",
+    "sim_algo":"milenage",
+    "op": "1006020f0a478bf6b699f15c062e42b3",
+    as_release: 15,
+    ue_category: "nr",
+    apn:"oai",
+    attach_pdn_type:"ipv4",
+    default_nssai: [
+      {
+      sst: 1,
+      sd: 66051,
+      },
+    ],
+    default_pdu_session_snssai: {
+      sst: 1,
+      sd: 66051,
+    },
+    /* Enable it to allow sim_events to be handled remotely */
+    //rue_addr: "127.1.0.0",
+    /* Enable it to create a TUN interface for each UE PDN */
+    tun_setup_script: "ue-ifup",
+    sim_events: [
+      {
+        event: "power_on",
+        start_time: 5,
+      },
+      {
+        event: "power_off",
+        start_time: 30,
+      }
+    ] /*end sim events */
+  } /*end UE object 2*/
+  ],/*end UE list*/
+}/*end json*/
+
diff --git a/ci-scripts/as_ue/oaicicd-multi-ue-1xPing-SATest.cfg b/ci-scripts/as_ue/oaicicd-multi-ue-1xPing-SATest.cfg
new file mode 100644
index 0000000000000000000000000000000000000000..3405f99a59ddee7f7294b2fa838dea6798ec5ef3
--- /dev/null
+++ b/ci-scripts/as_ue/oaicicd-multi-ue-1xPing-SATest.cfg
@@ -0,0 +1,142 @@
+/* UE simulator configuration */
+
+
+/* UE simulator configuration file version 2021-06-17
+ * LTE / 5G Non StandAlone
+ * Copyright (C) 2019-2021 Amarisoft
+ */
+{
+#define N_ANTENNA_DL 1
+#define TDD 1
+#define CELL_BANDWIDTH 40
+#define UE_COUNT 2 // number of simulated UEs 208970100001127, 208970100001128, 208970100001129
+
+
+log_options: "all.level=error,all.max_size=0,nas.level=debug,nas.max_size=1,rrc.level=debug,rrc.max_size=1",
+log_filename: "/tmp/ue0.log",
+
+/* Enable remote API and Web interface */
+com_addr: "0.0.0.0:9002",
+
+include "rf_driver/1chan.cfg",
+
+/* If true, allow the simulation of several UEs at the same time and allow dynamic UE creation from remote API */
+                    
+cell_groups: [{
+    group_type: "nr",
+    multi_ue: true,
+    cells: [{
+      rf_port: 0,
+      bandwidth: CELL_BANDWIDTH,
+#if TDD == 1
+      band: 78,
+      dl_nr_arfcn:621312,
+      ssb_nr_arfcn:621312,
+
+      //band: 41,
+      //dl_nr_arfcn:517020,
+      //ssb_nr_arfcn:516990,
+#else
+      band: 7,
+      dl_nr_arfcn: 536020,
+      ssb_nr_arfcn: 535930,
+      ssb_subcarrier_spacing: 15,
+#endif
+      subcarrier_spacing: 30,
+      n_antenna_dl: N_ANTENNA_DL,
+      n_antenna_ul: 1,
+      rx_to_tx_latency:2,
+    }],
+}],
+
+    
+/* Enable it to allow sim_events to be handled remotely */
+//rue_bind_addr: "127.0.10.11",
+
+
+
+ue_list: [
+  {
+    /* UE capabilities */ 
+    /* USIM data */    
+    "ue_id" : 1,
+    "imsi": "208970100001127",
+    "K": "fec86ba6eb707ed08905757b1bb44b8f",
+    "sim_algo":"milenage",
+    "op": "1006020f0a478bf6b699f15c062e42b3",
+    as_release: 15,
+    ue_category: "nr",
+    apn:"oai",
+    attach_pdn_type:"ipv4",
+    default_nssai: [
+      {
+      sst: 1,
+      sd: 66051,
+      },
+    ],
+    default_pdu_session_snssai: {
+      sst: 1,
+      sd: 66051,
+    },
+    /* Enable it to allow sim_events to be handled remotely */
+    //rue_addr: "127.1.0.0",
+    /* Enable it to create a TUN interface for each UE PDN */
+    tun_setup_script: "ue-ifup",
+    sim_events: [
+      {
+        event: "power_on",
+        start_time: 5,
+      }, 
+      {
+        event: "power_off",
+        start_time: 30,
+      }
+    ] /*end sim events */
+  }, /*end UE object 0*/
+  {
+    /* UE capabilities */ 
+    /* USIM data */  
+    "ue_id" : 2, 
+    "imsi": "208970100001128",
+    "K": "fec86ba6eb707ed08905757b1bb44b8f",
+    "sim_algo":"milenage",
+    "op": "1006020f0a478bf6b699f15c062e42b3",
+    as_release: 15,
+    ue_category: "nr",
+    apn:"oai",
+    attach_pdn_type:"ipv4",
+    default_nssai: [
+      {
+      sst: 1,
+      sd: 66051,
+      },
+    ],
+    default_pdu_session_snssai: {
+      sst: 1,
+      sd: 66051,
+    },
+    /* Enable it to allow sim_events to be handled remotely */
+    //rue_addr: "127.1.0.0",
+    /* Enable it to create a TUN interface for each UE PDN */
+    tun_setup_script: "ue-ifup",
+    sim_events: [
+      {
+        event: "power_on",
+        start_time: 5,
+      }, 
+      {
+       "tag": "ping",
+       "prog":"oai_ext_app.sh",
+        start_time: 15,
+        end_time: 25,
+        "args":["ping 192.168.70.136"],
+        "event":"ext_app"              
+      },
+      {
+        event: "power_off",
+        start_time: 30,
+      }
+    ] /*end sim events */
+  } /*end UE object 1*/
+  ],/*end UE list*/
+}/*end json*/
diff --git a/ci-scripts/as_ue/oaicicd-multi-ue-2xPing-SATest.cfg b/ci-scripts/as_ue/oaicicd-multi-ue-2xPing-SATest.cfg
new file mode 100644
index 0000000000000000000000000000000000000000..eaa9b894fca3fe740c5af0fe870c42ba7c00fbc0
--- /dev/null
+++ b/ci-scripts/as_ue/oaicicd-multi-ue-2xPing-SATest.cfg
@@ -0,0 +1,150 @@
+/* UE simulator configuration */
+
+
+/* UE simulator configuration file version 2021-06-17
+ * LTE / 5G Non StandAlone
+ * Copyright (C) 2019-2021 Amarisoft
+ */
+{
+#define N_ANTENNA_DL 1
+#define TDD 1
+#define CELL_BANDWIDTH 40
+#define UE_COUNT 2 // number of simulated UEs 208970100001127, 208970100001128, 208970100001129
+
+
+log_options: "all.level=error,all.max_size=0,nas.level=debug,nas.max_size=1,rrc.level=debug,rrc.max_size=1",
+log_filename: "/tmp/ue0.log",
+
+/* Enable remote API and Web interface */
+com_addr: "0.0.0.0:9002",
+
+include "rf_driver/1chan.cfg",
+
+/* If true, allow the simulation of several UEs at the same time and allow dynamic UE creation from remote API */
+                    
+cell_groups: [{
+    group_type: "nr",
+    multi_ue: true,
+    cells: [{
+      rf_port: 0,
+      bandwidth: CELL_BANDWIDTH,
+#if TDD == 1
+      band: 78,
+      dl_nr_arfcn:621312,
+      ssb_nr_arfcn:621312,
+
+      //band: 41,
+      //dl_nr_arfcn:517020,
+      //ssb_nr_arfcn:516990,
+#else
+      band: 7,
+      dl_nr_arfcn: 536020,
+      ssb_nr_arfcn: 535930,
+      ssb_subcarrier_spacing: 15,
+#endif
+      subcarrier_spacing: 30,
+      n_antenna_dl: N_ANTENNA_DL,
+      n_antenna_ul: 1,
+      rx_to_tx_latency:2,
+    }],
+}],
+
+    
+/* Enable it to allow sim_events to be handled remotely */
+//rue_bind_addr: "127.0.10.11",
+
+
+
+ue_list: [
+  {
+    /* UE capabilities */ 
+    /* USIM data */    
+    "ue_id" : 1,
+    "imsi": "208970100001127",
+    "K": "fec86ba6eb707ed08905757b1bb44b8f",
+    "sim_algo":"milenage",
+    "op": "1006020f0a478bf6b699f15c062e42b3",
+    as_release: 15,
+    ue_category: "nr",
+    apn:"oai",
+    attach_pdn_type:"ipv4",
+    default_nssai: [
+      {
+      sst: 1,
+      sd: 66051,
+      },
+    ],
+    default_pdu_session_snssai: {
+      sst: 1,
+      sd: 66051,
+    },
+    /* Enable it to allow sim_events to be handled remotely */
+    //rue_addr: "127.1.0.0",
+    /* Enable it to create a TUN interface for each UE PDN */
+    tun_setup_script: "ue-ifup",
+    sim_events: [
+      {
+        event: "power_on",
+        start_time: 5,
+      }, 
+      {
+       "tag": "ping",
+       "prog":"oai_ext_app.sh",
+        start_time: 15,
+        end_time: 25,
+        "args":["ping 192.168.70.136"],
+        "event":"ext_app"              
+      },
+      {
+        event: "power_off",
+        start_time: 30,
+      }
+    ] /*end sim events */
+  }, /*end UE object 0*/
+  {
+    /* UE capabilities */ 
+    /* USIM data */  
+    "ue_id" : 2, 
+    "imsi": "208970100001128",
+    "K": "fec86ba6eb707ed08905757b1bb44b8f",
+    "sim_algo":"milenage",
+    "op": "1006020f0a478bf6b699f15c062e42b3",
+    as_release: 15,
+    ue_category: "nr",
+    apn:"oai",
+    attach_pdn_type:"ipv4",
+    default_nssai: [
+      {
+      sst: 1,
+      sd: 66051,
+      },
+    ],
+    default_pdu_session_snssai: {
+      sst: 1,
+      sd: 66051,
+    },
+    /* Enable it to allow sim_events to be handled remotely */
+    //rue_addr: "127.1.0.0",
+    /* Enable it to create a TUN interface for each UE PDN */
+    tun_setup_script: "ue-ifup",
+    sim_events: [
+      {
+        event: "power_on",
+        start_time: 5,
+      }, 
+      {
+       "tag": "ping",
+       "prog":"oai_ext_app.sh",
+        start_time: 15,
+        end_time: 25,
+        "args":["ping 192.168.70.136"],
+        "event":"ext_app"              
+      },
+      {
+        event: "power_off",
+        start_time: 30,
+      }
+    ] /*end sim events */
+  } /*end UE object 1*/
+  ],/*end UE list*/
+}/*end json*/
diff --git a/ci-scripts/as_ue/oaicicd-multi-ue-2xPingSeq-SATest.cfg b/ci-scripts/as_ue/oaicicd-multi-ue-2xPingSeq-SATest.cfg
new file mode 100644
index 0000000000000000000000000000000000000000..9ebb3e01c5769d570a0148cce2ebf2fa8f2306e6
--- /dev/null
+++ b/ci-scripts/as_ue/oaicicd-multi-ue-2xPingSeq-SATest.cfg
@@ -0,0 +1,150 @@
+/* UE simulator configuration */
+
+
+/* UE simulator configuration file version 2021-06-17
+ * LTE / 5G Non StandAlone
+ * Copyright (C) 2019-2021 Amarisoft
+ */
+{
+#define N_ANTENNA_DL 1
+#define TDD 1
+#define CELL_BANDWIDTH 40
+#define UE_COUNT 2 // number of simulated UEs 208970100001127, 208970100001128, 208970100001129
+
+
+log_options: "all.level=error,all.max_size=0,nas.level=debug,nas.max_size=1,rrc.level=debug,rrc.max_size=1",
+log_filename: "/tmp/ue0.log",
+
+/* Enable remote API and Web interface */
+com_addr: "0.0.0.0:9002",
+
+include "rf_driver/1chan.cfg",
+
+/* If true, allow the simulation of several UEs at the same time and allow dynamic UE creation from remote API */
+                    
+cell_groups: [{
+    group_type: "nr",
+    multi_ue: true,
+    cells: [{
+      rf_port: 0,
+      bandwidth: CELL_BANDWIDTH,
+#if TDD == 1
+      band: 78,
+      dl_nr_arfcn:621312,
+      ssb_nr_arfcn:621312,
+
+      //band: 41,
+      //dl_nr_arfcn:517020,
+      //ssb_nr_arfcn:516990,
+#else
+      band: 7,
+      dl_nr_arfcn: 536020,
+      ssb_nr_arfcn: 535930,
+      ssb_subcarrier_spacing: 15,
+#endif
+      subcarrier_spacing: 30,
+      n_antenna_dl: N_ANTENNA_DL,
+      n_antenna_ul: 1,
+      rx_to_tx_latency:2,
+    }],
+}],
+
+    
+/* Enable it to allow sim_events to be handled remotely */
+//rue_bind_addr: "127.0.10.11",
+
+
+
+ue_list: [
+  {
+    /* UE capabilities */ 
+    /* USIM data */    
+    "ue_id" : 1,
+    "imsi": "208970100001127",
+    "K": "fec86ba6eb707ed08905757b1bb44b8f",
+    "sim_algo":"milenage",
+    "op": "1006020f0a478bf6b699f15c062e42b3",
+    as_release: 15,
+    ue_category: "nr",
+    apn:"oai",
+    attach_pdn_type:"ipv4",
+    default_nssai: [
+      {
+      sst: 1,
+      sd: 66051,
+      },
+    ],
+    default_pdu_session_snssai: {
+      sst: 1,
+      sd: 66051,
+    },
+    /* Enable it to allow sim_events to be handled remotely */
+    //rue_addr: "127.1.0.0",
+    /* Enable it to create a TUN interface for each UE PDN */
+    tun_setup_script: "ue-ifup",
+    sim_events: [
+      {
+        event: "power_on",
+        start_time: 5,
+      },
+      {
+       "tag": "ping",
+       "prog":"oai_ext_app.sh",
+        start_time: 20,
+        end_time: 30,
+        "args":["ping 192.168.70.136"],
+        "event":"ext_app"
+      },
+      {
+        event: "power_off",
+        start_time: 60,
+      }
+    ] /*end sim events */
+  }, /*end UE object 0*/
+  {
+    /* UE capabilities */ 
+    /* USIM data */  
+    "ue_id" : 2, 
+    "imsi": "208970100001128",
+    "K": "fec86ba6eb707ed08905757b1bb44b8f",
+    "sim_algo":"milenage",
+    "op": "1006020f0a478bf6b699f15c062e42b3",
+    as_release: 15,
+    ue_category: "nr",
+    apn:"oai",
+    attach_pdn_type:"ipv4",
+    default_nssai: [
+      {
+      sst: 1,
+      sd: 66051,
+      },
+    ],
+    default_pdu_session_snssai: {
+      sst: 1,
+      sd: 66051,
+    },
+    /* Enable it to allow sim_events to be handled remotely */
+    //rue_addr: "127.1.0.0",
+    /* Enable it to create a TUN interface for each UE PDN */
+    tun_setup_script: "ue-ifup",
+    sim_events: [
+      {
+        event: "power_on",
+        start_time: 5,
+      }, 
+      {
+       "tag": "ping",
+       "prog":"oai_ext_app.sh",
+        start_time: 40,
+        end_time: 50,
+        "args":["ping 192.168.70.136"],
+        "event":"ext_app"              
+      },
+      {
+        event: "power_off",
+        start_time: 60,
+      }
+    ] /*end sim events */
+  } /*end UE object 1*/
+  ],/*end UE list*/
+}/*end json*/
diff --git a/ci-scripts/as_ue/oaicicd-ue-Ping-SATest.cfg b/ci-scripts/as_ue/oaicicd-ue-Ping-SATest.cfg
new file mode 100644
index 0000000000000000000000000000000000000000..ba22cbb233bb9e11a385005f822bb410597a6af1
--- /dev/null
+++ b/ci-scripts/as_ue/oaicicd-ue-Ping-SATest.cfg
@@ -0,0 +1,113 @@
+/* UE simulator configuration */
+
+
+
+/* UE simulator configuration file version 2021-06-17
+ * LTE / 5G Non StandAlone
+ * Copyright (C) 2019-2021 Amarisoft
+ */
+{
+#define N_ANTENNA_DL 1
+#define TDD 1
+#define CELL_BANDWIDTH 40
+
+
+  log_options: "all.level=error,all.max_size=0,nas.level=debug,nas.max_size=1,rrc.level=debug,rrc.max_size=1",
+  log_filename: "/tmp/ue1.log",
+
+  /* Enable remote API and Web interface */
+  com_addr: "0.0.0.0:9002",
+
+  include "rf_driver/1chan.cfg",
+
+      /* If true, allow the simulation of several UEs at the same time and
+         allow dynamic UE creation from remote API */
+                    
+cell_groups: [{
+    group_type: "nr",
+    multi_ue: false,
+    cells: [{
+      rf_port: 0,
+      bandwidth: CELL_BANDWIDTH,
+#if TDD == 1
+      band: 78,
+      dl_nr_arfcn:621312,
+      ssb_nr_arfcn:621312,
+
+      //band: 41,
+      //dl_nr_arfcn:517020,
+      //ssb_nr_arfcn:516990,
+#else
+      band: 7,
+      dl_nr_arfcn: 536020,
+      ssb_nr_arfcn: 535930,
+      ssb_subcarrier_spacing: 15,
+#endif
+      subcarrier_spacing: 30,
+      n_antenna_dl: N_ANTENNA_DL,
+      n_antenna_ul: 1,
+      rx_to_tx_latency:2,
+    }],
+  }],
+
+
+
+       
+  /* Enable it to allow sim_events to be handled remotely */
+  //rue_bind_addr: "127.0.10.11",
+
+  ue_list: [
+    {
+      /* UE capabilities */
+   
+    /* USIM data */
+
+
+    "imsi": "208970100001127",
+    "K": "fec86ba6eb707ed08905757b1bb44b8f",
+    "sim_algo":"milenage",
+    "op": "1006020f0a478bf6b699f15c062e42b3",
+
+
+    as_release: 15,
+    ue_category: "nr",
+    apn:"oai",
+    attach_pdn_type:"ipv4",
+    default_nssai: [
+    {
+    sst: 1,
+    sd: 66051,
+    },
+    ],
+
+    default_pdu_session_snssai: {
+    sst: 1,
+    sd: 66051,
+    },
+
+
+      /* Enable it to allow sim_events to be handled remotely */
+      //rue_addr: "127.1.0.0",
+
+      /* Enable it to create a TUN interface for each UE PDN */
+      tun_setup_script: "ue-ifup",
+
+      sim_events: [{
+        event: "power_on",
+        start_time: 5,
+      }, {
+       "tag": "ping",
+       "prog":"oai_ext_app.sh",
+        start_time: 15,
+        end_time: 25,
+        "args":["ping 192.168.70.136"],
+        "event":"ext_app"
+              
+      },
+      {
+        event: "power_off",
+        start_time: 30,
+      }]
+    }
+  ],
+}
diff --git a/ci-scripts/as_ue/oaicicd-ue-iperf-SATest.cfg b/ci-scripts/as_ue/oaicicd-ue-iperf-SATest.cfg
new file mode 100644
index 0000000000000000000000000000000000000000..841dafb74605d5ab006362d845fc8541a744eeae
--- /dev/null
+++ b/ci-scripts/as_ue/oaicicd-ue-iperf-SATest.cfg
@@ -0,0 +1,109 @@
+/* UE simulator configuration */
+
+
+
+/* UE simulator configuration file version 2021-06-17
+ * LTE / 5G Non StandAlone
+ * Copyright (C) 2019-2021 Amarisoft
+ */
+{
+#define N_ANTENNA_DL 1
+#define TDD 1
+#define CELL_BANDWIDTH 20
+
+
+  log_options: "all.level=error,all.max_size=0,nas.level=debug,nas.max_size=1,rrc.level=debug,rrc.max_size=1",
+  log_filename: "/tmp/ue0.log",
+
+  /* Enable remote API and Web interface */
+  com_addr: "0.0.0.0:9002",
+
+  include "rf_driver/1chan.cfg",
+
+      /* If true, allow the simulation of several UEs at the same time and
+         allow dynamic UE creation from remote API */
+                    
+cell_groups: [{
+    group_type: "nr",
+    multi_ue: false,
+    cells: [{
+      rf_port: 0,
+      bandwidth: CELL_BANDWIDTH,
+#if TDD == 1
+     // band: 78,
+     // dl_nr_arfcn:621312,
+     // ssb_nr_arfcn:621312,*/
+
+      band: 41,
+      dl_nr_arfcn:517020,
+      ssb_nr_arfcn:516990,
+#else
+      band: 7,
+      dl_nr_arfcn: 536020,
+      ssb_nr_arfcn: 535930,
+      ssb_subcarrier_spacing: 15,
+#endif
+      subcarrier_spacing: 30,
+      n_antenna_dl: N_ANTENNA_DL,
+      n_antenna_ul: 1,
+      rx_to_tx_latency:2,
+    }],
+  }],
+
+
+
+       
+  /* Enable it to allow sim_events to be handled remotely */
+  //rue_bind_addr: "127.0.10.11",
+
+  ue_list: [
+    {
+      /* UE capabilities */
+   
+    /* USIM data */
+     
+    "imsi": "208970100001127",
+    "K": "fec86ba6eb707ed08905757b1bb44b8f",
+    "sim_algo":"milenage",
+    "op": "1006020f0a478bf6b699f15c062e42b3",
+
+
+    as_release: 15,
+    ue_category: "nr",
+    apn:"oai",
+    attach_pdn_type:"ipv4",
+    default_nssai: [
+    {
+    sst: 1,
+    sd: 1,
+    },
+    ],
+
+    default_pdu_session_snssai: {
+    sst: 1,
+    sd: 1,
+    },
+
+
+      /* Enable it to allow sim_events to be handled remotely */
+      //rue_addr: "127.1.0.0",
+
+      /* Enable it to create a TUN interface for each UE PDN */
+      tun_setup_script: "ue-ifup",
+
+      sim_events: [{
+        event: "power_on",
+        start_time: 5,
+      }, {
+        event: "ext_app",
+        start_time: 15,
+        end_time: 25,
+        prog: "ext_app.sh",
+        args: ["iperf", " -c  172.21.10.5", " -u"," -b 1M"," -i 1"," -t 10"]
+      }, {
+        event: "power_off",
+        start_time: 30,
+      }]
+    }
+  ],
+}
diff --git a/ci-scripts/build_fr1_template.yaml b/ci-scripts/build_fr1_template.yaml
index 02e49bc4b59b303ee3a1cd36136a34d3796ce0ad..5c7b2fc6f4cf316e22515494c5532cc030853992 100755
--- a/ci-scripts/build_fr1_template.yaml
+++ b/ci-scripts/build_fr1_template.yaml
@@ -14,7 +14,7 @@ steps:
 
 
 ADB: #on Caracal
-  ADBIPAddress : 192.168.18.196
+  ADBIPAddress : 172.21.16.132
   ADBUserName : oaici
   ADBPassword : KkexF6CErOi1fNuebCPsuIVK
 
diff --git a/ci-scripts/ci_ueinfra.yaml b/ci-scripts/ci_ueinfra.yaml
index 0a915740f243cbb114120ed6971140ee7c3e5ee6..b888f6bb59fc0257c9d402e18a0e86178d4d2537 100644
--- a/ci-scripts/ci_ueinfra.yaml
+++ b/ci-scripts/ci_ueinfra.yaml
@@ -12,7 +12,7 @@ idefix:
   LogStore : /media/usb-drive/ci_qlogs
   PLMN : 22201
   UENetwork : wwan0 
-  HostIPAddress : 192.168.18.188
+  HostIPAddress : 172.21.16.135
   HostUsername : oaicicd
   HostPassword : oaicicd
   HostSourceCodePath : none
@@ -32,13 +32,61 @@ nrmodule2_quectel:
   LogStore : /media/ci_qlogs  
   PLMN : 20897
   UENetwork : wwan0
-  HostIPAddress : 192.168.18.189
+  HostIPAddress : 172.21.16.139
   HostUsername : nrmodule2 
   HostPassword : linux 
   HostSourceCodePath : none
   StartCommands :
     - sudo -S ip link set dev wwan1 mtu 1500
   MTU : 1500
+
+# CAUTION: 192.168.18.89 address has to be changed when the server is moved
+#single UE single ping
+amarisoft_ue_1:
+  ID: amarisoft_ue_1
+  State : enabled
+  Kind : amarisoft
+  #not required for AS config but needed for py script
+  WakeupScript : none
+  DetachScript : none
+  #end 
+  Cmd : /root/NV17-12-21/ue/lteue 
+  Config : /root/NV17-12-21/ue/config/oaicicd-ue-Ping-SATest.cfg 
+  Duration : 60
+  Ping : /tmp/test_ue1.log
+  UELog : /tmp/ue1.log
+  HostIPAddress : 192.168.18.89
+  HostUsername : root
+  HostPassword : toor 
+  HostSourceCodePath : /tmp
+
+
+#an other scenario example
+#notice : this will not work as such, only suggestion for multi ue scenario
+amarisoft_ue_2:
+  ID: amarisoft_ue_2
+  State : enabled
+  Kind : amarisoft
+  #not required for AS config but needed for py script
+  WakeupScript : none
+  DetachScript : none
+  #end 
+  Cmd : /root/NV17-12-21/ue/lteue 
+  Config : /root/NV17-12-21/ue/config/xxxxxxx.cfg #to be updated for an other scenario 
+  Duration : 60
+  Ping :
+    - /tmp/test_ue1.log #to be updated fo an other scenario
+    - /tmp/test_ue2.log #could be a list for a multi ue scenario
+  UELog :
+    - /tmp/ue1.log
+    - /tmp/ue1.log
+  HostIPAddress : 192.168.18.89
+  HostUsername : root
+  HostPassword : toor 
+  HostSourceCodePath : /tmp
+
+
+#do not remove
 dummy:
   ID: ''
   State : ''
@@ -50,7 +98,7 @@ dummy:
   DetachScript : ''
   PLMN : 22201
   UENetwork : wwan0
-  HostIPAddress : 192.168.18.188
+  HostIPAddress : 172.21.16.135
   HostUsername : oaicicd
   HostPassword : oaicicd
   HostSourceCodePath : none
diff --git a/ci-scripts/cls_amarisoft_ue.py b/ci-scripts/cls_amarisoft_ue.py
new file mode 100644
index 0000000000000000000000000000000000000000..367bfaac3f7810a7dd1cd5ba32d98d81f0cdca06
--- /dev/null
+++ b/ci-scripts/cls_amarisoft_ue.py
@@ -0,0 +1,81 @@
+# * 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
+# */
+#---------------------------------------------------------------------
+#
+#   Required Python Version
+#     Python 3.x
+#
+#---------------------------------------------------------------------
+
+#to use isfile
+import os
+import sys
+import logging
+#to create a SSH object locally in the methods
+import sshconnection
+#time.sleep
+import time
+
+
+import re
+import subprocess
+
+from datetime import datetime
+
+
+class AS_UE:
+
+	def __init__(self,Module):
+		#create attributes as in the UE dictionary
+		for k, v in Module.items():
+			setattr(self, k, v)
+	
+
+
+
+#-----------------$
+#PUBLIC Methods$
+#-----------------$
+
+	def WaitEndScenario(self):
+		logging.debug('waiting for scenario duration')
+		time.sleep(int(self.Duration))
+
+	def KillASUE(self):
+		mySSH = sshconnection.SSHConnection()
+		mySSH.open(self.HostIPAddress, self.HostUsername, self.HostPassword)
+		mySSH.command('killall --signal SIGKILL lteue-avx2', '#', 5)
+		mySSH.close()
+
+	def RunScenario(self):
+		mySSH = sshconnection.SSHConnection()
+		mySSH.open(self.HostIPAddress, self.HostUsername, self.HostPassword)
+
+		logging.debug("Deleting old artifacts :")
+		cmd='rm -rf ' + self.Ping + ' ' + self.UELog 
+		mySSH.command(cmd,'#',5)
+		logging.debug("Running scenario :")
+		cmd='echo $USER; nohup '+self.Cmd + ' ' + self.Config + ' &'
+		mySSH.command(cmd,'#',5)
+
+		mySSH.close()
+
+
+
diff --git a/ci-scripts/cls_containerize.py b/ci-scripts/cls_containerize.py
index d85659568bc76b4973b89ed9b5cbbecf4a8944c1..89a3ac586d43504345b6692099028bf7a13595f6 100644
--- a/ci-scripts/cls_containerize.py
+++ b/ci-scripts/cls_containerize.py
@@ -93,6 +93,7 @@ class Containerize():
 		self.allImagesSize = {}
 		self.collectInfo = {}
 
+		self.deployedContainers = []
 		self.tsharkStarted = False
 		self.pingContName = ''
 		self.pingOptions = ''
@@ -242,7 +243,7 @@ class Containerize():
 		# Build the base image only on Push Events (not on Merge Requests)
 		# On when the base image docker file is being modified.
 		if forceBaseImageBuild:
-			mySSH.command(self.cli + ' build ' + self.cliBuildOptions + ' --target ' + baseImage + ' --tag ' + baseImage + ':' + baseTag + ' --file docker/Dockerfile.base' + self.dockerfileprefix + ' --build-arg NEEDED_GIT_PROXY="http://proxy.eurecom.fr:8080" . > cmake_targets/log/ran-base.log 2>&1', '\$', 1600)
+			mySSH.command(self.cli + ' build ' + self.cliBuildOptions + ' --target ' + baseImage + ' --tag ' + baseImage + ':' + baseTag + ' --file docker/Dockerfile.base' + self.dockerfileprefix + ' . > cmake_targets/log/ran-base.log 2>&1', '\$', 1600)
 		# First verify if the base image was properly created.
 		status = True
 		mySSH.command(self.cli + ' image inspect --format=\'Size = {{.Size}} bytes\' ' + baseImage + ':' + baseTag, '\$', 5)
@@ -682,12 +683,28 @@ class Containerize():
 		cmd = 'cd ' + self.yamlPath[0] + ' && docker-compose -f docker-compose-ci.yml ps -a'
 		count = 0
 		healthy = 0
+		newContainers = []
 		while (count < 10):
 			count += 1
 			containerStatus = []
 			deployStatus = subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT, universal_newlines=True, timeout=30)
 			healthy = 0
 			for state in deployStatus.split('\n'):
+				res = re.search('Name|----------', state)
+				if res is not None:
+					continue
+				if len(state) == 0:
+					continue
+				res = re.search('^(?P<container_name>[a-zA-Z0-9\-\_]+) ', state)
+				if res is not None:
+					cName = res.group('container_name')
+					found = False
+					for alreadyDeployed in self.deployedContainers:
+						if cName == alreadyDeployed:
+							found = True
+					if not found:
+						newContainers.append(cName)
+						self.deployedContainers.append(cName)
 				if re.search('Up \(healthy\)', state) is not None:
 					healthy += 1
 				if re.search('rfsim4g-db-init.*Exit 0', state) is not None:
@@ -698,16 +715,33 @@ class Containerize():
 			else:
 				time.sleep(10)
 
+		imagesInfo = ''
+		for newCont in newContainers:
+			cmd = 'docker inspect -f "{{.Config.Image}}" ' + newCont
+			imageName = subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT, universal_newlines=True, timeout=30)
+			imageName = str(imageName).strip()
+			cmd = 'docker image inspect --format "{{.RepoTags}}\t{{.Size}}\t{{.Created}}" ' + imageName
+			imagesInfo += subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT, universal_newlines=True, timeout=30)
+
+		html_queue = SimpleQueue()
+		html_cell = '<pre style="background-color:white">\n'
+		for imageInfo in imagesInfo.split('\n'):
+			html_cell += imageInfo[:-11] + '\n'
+		html_cell += '\n'
+		for cState in containerStatus:
+			html_cell += cState + '\n'
+		html_cell += '</pre>'
+		html_queue.put(html_cell)
 		if count == 100 and healthy == self.nb_healthy[0]:
 			if self.tsharkStarted == False:
 				logging.debug('Starting tshark on public network')
 				self.CaptureOnDockerNetworks()
-			HTML.CreateHtmlTestRow('n/a', 'OK', CONST.ALL_PROCESSES_OK)
+			HTML.CreateHtmlTestRowQueue('n/a', 'OK', 1, html_queue)
 			for cState in containerStatus:
 				logging.debug(cState)
 			logging.info('\u001B[1m Deploying OAI Object(s) PASS\u001B[0m')
 		else:
-			HTML.CreateHtmlTestRow('Could not deploy in time', 'KO', CONST.ALL_PROCESSES_OK)
+			HTML.CreateHtmlTestRowQueue('Could not deploy in time', 'KO', 1, html_queue)
 			for cState in containerStatus:
 				logging.debug(cState)
 			logging.error('\u001B[1m Deploying OAI Object(s) FAILED\u001B[0m')
@@ -723,13 +757,19 @@ class Containerize():
 		cmd = 'cd ' + self.yamlPath[0] + ' && docker-compose -f docker-compose-ci.yml config | grep com.docker.network.bridge.name | sed -e "s@^.*name: @@"'
 		networkNames = subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT, universal_newlines=True, timeout=10)
 		if re.search('4g.*rfsimulator', self.yamlPath[0]) is not None:
+			# Excluding any traffic from LTE-UE container (192.168.61.30)
+			# From the trf-gen, keeping only PING traffic
 			cmd = 'sudo nohup tshark -f "(host 192.168.61.11 and icmp) or (not host 192.168.61.11 and not host 192.168.61.30 and not arp and not port 53 and not port 2152)"'
 		elif re.search('5g.*rfsimulator', self.yamlPath[0]) is not None:
-			cmd = 'sudo nohup tshark -f "(host 192.168.72.135 and icmp) or (not host 192.168.72.135 and not host 192.168.71.150 and not arp and not port 53 and not port 2152 and not port 2153)"'
+			# Excluding any traffic from NR-UE containers (192.168.71.150 and 192.168.71.151)
+			# From the ext-dn, keeping only PING traffic
+			cmd = 'sudo nohup tshark -f "(host 192.168.72.135 and icmp) or (not host 192.168.72.135 and not host 192.168.71.150 and not host 192.168.71.151 and not arp and not port 53 and not port 2152 and not port 2153)"'
+		elif re.search('5g_l2sim', self.yamlPath[0]) is not None:
+			cmd = 'sudo nohup tshark -f "(host 192.168.72.135 and icmp) or (not host 192.168.72.135 and not arp and not port 53 and not port 2152 and not port 2153)"'
 		else:
 			return
 		for name in networkNames.split('\n'):
-			if re.search('rfsim', name) is not None:
+			if re.search('rfsim', name) is not None or re.search('l2sim', name) is not None:
 				cmd += ' -i ' + name
 		cmd += ' -w /tmp/capture_'
 		ymlPath = self.yamlPath[0].split('/')
@@ -781,46 +821,48 @@ class Containerize():
 			# Analyzing log file(s)!
 			listOfPossibleRanContainers = ['enb', 'gnb', 'cu', 'du']
 			for container in listOfPossibleRanContainers:
-				filename = self.yamlPath[0] + '/rfsim?g-oai-' + container + '.log'
-				cmd = 'ls ' + filename
+				filenames = self.yamlPath[0] + '/*-oai-' + container + '.log'
+				cmd = 'ls ' + filenames
 				containerStatus = True
 				try:
 					lsStatus = subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT, universal_newlines=True, timeout=10)
-					filename = str(lsStatus).strip()
+					filenames = str(lsStatus).strip()
 				except:
 					containerStatus = False
 				if not containerStatus:
 					continue
 
-				logging.debug('\u001B[1m Analyzing xNB logfile ' + filename + ' \u001B[0m')
-				logStatus = RAN.AnalyzeLogFile_eNB(filename, HTML, self.ran_checkers)
-				if (logStatus < 0):
-					fullStatus = False
-					self.exitStatus = 1
-					HTML.CreateHtmlTestRow(RAN.runtime_stats, 'KO', logStatus)
-				else:
-					HTML.CreateHtmlTestRow(RAN.runtime_stats, 'OK', CONST.ALL_PROCESSES_OK)
+				for filename in filenames.split('\n'):
+					logging.debug('\u001B[1m Analyzing xNB logfile ' + filename + ' \u001B[0m')
+					logStatus = RAN.AnalyzeLogFile_eNB(filename, HTML, self.ran_checkers)
+					if (logStatus < 0):
+						fullStatus = False
+						self.exitStatus = 1
+						HTML.CreateHtmlTestRow(RAN.runtime_stats, 'KO', logStatus)
+					else:
+						HTML.CreateHtmlTestRow(RAN.runtime_stats, 'OK', CONST.ALL_PROCESSES_OK)
 
 			listOfPossibleUeContainers = ['lte-ue*', 'nr-ue*']
 			for container in listOfPossibleUeContainers:
-				filename = self.yamlPath[0] + '/rfsim?g-oai-' + container + '.log'
-				cmd = 'ls ' + filename
+				filenames = self.yamlPath[0] + '/*-oai-' + container + '.log'
+				cmd = 'ls ' + filenames
 				containerStatus = True
 				try:
 					lsStatus = subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT, universal_newlines=True, timeout=10)
-					filename = str(lsStatus).strip()
+					filenames = str(lsStatus).strip()
 				except:
 					containerStatus = False
 				if not containerStatus:
 					continue
 
-				logging.debug('\u001B[1m Analyzing UE logfile ' + filename + ' \u001B[0m')
-				logStatus = UE.AnalyzeLogFile_UE(filename, HTML, RAN)
-				if (logStatus < 0):
-					fullStatus = False
-					HTML.CreateHtmlTestRow('UE log Analysis', 'KO', logStatus)
-				else:
-					HTML.CreateHtmlTestRow('UE log Analysis', 'OK', CONST.ALL_PROCESSES_OK)
+				for filename in filenames.split('\n'):
+					logging.debug('\u001B[1m Analyzing UE logfile ' + filename + ' \u001B[0m')
+					logStatus = UE.AnalyzeLogFile_UE(filename, HTML, RAN)
+					if (logStatus < 0):
+						fullStatus = False
+						HTML.CreateHtmlTestRow('UE log Analysis', 'KO', logStatus)
+					else:
+						HTML.CreateHtmlTestRow('UE log Analysis', 'OK', CONST.ALL_PROCESSES_OK)
 
 			cmd = 'rm ' + self.yamlPath[0] + '/*.log'
 			logging.debug(cmd)
@@ -851,6 +893,7 @@ class Containerize():
 			logging.error('\u001B[1m Undeploying OAI Object(s) FAILED\u001B[0m')
 			return
 
+		self.deployedContainers = []
 		# Cleaning any created tmp volume
 		cmd = 'docker volume prune --force || true'
 		logging.debug(cmd)
@@ -863,6 +906,40 @@ class Containerize():
 			HTML.CreateHtmlTestRow('n/a', 'KO', CONST.ALL_PROCESSES_OK)
 			logging.info('\u001B[1m Undeploying OAI Object(s) FAIL\u001B[0m')
 
+	def StatsFromGenObject(self, HTML):
+		self.exitStatus = 0
+		ymlPath = self.yamlPath[0].split('/')
+		logPath = '../cmake_targets/log/' + ymlPath[1]
+
+		# if the containers are running, recover the logs!
+		cmd = 'cd ' + self.yamlPath[0] + ' && docker-compose -f docker-compose-ci.yml ps --all'
+		logging.debug(cmd)
+		deployStatus = subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT, universal_newlines=True, timeout=30)
+		cmd = 'docker stats --no-stream --format "table {{.Container}}\t{{.CPUPerc}}\t{{.MemUsage}}\t{{.MemPerc}}" '
+		anyLogs = False
+		for state in deployStatus.split('\n'):
+			res = re.search('Name|----------', state)
+			if res is not None:
+				continue
+			if len(state) == 0:
+				continue
+			res = re.search('^(?P<container_name>[a-zA-Z0-9\-\_]+) ', state)
+			if res is not None:
+				anyLogs = True
+				cmd += res.group('container_name') + ' '
+		message = ''
+		if anyLogs:
+			logging.debug(cmd)
+			stats = subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT, universal_newlines=True, timeout=30)
+			for statLine in stats.split('\n'):
+				logging.debug(statLine)
+				message += statLine + '\n'
+
+		html_queue = SimpleQueue()
+		html_cell = '<pre style="background-color:white">\n' + message + '</pre>'
+		html_queue.put(html_cell)
+		HTML.CreateHtmlTestRowQueue(self.pingOptions, 'OK', 1, html_queue)
+
 	def PingFromContainer(self, HTML, RAN, UE):
 		self.exitStatus = 0
 		ymlPath = self.yamlPath[0].split('/')
@@ -1069,19 +1146,19 @@ class Containerize():
 			mySSH.open(ipAddr, userName, password)
 			# Check if route to asterix gnb exists
 			mySSH.command('ip route | grep --colour=never "192.168.68.64/26"', '\$', 10)
-			result = re.search('192.168.18.194', mySSH.getBefore())
+			result = re.search('172.21.16.127', mySSH.getBefore())
 			if result is None:
-				mySSH.command('echo ' + password + ' | sudo -S ip route add 192.168.68.64/26 via 192.168.18.194 dev eno1', '\$', 10)
+				mySSH.command('echo ' + password + ' | sudo -S ip route add 192.168.68.64/26 via 172.21.16.127 dev eno1', '\$', 10)
 			# Check if route to obelix enb exists
 			mySSH.command('ip route | grep --colour=never "192.168.68.128/26"', '\$', 10)
-			result = re.search('192.168.18.193', mySSH.getBefore())
+			result = re.search('172.21.16.128', mySSH.getBefore())
 			if result is None:
-				mySSH.command('echo ' + password + ' | sudo -S ip route add 192.168.68.128/26 via 192.168.18.193 dev eno1', '\$', 10)
+				mySSH.command('echo ' + password + ' | sudo -S ip route add 192.168.68.128/26 via 172.21.16.128 dev eno1', '\$', 10)
 			# Check if route to nepes gnb exists
 			mySSH.command('ip route | grep --colour=never "192.168.68.192/26"', '\$', 10)
-			result = re.search('192.168.18.209', mySSH.getBefore())
+			result = re.search('172.21.16.137', mySSH.getBefore())
 			if result is None:
-				mySSH.command('echo ' + password + ' | sudo -S ip route add 192.168.68.192/26 via 192.168.18.209 dev eno1', '\$', 10)
+				mySSH.command('echo ' + password + ' | sudo -S ip route add 192.168.68.192/26 via 172.21.16.137 dev eno1', '\$', 10)
 			# Check if forwarding is enabled
 			mySSH.command('sysctl net.ipv4.conf.all.forwarding', '\$', 10)
 			result = re.search('net.ipv4.conf.all.forwarding = 1', mySSH.getBefore())
@@ -1097,19 +1174,19 @@ class Containerize():
 			mySSH.open(ipAddr, userName, password)
 			# Check if route to porcepix epc exists
 			mySSH.command('ip route | grep --colour=never "192.168.61.192/26"', '\$', 10)
-			result = re.search('192.168.18.210', mySSH.getBefore())
+			result = re.search('172.21.16.136', mySSH.getBefore())
 			if result is None:
-				mySSH.command('echo ' + password + ' | sudo -S ip route add 192.168.61.192/26 via 192.168.18.210 dev em1', '\$', 10)
+				mySSH.command('echo ' + password + ' | sudo -S ip route add 192.168.61.192/26 via 172.21.16.136 dev em1', '\$', 10)
 			# Check if route to porcepix cn5g exists
 			mySSH.command('ip route | grep --colour=never "192.168.70.128/26"', '\$', 10)
-			result = re.search('192.168.18.210', mySSH.getBefore())
+			result = re.search('172.21.16.136', mySSH.getBefore())
 			if result is None:
-				mySSH.command('echo ' + password + ' | sudo -S ip route add 192.168.70.128/26 via 192.168.18.210 dev em1', '\$', 10)
+				mySSH.command('echo ' + password + ' | sudo -S ip route add 192.168.70.128/26 via 172.21.16.136 dev em1', '\$', 10)
 			# Check if X2 route to obelix enb exists
 			mySSH.command('ip route | grep --colour=never "192.168.68.128/26"', '\$', 10)
-			result = re.search('192.168.18.193', mySSH.getBefore())
+			result = re.search('172.21.16.128', mySSH.getBefore())
 			if result is None:
-				mySSH.command('echo ' + password + ' | sudo -S ip route add 192.168.68.128/26 via 192.168.18.193 dev em1', '\$', 10)
+				mySSH.command('echo ' + password + ' | sudo -S ip route add 192.168.68.128/26 via 172.21.16.128 dev em1', '\$', 10)
 			# Check if forwarding is enabled
 			mySSH.command('sysctl net.ipv4.conf.all.forwarding', '\$', 10)
 			result = re.search('net.ipv4.conf.all.forwarding = 1', mySSH.getBefore())
@@ -1125,19 +1202,19 @@ class Containerize():
 			mySSH.open(ipAddr, userName, password)
 			# Check if route to porcepix epc exists
 			mySSH.command('ip route | grep --colour=never "192.168.61.192/26"', '\$', 10)
-			result = re.search('192.168.18.210', mySSH.getBefore())
+			result = re.search('172.21.16.136', mySSH.getBefore())
 			if result is None:
-				mySSH.command('echo ' + password + ' | sudo -S ip route add 192.168.61.192/26 via 192.168.18.210 dev eno1', '\$', 10)
+				mySSH.command('echo ' + password + ' | sudo -S ip route add 192.168.61.192/26 via 172.21.16.136 dev eno1', '\$', 10)
 			# Check if X2 route to asterix gnb exists
 			mySSH.command('ip route | grep --colour=never "192.168.68.64/26"', '\$', 10)
-			result = re.search('192.168.18.194', mySSH.getBefore())
+			result = re.search('172.21.16.127', mySSH.getBefore())
 			if result is None:
-				mySSH.command('echo ' + password + ' | sudo -S ip route add 192.168.68.64/26 via 192.168.18.194 dev eno1', '\$', 10)
+				mySSH.command('echo ' + password + ' | sudo -S ip route add 192.168.68.64/26 via 172.21.16.127 dev eno1', '\$', 10)
 			# Check if X2 route to nepes gnb exists
 			mySSH.command('ip route | grep --colour=never "192.168.68.192/26"', '\$', 10)
-			result = re.search('192.168.18.209', mySSH.getBefore())
+			result = re.search('172.21.16.137', mySSH.getBefore())
 			if result is None:
-				mySSH.command('echo ' + password + ' | sudo -S ip route add 192.168.68.192/26 via 192.168.18.209 dev eno1', '\$', 10)
+				mySSH.command('echo ' + password + ' | sudo -S ip route add 192.168.68.192/26 via 172.21.16.137 dev eno1', '\$', 10)
 			# Check if forwarding is enabled
 			mySSH.command('sysctl net.ipv4.conf.all.forwarding', '\$', 10)
 			result = re.search('net.ipv4.conf.all.forwarding = 1', mySSH.getBefore())
@@ -1153,14 +1230,14 @@ class Containerize():
 			mySSH.open(ipAddr, userName, password)
 			# Check if route to porcepix epc exists
 			mySSH.command('ip route | grep --colour=never "192.168.61.192/26"', '\$', 10)
-			result = re.search('192.168.18.210', mySSH.getBefore())
+			result = re.search('172.21.16.136', mySSH.getBefore())
 			if result is None:
-				mySSH.command('echo ' + password + ' | sudo -S ip route add 192.168.61.192/26 via 192.168.18.210 dev enp0s31f6', '\$', 10)
+				mySSH.command('echo ' + password + ' | sudo -S ip route add 192.168.61.192/26 via 172.21.16.136 dev enp0s31f6', '\$', 10)
 			# Check if X2 route to obelix enb exists
 			mySSH.command('ip route | grep --colour=never "192.168.68.128/26"', '\$', 10)
-			result = re.search('192.168.18.193', mySSH.getBefore())
+			result = re.search('172.21.16.128', mySSH.getBefore())
 			if result is None:
-				mySSH.command('echo ' + password + ' | sudo -S ip route add 192.168.68.128/26 via 192.168.18.193 dev enp0s31f6', '\$', 10)
+				mySSH.command('echo ' + password + ' | sudo -S ip route add 192.168.68.128/26 via 172.21.16.128 dev enp0s31f6', '\$', 10)
 			# Check if forwarding is enabled
 			mySSH.command('sysctl net.ipv4.conf.all.forwarding', '\$', 10)
 			result = re.search('net.ipv4.conf.all.forwarding = 1', mySSH.getBefore())
diff --git a/ci-scripts/cls_log_mgt.py b/ci-scripts/cls_log_mgt.py
index 905a105512213e0c8ad80e450931d2dd43de99c8..f1dbf6b8ec2a90bba38808f0f27e4aa54ec9383c 100644
--- a/ci-scripts/cls_log_mgt.py
+++ b/ci-scripts/cls_log_mgt.py
@@ -64,10 +64,10 @@ class Log_Mgt:
 		if m is not None:
 			return int(m.group(1))
 
-	def __RemoveOldest(self):
+	def __RemoveOldest(self, days):
 		mySSH = sshconnection.SSHConnection()
 		mySSH.open(self.IPAddress, self.Username, self.Password)
-		COMMAND='echo ' + self.Password + ' | sudo -S find ' + self.path + ' -type f -mtime +14 -delete'
+		COMMAND='echo ' + self.Password + ' | sudo -S find ' + self.path + ' -type f -mtime +' +  str(days) + ' -delete'
 		mySSH.command(COMMAND,'\$',20)
 		mySSH.close()
 
@@ -79,13 +79,18 @@ class Log_Mgt:
 
 
 	def LogRotation(self):
-		used_space = self.__CheckUsedSpace() #avail space in target folder
-		if used_space > 80 :
-			logging.debug('\u001B[1;37;41m  Used Disk > 80%, on '  + self.Username+'@'+self.IPAddress + '\u001B[0m')
-			logging.debug('\u001B[1;37;41m  Removing Artifacts older than 14 days \u001B[0m')
-			self.__RemoveOldest()
-		else:
-			logging.debug('Used Disk < 80%, on '  + self.Username+'@'+self.IPAddress +', no cleaning required')
+		doLoop = True
+		nbDays = 14
+		while doLoop and nbDays > 1:
+			used_space = self.__CheckUsedSpace() #avail space in target folder
+			if used_space > 80 :
+				logging.debug('\u001B[1;37;41m  Used Disk (' + str(used_space) + '%) > 80%, on '  + self.Username+'@'+self.IPAddress + '\u001B[0m')
+				logging.debug('\u001B[1;37;41m  Removing Artifacts older than ' + str(nbDays) + ' days \u001B[0m')
+				self.__RemoveOldest(nbDays)
+				nbDays -= 1
+			else:
+				logging.debug('Used Disk (' + str(used_space) + '%) < 80%, on '  + self.Username+'@'+self.IPAddress +', no cleaning required')
+				doLoop = False
 
 
 			
diff --git a/ci-scripts/cls_module_ue.py b/ci-scripts/cls_module_ue.py
index fb107007980d53059da297e06bcb396a80922480..dcf75a34fcd616a111cc3c98fc25f1e9281706dd 100644
--- a/ci-scripts/cls_module_ue.py
+++ b/ci-scripts/cls_module_ue.py
@@ -107,14 +107,15 @@ class Module_UE:
 	def GetModuleIPAddress(self):
 		HOST=self.HostUsername+'@'+self.HostIPAddress
 		response= []
-		tentative = 3 
+		tentative = 8
 		while (len(response)==0) and (tentative>0):
 			COMMAND="ip a show dev " + self.UENetwork + " | grep --colour=never inet | grep " + self.UENetwork
-			logging.debug(COMMAND)
+			if tentative == 8:
+				logging.debug(COMMAND)
 			ssh = subprocess.Popen(["ssh", "%s" % HOST, COMMAND],shell=False,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
 			response = ssh.stdout.readlines()
 			tentative-=1
-			time.sleep(10)
+			time.sleep(2)
 		if (tentative==0) and (len(response)==0):
 			logging.debug('\u001B[1;37;41m Module IP Address Not Found! Time expired \u001B[0m')
 			return -1
diff --git a/ci-scripts/html.py b/ci-scripts/cls_oai_html.py
similarity index 100%
rename from ci-scripts/html.py
rename to ci-scripts/cls_oai_html.py
diff --git a/ci-scripts/cls_oaicitest.py b/ci-scripts/cls_oaicitest.py
index 0865d4efb5b961555ad44f7d479eca9aed935783..9d5ae840387e4e9d12ba33352e913167fd1ce4c4 100644
--- a/ci-scripts/cls_oaicitest.py
+++ b/ci-scripts/cls_oaicitest.py
@@ -55,6 +55,7 @@ import constants as CONST
 import sshconnection
 
 import cls_module_ue
+import cls_amarisoft_ue
 import cls_ci_ueinfra		#class defining the multi Ue infrastrucure
 
 logging.getLogger("matplotlib").setLevel(logging.WARNING)
@@ -419,49 +420,63 @@ class OaiCiTest():
 			for job in multi_jobs:
 				job.join()
 			HTML.CreateHtmlTestRow('N/A', 'OK', CONST.ALL_PROCESSES_OK)
-		else: #if an ID is specified, it is a module from the yaml infrastructure file
-			#RH
-			Module_UE = cls_module_ue.Module_UE(InfraUE.ci_ue_infra[self.ue_id])
-			Module_UE.ue_trace=ue_trace
-			is_module=Module_UE.CheckCMProcess(EPC.Type)
-			if is_module:
-				Module_UE.EnableTrace()
-				time.sleep(5)
+		else: #if an ID is specified, it is a UE from the yaml infrastructure file
+			ue_kind = InfraUE.ci_ue_infra[self.ue_id]['Kind']
+			logging.debug("Detected UE Kind : " + ue_kind)
+
+			#case it is a quectel module (only 1 at a time supported at the moment)
+			if ue_kind == 'quectel':
+				Module_UE = cls_module_ue.Module_UE(InfraUE.ci_ue_infra[self.ue_id])
+				Module_UE.ue_trace=ue_trace
+				is_module=Module_UE.CheckCMProcess(EPC.Type)
+				if is_module:
+					Module_UE.EnableTrace()
+					time.sleep(5)
+
+					# Looping attach / detach / wait to be successful at least once
+					cnt = 0
+					status = -1
+					while cnt < 4:
+						Module_UE.Command("wup")
+						logging.debug("Waiting for IP address to be assigned")
+						time.sleep(5)
+						logging.debug("Retrieve IP address")
+						status=Module_UE.GetModuleIPAddress()
+						if status==0:
+							cnt = 10
+						else:
+							cnt += 1
+							Module_UE.Command("detach")
+							time.sleep(20)
+
+					if cnt == 10 and status == 0:
+						HTML.CreateHtmlTestRow(Module_UE.UEIPAddress, 'OK', CONST.ALL_PROCESSES_OK)	
+						logging.debug('UE IP addresss : '+ Module_UE.UEIPAddress)
+						#execute additional commands from yaml file after UE attach
+						SSH = sshconnection.SSHConnection()
+						SSH.open(Module_UE.HostIPAddress, Module_UE.HostUsername, Module_UE.HostPassword)
+						if hasattr(Module_UE,'StartCommands'):
+							for startcommand in Module_UE.StartCommands:
+								cmd = 'echo ' + Module_UE.HostPassword + ' | ' + startcommand
+								SSH.command(cmd,'\$',5)
+						SSH.close()
+						#check that the MTU is as expected / requested
+						Module_UE.CheckModuleMTU()
+					else: #status==-1 failed to retrieve IP address
+						HTML.CreateHtmlTestRow('N/A', 'KO', CONST.UE_IP_ADDRESS_ISSUE)
+						self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE,CONTAINERS)
+						return
 
-				# Looping attach / detach / wait to be successful at least once
-				cnt = 0
-				status = -1
-				while cnt < 4:
-					Module_UE.Command("wup")
-					logging.debug("Waiting for IP address to be assigned")
-					time.sleep(20)
-					logging.debug("Retrieve IP address")
-					status=Module_UE.GetModuleIPAddress()
-					if status==0:
-						cnt = 10
-					else:
-						cnt += 1
-						Module_UE.Command("detach")
-						time.sleep(20)
-
-				if cnt == 10 and status == 0:
-					HTML.CreateHtmlTestRow(Module_UE.UEIPAddress, 'OK', CONST.ALL_PROCESSES_OK)	
-					logging.debug('UE IP addresss : '+ Module_UE.UEIPAddress)
-					#execute additional commands from yaml file after UE attach
-					SSH = sshconnection.SSHConnection()
-					SSH.open(Module_UE.HostIPAddress, Module_UE.HostUsername, Module_UE.HostPassword)
-					if hasattr(Module_UE,'StartCommands'):
-						for startcommand in Module_UE.StartCommands:
-							cmd = 'echo ' + Module_UE.HostPassword + ' | ' + startcommand
-							SSH.command(cmd,'\$',5)
-					SSH.close()
-					#check that the MTU is as expected / requested
-					Module_UE.CheckModuleMTU()
-				else: #status==-1 failed to retrieve IP address
-					HTML.CreateHtmlTestRow('N/A', 'KO', CONST.UE_IP_ADDRESS_ISSUE)
-					self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE,CONTAINERS)
-					return
-			
+			#case it is a amarisoft ue (only 1 at a time supported at the moment)
+			elif ue_kind == 'amarisoft':
+				AS_UE = cls_amarisoft_ue.AS_UE(InfraUE.ci_ue_infra[self.ue_id])
+				HTML.CreateHtmlTestRow(AS_UE.Config, 'OK', CONST.ALL_PROCESSES_OK)
+				AS_UE.RunScenario()
+				AS_UE.WaitEndScenario()
+				AS_UE.KillASUE()
+
+			else:
+				logging.debug("Incorrect UE Kind was detected")								
 
 
 	def InitializeOAIUE(self,HTML,RAN,EPC,COTS_UE,InfraUE,CONTAINERS):
@@ -1096,7 +1111,7 @@ class OaiCiTest():
 			while cnt < 4:
 				Module_UE.Command("wup")
 				logging.debug("Waiting for IP address to be assigned")
-				time.sleep(20)
+				time.sleep(5)
 				logging.debug("Retrieve IP address")
 				status=Module_UE.GetModuleIPAddress()
 				if status==0:
@@ -1570,16 +1585,23 @@ class OaiCiTest():
 			SSH = sshconnection.SSHConnection()
 			# Launch ping on the EPC side (true for ltebox and old open-air-cn)
 			# But for OAI-Rel14-CUPS, we launch from python executor
+			ping_status = 0
 			launchFromEpc = True
 			launchFromModule = False
+			launchFromASUE = False
 			if re.match('OAI-Rel14-CUPS', EPC.Type, re.IGNORECASE):
 				launchFromEpc = False
 			#if module, ping from module to EPC
 			if self.ue_id!='':
-				launchFromEpc = False
-				launchfromModule = True
-
-			ping_time = re.findall("-c (\d+)",str(self.ping_args))
+				if (re.match('amarisoft', self.ue_id, re.IGNORECASE)):
+					launchFromEpc = False
+					launchFromASUE = True
+				else:
+					launchFromEpc = False
+					launchFromModule = True
+			#no ping args for ASUE
+			if self.ping_args!='':
+				ping_time = re.findall("-c (\d+)",str(self.ping_args))
 
 			if launchFromEpc:
 				SSH.open(EPC.IPAddress, EPC.UserName, EPC.Password)
@@ -1597,14 +1619,14 @@ class OaiCiTest():
 				#copy the ping log file to have it locally for analysis (ping stats)
 				SSH.copyin(EPC.IPAddress, EPC.UserName, EPC.Password, EPC.SourceCodePath + '/scripts/ping_' + self.testCase_id + '_' + device_id + '.log', '.')				
 			else:
-				if launchfromModule == False:
+				if (launchFromModule == False) and (launchFromASUE == False):
 					#ping log file is on the python executor
 					cmd = 'ping ' + self.ping_args + ' ' + UE_IPAddress + ' > ping_' + self.testCase_id + '_' + device_id + '.log 2>&1'
 					message = cmd + '\n'
 					logging.debug(cmd)
 					ret = subprocess.run(cmd, shell=True)
 					ping_status = ret.returncode
-					#copy the ping log file to an other folder for log collection (source and destination are EPC)
+					#copy the ping log file to an other folder for log collection (source and desti				elif (launchfromModule == True) and (launchfromASUE == False): #launch from Modulenation are EPC)
 					SSH.copyout(EPC.IPAddress, EPC.UserName, EPC.Password, 'ping_' + self.testCase_id + '_' + device_id + '.log', EPC.SourceCodePath + '/scripts')
                 	#copy the ping log file to have it locally for analysis (ping stats)
 					logging.debug(EPC.SourceCodePath + 'ping_' + self.testCase_id + '_' + device_id + '.log')
@@ -1614,7 +1636,8 @@ class OaiCiTest():
 					#cat is executed on EPC
 					SSH.command('cat ' + EPC.SourceCodePath + '/scripts/ping_' + self.testCase_id + '_' + device_id + '.log', '\$', 5)
 					ping_log_file='/scripts/ping_' + self.testCase_id + '_' + device_id + '.log'
-				else: #launch from Module
+
+				elif (launchFromModule == True) and (launchFromASUE == False): #launch from Module
 					SSH.open(Module_UE.HostIPAddress, Module_UE.HostUsername, Module_UE.HostPassword)
 					#target address is different depending on EPC type
 					if re.match('OAI-Rel14-Docker', EPC.Type, re.IGNORECASE):
@@ -1626,13 +1649,27 @@ class OaiCiTest():
 					#ping from module NIC rather than IP address to make sure round trip is over the air	
 					cmd = 'ping -I ' + Module_UE.UENetwork  + ' ' + self.ping_args + ' ' +  Target  + ' > ping_' + self.testCase_id + '_' + self.ue_id + '.log 2>&1'
 					SSH.command(cmd,'\$',int(ping_time[0])*1.5)
+
 					#copy the ping log file to have it locally for analysis (ping stats)
 					SSH.copyin(Module_UE.HostIPAddress, Module_UE.HostUsername, Module_UE.HostPassword, 'ping_' + self.testCase_id + '_' + self.ue_id + '.log', '.')
 
 					#cat is executed locally 
 					SSH.command('cat ping_' + self.testCase_id + '_' + self.ue_id + '.log', '\$', 5)
 					ping_log_file='ping_' + self.testCase_id + '_' + self.ue_id + '.log'
-					ping_status=0
+
+				elif (launchFromASUE == True): 
+					#ping was already executed when running scenario
+					#we only need to retrieve ping log file, whose location is in the ci_ueinfra.yaml
+					logging.debug("Get logs from AS server : " + Module_UE.Ping + ", " + Module_UE.UELog)
+					SSH.copyin(Module_UE.HostIPAddress, Module_UE.HostUsername, Module_UE.HostPassword, Module_UE.Ping, '.')
+					SSH.copyin(Module_UE.HostIPAddress, Module_UE.HostUsername, Module_UE.HostPassword, Module_UE.UELog, '.')
+					logging.debug("Ping analysis from Amarisoft scenario")
+					path,ping_log_file = os.path.split(Module_UE.Ping)
+					SSH.open(Module_UE.HostIPAddress, Module_UE.HostUsername, Module_UE.HostPassword)
+					SSH.command('cat ' + Module_UE.Ping, '\#', 5)
+
+				else:
+					ping_status=-1
 
 			# TIMEOUT CASE
 			if ping_status < 0:
@@ -1680,28 +1717,30 @@ class OaiCiTest():
 
 			#adding extra ping stats from local file
 			#ping_log_file variable is defined above in this function, depending on device/ue
-			logging.debug('Analyzing Ping log file : ' + os.getcwd() + '/' + ping_log_file)
-			ping_stat=GetPingTimeAnalysis(RAN,ping_log_file,self.ping_rttavg_threshold)
 			ping_stat_msg=''
-			if (ping_stat!=-1) and (len(ping_stat)!=0):
-				ping_stat_msg+='Ping stats before removing largest value : \n'
-				ping_stat_msg+='RTT(Min)    : ' + str("{:.2f}".format(ping_stat['min_0'])) + 'ms \n'
-				ping_stat_msg+='RTT(Mean)   : ' + str("{:.2f}".format(ping_stat['mean_0'])) + 'ms \n'
-				ping_stat_msg+='RTT(Median) : ' + str("{:.2f}".format(ping_stat['median_0'])) + 'ms \n'
-				ping_stat_msg+='RTT(Max)    : ' + str("{:.2f}".format(ping_stat['max_0'])) + 'ms \n'
-				ping_stat_msg+='Max Index   : ' + str(ping_stat['max_loc']) + '\n'
-				ping_stat_msg+='Ping stats after removing largest value : \n'
-				ping_stat_msg+='RTT(Min)    : ' + str("{:.2f}".format(ping_stat['min_1'])) + 'ms \n'
-				ping_stat_msg+='RTT(Mean)   : ' + str("{:.2f}".format(ping_stat['mean_1'])) + 'ms \n'
-				ping_stat_msg+='RTT(Median) : ' + str("{:.2f}".format(ping_stat['median_1'])) + 'ms \n'
-				ping_stat_msg+='RTT(Max)    : ' + str("{:.2f}".format(ping_stat['max_1'])) + 'ms \n'
+			if launchFromASUE == False : #skip in case of AS UE (for the moment)
+				logging.debug('Analyzing Ping log file : ' + os.getcwd() + '/' + ping_log_file)
+				ping_stat=GetPingTimeAnalysis(RAN,ping_log_file,self.ping_rttavg_threshold)
+
+				if (ping_stat!=-1) and (len(ping_stat)!=0):
+					ping_stat_msg+='Ping stats before removing largest value : \n'
+					ping_stat_msg+='RTT(Min)    : ' + str("{:.2f}".format(ping_stat['min_0'])) + 'ms \n'
+					ping_stat_msg+='RTT(Mean)   : ' + str("{:.2f}".format(ping_stat['mean_0'])) + 'ms \n'
+					ping_stat_msg+='RTT(Median) : ' + str("{:.2f}".format(ping_stat['median_0'])) + 'ms \n'
+					ping_stat_msg+='RTT(Max)    : ' + str("{:.2f}".format(ping_stat['max_0'])) + 'ms \n'
+					ping_stat_msg+='Max Index   : ' + str(ping_stat['max_loc']) + '\n'
+					ping_stat_msg+='Ping stats after removing largest value : \n'
+					ping_stat_msg+='RTT(Min)    : ' + str("{:.2f}".format(ping_stat['min_1'])) + 'ms \n'
+					ping_stat_msg+='RTT(Mean)   : ' + str("{:.2f}".format(ping_stat['mean_1'])) + 'ms \n'
+					ping_stat_msg+='RTT(Median) : ' + str("{:.2f}".format(ping_stat['median_1'])) + 'ms \n'
+					ping_stat_msg+='RTT(Max)    : ' + str("{:.2f}".format(ping_stat['max_1'])) + 'ms \n'
 
 			#building html message
 			qMsg = pal_msg + '\n' + min_msg + '\n' + avg_msg + '\n' + max_msg + '\n'  + ping_stat_msg
 
 			#checking packet loss compliance
 			packetLossOK = True
-			if packetloss is not None:
+			if (packetloss is not None) :
 				if float(packetloss) > float(self.ping_packetloss_threshold):
 					qMsg += '\nPacket Loss too high'
 					logging.debug('\u001B[1;37;41m Packet Loss too high; Target: '+ self.ping_packetloss_threshold + '%\u001B[0m')
@@ -1729,6 +1768,7 @@ class OaiCiTest():
 			lock.release()
 			SSH.close()
 		except:
+			logging.debug('exit from Ping_Common except')
 			os.kill(os.getppid(),signal.SIGUSR1)
 
 	def PingNoS1_wrong_exit(self, qMsg,HTML):
@@ -1856,11 +1896,21 @@ class OaiCiTest():
 				HTML.CreateHtmlTestRow(self.ping_args, 'KO', CONST.UE_IP_ADDRESS_ISSUE)
 				self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE,CONTAINERS)
 				return
-		else:
-			self.UEIPAddresses=[]
-			Module_UE = cls_module_ue.Module_UE(InfraUE.ci_ue_infra[self.ue_id])
-			Module_UE.GetModuleIPAddress()
-			self.UEIPAddresses.append(Module_UE.UEIPAddress)
+		else: #if an ID is specified, it is a UE from the yaml infrastructure file
+			ue_kind = InfraUE.ci_ue_infra[self.ue_id]['Kind']
+			logging.debug("Detected UE Kind : " + ue_kind)
+
+			if ue_kind == 'quectel':
+				self.UEIPAddresses=[]
+				Module_UE = cls_module_ue.Module_UE(InfraUE.ci_ue_infra[self.ue_id])
+				Module_UE.GetModuleIPAddress()
+				self.UEIPAddresses.append(Module_UE.UEIPAddress)
+			elif ue_kind == 'amarisoft':
+				self.UEIPAddresses=['AS UE IP']
+				Module_UE = cls_module_ue.Module_UE(InfraUE.ci_ue_infra[self.ue_id])
+			else:
+				logging.debug("Incorrect UE Kind was detected")	
+
 		logging.debug(self.UEIPAddresses)
 		multi_jobs = []
 		i = 0
@@ -1871,6 +1921,7 @@ class OaiCiTest():
 				device_id = self.UEDevices[i]
 			else:
 				device_id = Module_UE.ID + "-" + Module_UE.Kind 
+				logging.debug(device_id)
 			p = Process(target = self.Ping_common, args = (lock,UE_IPAddress,device_id,status_queue,EPC,Module_UE,RAN,))
 			p.daemon = True
 			p.start()
@@ -3156,10 +3207,12 @@ class OaiCiTest():
 		nrFoundDCI = 0
 		nrCRCOK = 0
 		mbms_messages = 0
+		nbPduSessAccept = 0
+		nbPduDiscard = 0
 		HTML.htmlUEFailureMsg=''
 		global_status = CONST.ALL_PROCESSES_OK
 		for line in ue_log_file.readlines():
-			result = re.search('nr_synchro_time', str(line))
+			result = re.search('nr_synchro_time|Starting NR UE soft modem', str(line))
 			if result is not None:
 				nrUEFlag = True
 			if nrUEFlag:
@@ -3172,6 +3225,15 @@ class OaiCiTest():
 				result = re.search('CRC OK', str(line))
 				if result is not None:
 					nrCRCOK += 1
+				result = re.search('Received PDU Session Establishment Accept', str(line))
+				if result is not None:
+					nbPduSessAccept += 1
+				result = re.search('warning: discard PDU, sn out of window', str(line))
+				if result is not None:
+					nbPduDiscard += 1
+				result = re.search('--nfapi 5 --node-number 2 --sa', str(line))
+				if result is not None:
+					frequency_found = True
 			result = re.search('Exiting OAI softmodem', str(line))
 			if result is not None:
 				exitSignalReceived = True
@@ -3302,21 +3364,29 @@ class OaiCiTest():
 			HTML.htmlUEFailureMsg=HTML.htmlUEFailureMsg + statMsg + '\n'
 		if nrUEFlag:
 			if nrDecodeMib > 0:
-				statMsg = 'UE showed ' + str(nrDecodeMib) + ' MIB decode message(s)'
+				statMsg = 'UE showed ' + str(nrDecodeMib) + ' "MIB decode" message(s)'
 				logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m')
 				HTML.htmlUEFailureMsg=HTML.htmlUEFailureMsg + statMsg + '\n'
 			if nrFoundDCI > 0:
-				statMsg = 'UE showed ' + str(nrFoundDCI) + ' DCI found message(s)'
+				statMsg = 'UE showed ' + str(nrFoundDCI) + ' "DCI found" message(s)'
 				logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m')
 				HTML.htmlUEFailureMsg=HTML.htmlUEFailureMsg + statMsg + '\n'
 			if nrCRCOK > 0:
-				statMsg = 'UE showed ' + str(nrCRCOK) + ' PDSCH decoding message(s)'
+				statMsg = 'UE showed ' + str(nrCRCOK) + ' "PDSCH decoding" message(s)'
 				logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m')
 				HTML.htmlUEFailureMsg=HTML.htmlUEFailureMsg + statMsg + '\n'
 			if not frequency_found:
 				statMsg = 'NR-UE could NOT synch!'
 				logging.error('\u001B[1;30;43m ' + statMsg + ' \u001B[0m')
 				HTML.htmlUEFailureMsg=HTML.htmlUEFailureMsg + statMsg + '\n'
+			if nbPduSessAccept > 0:
+				statMsg = 'UE showed ' + str(nbPduSessAccept) + ' "Received PDU Session Establishment Accept" message(s)'
+				logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m')
+				HTML.htmlUEFailureMsg=HTML.htmlUEFailureMsg + statMsg + '\n'
+			if nbPduDiscard > 0:
+				statMsg = 'UE showed ' + str(nbPduDiscard) + ' "warning: discard PDU, sn out of window" message(s)'
+				logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m')
+				HTML.htmlUEFailureMsg=HTML.htmlUEFailureMsg + statMsg + '\n'
 		if uciStatMsgCount > 0:
 			statMsg = 'UE showed ' + str(uciStatMsgCount) + ' "uci->stat" message(s)'
 			logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m')
@@ -3447,16 +3517,23 @@ class OaiCiTest():
 				job.join()
 			HTML.CreateHtmlTestRow('N/A', 'OK', CONST.ALL_PROCESSES_OK)
 		else: #if an ID is specified, it is a module from the yaml infrastructure file
-			Module_UE = cls_module_ue.Module_UE(InfraUE.ci_ue_infra[self.ue_id])
-			Module_UE.ue_trace=ue_trace
-			Module_UE.Command("detach")	
-			Module_UE.DisableTrace()
-			Module_UE.DisableCM()
-			archive_destination=Module_UE.LogCollect()
-			if Module_UE.ue_trace=='yes':
-				HTML.CreateHtmlTestRow('QLog at : '+archive_destination, 'OK', CONST.ALL_PROCESSES_OK)
+			ue_kind = InfraUE.ci_ue_infra[self.ue_id]['Kind']
+			logging.debug("Detected UE Kind : " + ue_kind)
+			if ue_kind == 'quectel':
+				Module_UE = cls_module_ue.Module_UE(InfraUE.ci_ue_infra[self.ue_id])
+				Module_UE.ue_trace=ue_trace
+				Module_UE.Command("detach")
+				Module_UE.DisableTrace()
+				Module_UE.DisableCM()
+				archive_destination=Module_UE.LogCollect()
+				if Module_UE.ue_trace=='yes':
+					HTML.CreateHtmlTestRow('QLog at : '+archive_destination, 'OK', CONST.ALL_PROCESSES_OK)
+				else:
+					HTML.CreateHtmlTestRow('QLog trace is disabled', 'OK', CONST.ALL_PROCESSES_OK)
+			elif ue_kind == 'amarisoft':
+				HTML.CreateHtmlTestRow('AS UE is already terminated', 'OK', CONST.ALL_PROCESSES_OK)
 			else:
-				HTML.CreateHtmlTestRow('QLog trace is disabled', 'OK', CONST.ALL_PROCESSES_OK)			
+				logging.debug("Incorrect UE Kind was detected")
 
 	def TerminateOAIUE(self,HTML,RAN,COTS_UE,EPC,InfraUE,CONTAINERS):
 		SSH = sshconnection.SSHConnection()
diff --git a/ci-scripts/cls_physim.py b/ci-scripts/cls_physim.py
index 33792f6ca4cb2c57f6179c1460ef43f3d2b0d183..ecd8f63af121561c3d004b2f2a0bef9443b71bf4 100644
--- a/ci-scripts/cls_physim.py
+++ b/ci-scripts/cls_physim.py
@@ -32,7 +32,7 @@ import logging
 #to create a SSH object locally in the methods
 import sshconnection
 #to update the HTML object
-import html
+import cls_oai_html
 from multiprocessing import SimpleQueue
 #for log folder maintenance
 import os
diff --git a/ci-scripts/cls_physim1.py b/ci-scripts/cls_physim1.py
index 83fb74b7cb0e030969dd82e654ad2eb4470d184c..3907fc2a34d3364225f0c9534b1350cb0dbcd4f4 100644
--- a/ci-scripts/cls_physim1.py
+++ b/ci-scripts/cls_physim1.py
@@ -33,7 +33,7 @@
 #-----------------------------------------------------------
 import logging
 import sshconnection as SSH
-import html
+import cls_oai_html
 import os
 import re
 import time
@@ -153,6 +153,7 @@ class PhySim:
 		mySSH.command(f'oc project {ocProjectName}', '\$', 30)
 		if mySSH.getBefore().count(f'Already on project "{ocProjectName}"') == 0 and mySSH.getBefore().count(f'Now using project "{self.OCProjectName}"') == 0:
 			logging.error(f'\u001B[1m Unable to access OC project {ocProjectName}\u001B[0m')
+			mySSH.command('oc logout', '\$', 30)
 			mySSH.close()
 			HTML.CreateHtmlTestRow('N/A', 'KO', CONST.OC_PROJECT_FAIL)
 			RAN.prematureExit = True
@@ -161,9 +162,10 @@ class PhySim:
 			logging.debug(f'\u001B[1m   Now using project {ocProjectName}\u001B[0m')
 
 		# Tag the image and push to the OC cluster
-		mySSH.command('oc whoami -t | sudo podman login -u ' + ocUserName + ' --password-stdin https://default-route-openshift-image-registry.apps.5glab.nsa.eurecom.fr/ --tls-verify=false', '\$', 30)
+		mySSH.command('oc whoami -t | sudo podman login -u ' + ocUserName + ' --password-stdin https://default-route-openshift-image-registry.apps.oai.cs.eurecom.fr/ --tls-verify=false', '\$', 30)
 		if mySSH.getBefore().count('Login Succeeded!') == 0:
 			logging.error('\u001B[1m Podman Login to OC Cluster Registry Failed\u001B[0m')
+			mySSH.command('oc logout', '\$', 30)
 			mySSH.close()
 			HTML.CreateHtmlTestRow('N/A', 'KO', CONST.OC_LOGIN_FAIL)
 			RAN.prematureExit = True
@@ -171,9 +173,11 @@ class PhySim:
 		else:
 			logging.debug('\u001B[1m Podman Login to OC Cluster Registry Successfully\u001B[0m')
 		time.sleep(2)
-		mySSH.command('oc create -f openshift/oai-physim-image-stream.yml', '\$', 30)
+		mySSH.command('oc create -f openshift/oai-physim-image-stream.yml || true', '\$', 30)
 		if mySSH.getBefore().count('(AlreadyExists):') == 0 and mySSH.getBefore().count('created') == 0:
 			logging.error(f'\u001B[1m Image Stream "oai-physim" Creation Failed on OC Cluster {ocProjectName}\u001B[0m')
+			mySSH.command('sudo podman logout https://default-route-openshift-image-registry.apps.oai.cs.eurecom.fr/', '\$', 6)
+			mySSH.command('oc logout', '\$', 30)
 			mySSH.close()
 			HTML.CreateHtmlTestRow('N/A', 'KO', CONST.OC_IS_FAIL)
 			RAN.prematureExit = True
@@ -181,11 +185,13 @@ class PhySim:
 		else:
 			logging.debug(f'\u001B[1m   Image Stream "oai-physim" created on OC project {ocProjectName}\u001B[0m')
 		time.sleep(2)
-		mySSH.command(f'sudo podman tag oai-physim:{imageTag} default-route-openshift-image-registry.apps.5glab.nsa.eurecom.fr/{self.OCProjectName}/oai-physim:{imageTag}', '\$', 30)
+		mySSH.command(f'sudo podman tag oai-physim:{imageTag} default-route-openshift-image-registry.apps.oai.cs.eurecom.fr/{self.OCProjectName}/oai-physim:{imageTag}', '\$', 30)
 		time.sleep(2)
-		mySSH.command(f'sudo podman push default-route-openshift-image-registry.apps.5glab.nsa.eurecom.fr/{self.OCProjectName}/oai-physim:{imageTag} --tls-verify=false', '\$', 180)
+		mySSH.command(f'sudo podman push default-route-openshift-image-registry.apps.oai.cs.eurecom.fr/{self.OCProjectName}/oai-physim:{imageTag} --tls-verify=false', '\$', 180)
 		if mySSH.getBefore().count('Storing signatures') == 0:
 			logging.error('\u001B[1m Image "oai-physim" push to OC Cluster Registry Failed\u001B[0m')
+			mySSH.command('sudo podman logout https://default-route-openshift-image-registry.apps.oai.cs.eurecom.fr/', '\$', 6)
+			mySSH.command('oc logout', '\$', 30)
 			mySSH.close()
 			HTML.CreateHtmlTestRow('N/A', 'KO', CONST.OC_IS_FAIL)
 			RAN.prematureExit = True
@@ -195,8 +201,9 @@ class PhySim:
 
 		# Using helm charts deployment
 		time.sleep(5)
+		mySSH.command(f'grep -rl OAICICD_PROJECT ./charts/ | xargs sed -i -e "s#OAICICD_PROJECT#{ocProjectName}#"', '\$', 30)
 		mySSH.command(f'sed -i -e "s#TAG#{imageTag}#g" ./charts/physims/values.yaml', '\$', 6)
-		mySSH.command('helm install physim ./charts/physims/ | tee -a cmake_targets/log/physim_helm_summary.txt 2>&1', '\$', 30)
+		mySSH.command('helm install physim ./charts/physims/ 2>&1 | tee -a cmake_targets/log/physim_helm_summary.txt', '\$', 30)
 		if mySSH.getBefore().count('STATUS: deployed') == 0:
 			logging.error('\u001B[1m Deploying PhySim Failed using helm chart on OC Cluster\u001B[0m')
 			mySSH.command('helm uninstall physim >> cmake_targets/log/physim_helm_summary.txt 2>&1', '\$', 30)
@@ -206,8 +213,10 @@ class PhySim:
 				mySSH.command('oc get pods -l app.kubernetes.io/instance=physim', '\$', 6, resync=True)
 				if re.search('No resources found', mySSH.getBefore()):
 					isFinished1 = True
-			mySSH.command(f'sudo podman rmi default-route-openshift-image-registry.apps.5glab.nsa.eurecom.fr/{self.OCProjectName}/oai-physim:{imageTag}', '\$', 30)
+			mySSH.command(f'sudo podman rmi default-route-openshift-image-registry.apps.oai.cs.eurecom.fr/{self.OCProjectName}/oai-physim:{imageTag}', '\$', 30)
 			mySSH.command('oc delete is oai-physim', '\$', 30)
+			mySSH.command('sudo podman logout https://default-route-openshift-image-registry.apps.oai.cs.eurecom.fr/', '\$', 6)
+			mySSH.command('oc logout', '\$', 30)
 			mySSH.close()
 			self.AnalyzeLogFile_phySim(HTML)
 			RAN.prematureExit = True
@@ -227,7 +236,7 @@ class PhySim:
 		if isRunning == False:
 			logging.error('\u001B[1m Some PODS Running FAILED \u001B[0m')
 			mySSH.command('oc get pods -l app.kubernetes.io/instance=physim 2>&1 | tee -a cmake_targets/log/physim_pods_summary.txt', '\$', 6)
-			mySSH.command('helm uninstall physim >> cmake_targets/log/physim_helm_summary.txt 2>&1', '\$', 6)
+			mySSH.command('helm uninstall physim 2>&1 >> cmake_targets/log/physim_helm_summary.txt', '\$', 6)
 			self.AnalyzeLogFile_phySim(HTML)
 			isFinished1 = False
 			while(isFinished1 == False):
@@ -235,8 +244,10 @@ class PhySim:
 				mySSH.command('oc get pods -l app.kubernetes.io/instance=physim', '\$', 6, resync=True)
 				if re.search('No resources found', mySSH.getBefore()):
 					isFinished1 = True
-			mySSH.command(f'sudo podman rmi default-route-openshift-image-registry.apps.5glab.nsa.eurecom.fr/{self.OCProjectName}/oai-physim:{imageTag}', '\$', 6)
+			mySSH.command(f'sudo podman rmi default-route-openshift-image-registry.apps.oai.cs.eurecom.fr/{self.OCProjectName}/oai-physim:{imageTag}', '\$', 6)
 			mySSH.command('oc delete is oai-physim', '\$', 6)
+			mySSH.command('sudo podman logout https://default-route-openshift-image-registry.apps.oai.cs.eurecom.fr/', '\$', 6)
+			mySSH.command('oc logout', '\$', 30)
 			HTML.CreateHtmlTestRow('N/A', 'KO', CONST.OC_PHYSIM_DEPLOY_FAIL)
 			HTML.CreateHtmlTestRowPhySimTestResult(self.testSummary,self.testResult)
 			RAN.prematureExit = True
@@ -293,9 +304,10 @@ class PhySim:
 				isFinished1 = True
 		if isFinished1 == True:
 			logging.debug('\u001B[1m UnDeployed PhySim Successfully on OC Cluster\u001B[0m')
-		mySSH.command(f'sudo podman rmi default-route-openshift-image-registry.apps.5glab.nsa.eurecom.fr/{self.OCProjectName}/oai-physim:{imageTag}', '\$', 6)
+		mySSH.command(f'sudo podman rmi default-route-openshift-image-registry.apps.oai.cs.eurecom.fr/{self.OCProjectName}/oai-physim:{imageTag}', '\$', 6)
 		mySSH.command('oc delete is oai-physim', '\$', 6)
 		logging.debug('\u001B[1m Deleted the Image and ImageStream\u001B[0m')
+		mySSH.command('sudo podman logout https://default-route-openshift-image-registry.apps.oai.cs.eurecom.fr/', '\$', 6)
 		mySSH.command('oc logout', '\$', 6)
 		mySSH.close()
 		self.AnalyzeLogFile_phySim(HTML)
diff --git a/ci-scripts/conf_files/enb.band38.lte_2x2.100PRB.usrpn310.conf b/ci-scripts/conf_files/enb.band38.lte_2x2.100PRB.usrpn310.conf
index fe2e031acb6d0a000b68a973ba54c89867f85783..a7100a97e3314417eaf15e621ef92228b6c762be 100644
--- a/ci-scripts/conf_files/enb.band38.lte_2x2.100PRB.usrpn310.conf
+++ b/ci-scripts/conf_files/enb.band38.lte_2x2.100PRB.usrpn310.conf
@@ -237,7 +237,7 @@ RUs = (
          max_pdschReferenceSignalPower = -27;
          max_rxgain                    = 75;
          eNB_instances  = [0];
-         sdr_addrs      = "mgmt_addr=192.168.18.241,addr=192.168.20.2,second_addr=192.168.10.2";
+         sdr_addrs      = "mgmt_addr=172.21.19.13,addr=192.168.20.2,second_addr=192.168.10.2";
 
     }
 );  
diff --git a/ci-scripts/conf_files/enb.band38.lte_2x2_tm2.100PRB.usrpn310.conf b/ci-scripts/conf_files/enb.band38.lte_2x2_tm2.100PRB.usrpn310.conf
index a0742c57a69022c74ec2e244ea320ea0ff0f83d7..1f358c15715e68f8f60df52c57f4bea37353054b 100644
--- a/ci-scripts/conf_files/enb.band38.lte_2x2_tm2.100PRB.usrpn310.conf
+++ b/ci-scripts/conf_files/enb.band38.lte_2x2_tm2.100PRB.usrpn310.conf
@@ -237,7 +237,7 @@ RUs = (
          max_pdschReferenceSignalPower = -27;
          max_rxgain                    = 75;
          eNB_instances  = [0];
-         sdr_addrs      = "mgmt_addr=192.168.18.241,addr=192.168.20.2,second_addr=192.168.10.2";
+         sdr_addrs      = "mgmt_addr=172.21.19.13,addr=192.168.20.2,second_addr=192.168.10.2";
 
     }
 );  
diff --git a/ci-scripts/conf_files/enb.band38.nsa_2x2.100PRB.usrpn310.conf b/ci-scripts/conf_files/enb.band38.nsa_2x2.100PRB.usrpn310.conf
index 480ba3952a7dd90bafc5b8cd99ec2524131a59a0..f7088aee5249884474f2bd395ee807b651ee6647 100644
--- a/ci-scripts/conf_files/enb.band38.nsa_2x2.100PRB.usrpn310.conf
+++ b/ci-scripts/conf_files/enb.band38.nsa_2x2.100PRB.usrpn310.conf
@@ -231,13 +231,13 @@ RUs = (
        local_rf       = "yes"
          nb_tx          = 2
          nb_rx          = 2
-         att_tx         = 0
+         att_tx         = 10
          att_rx         = 5;
          bands          = [38];
          max_pdschReferenceSignalPower = -27;
          max_rxgain                    = 75;
          eNB_instances  = [0];
-         sdr_addrs      = "mgmt_addr=192.168.18.241,addr=192.168.20.2,second_addr=192.168.10.2";
+         sdr_addrs      = "mgmt_addr=172.21.19.13,addr=192.168.20.2,second_addr=192.168.10.2";
 
     }
 );  
diff --git a/ci-scripts/conf_files/episci/episci_gnb.band78.sa.fr1.106PRB.usrpn310.conf b/ci-scripts/conf_files/episci/episci_gnb.band78.sa.fr1.106PRB.usrpn310.conf
index a98179197f159bef82afb5fc3e91cfe7eebc11d3..51ffb1d5cd2bb59f7818b390564b51278ec21ab7 100644
--- a/ci-scripts/conf_files/episci/episci_gnb.band78.sa.fr1.106PRB.usrpn310.conf
+++ b/ci-scripts/conf_files/episci/episci_gnb.band78.sa.fr1.106PRB.usrpn310.conf
@@ -33,9 +33,6 @@ gNBs =
     ////////// Physical parameters:
 
     ssb_SubcarrierOffset                                      = 0;
-    pdsch_AntennaPorts                                        = 1;
-    pusch_AntennaPorts                                        = 1;
-    ul_prbblacklist                                           = "51,52,53,54"
     min_rxtxtime = 6;
      pdcch_ConfigSIB1 = (
       {
@@ -73,15 +70,6 @@ gNBs =
       #pdcch-ConfigCommon
         initialDLBWPcontrolResourceSetZero                              = 12;
         initialDLBWPsearchSpaceZero                                     = 0;
-      #pdsch-ConfigCommon
-        #pdschTimeDomainAllocationList (up to 16 entries)
-        initialDLBWPk0_0                    = 0;  #for DL slot
-        initialDLBWPmappingType_0           = 0;  #0=typeA,1=typeB
-        initialDLBWPstartSymbolAndLength_0  = 40; #this is SS=1,L=13
-
-        initialDLBWPk0_1                    = 0;  #for mixed slot
-        initialDLBWPmappingType_1           = 0;
-        initialDLBWPstartSymbolAndLength_1  = 57; #this is SS=1,L=5
 
   #uplinkConfigCommon
      #frequencyInfoUL
@@ -136,19 +124,6 @@ gNBs =
 # 0=unrestricted, 1=restricted type A, 2=restricted type B
         restrictedSetConfig                                         = 0,
 
-      # pusch-ConfigCommon (up to 16 elements)
-        initialULBWPk2_0                      = 6;  # used for UL slot
-        initialULBWPmappingType_0             = 1
-        initialULBWPstartSymbolAndLength_0    = 41; # this is SS=0 L=13
-
-        initialULBWPk2_1                      = 6;  # used for mixed slot
-        initialULBWPmappingType_1             = 1;
-        initialULBWPstartSymbolAndLength_1    = 52; # this is SS=10 L=4
-
-        initialULBWPk2_2                      = 7;  # used for Msg.3 during RA
-        initialULBWPmappingType_2             = 1;
-        initialULBWPstartSymbolAndLength_2    = 52; # this is SS=10 L=4
-
         msg3_DeltaPreamble                                          = 1;
         p0_NominalWithGrant                                         =-90;
 
@@ -264,7 +239,7 @@ RUs = (
          #beamforming 1x4 matrix:
          bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000];
          #clock_src = "external";
-         sdr_addrs = "mgmt_addr=192.168.18.240,addr=192.168.10.2,second_addr=192.168.20.2,clock_source=internal,time_source=internal"
+         sdr_addrs = "mgmt_addr=172.21.19.14,addr=192.168.10.2,second_addr=192.168.20.2,clock_source=internal,time_source=internal"
     }
 );
 
diff --git a/ci-scripts/conf_files/episci/episci_nr-ue0.nfapi.conf b/ci-scripts/conf_files/episci/episci_nr-ue0.nfapi.conf
deleted file mode 100644
index 22ffb4cd3d2317e93a1e050b905bf124bc767d39..0000000000000000000000000000000000000000
--- a/ci-scripts/conf_files/episci/episci_nr-ue0.nfapi.conf
+++ /dev/null
@@ -1,45 +0,0 @@
-log_config = {
-  global_log_level                      ="info";
-  hw_log_level                          ="info";
-  phy_log_level                         ="info";
-  mac_log_level                         ="info";
-  rlc_log_level                         ="info";
-  pdcp_log_level                        ="info";
-  rrc_log_level                         ="info";
-};
-
-uicc0 = {
-imsi = "208950000000031";
-key = "0c0a34601d4f07677303652c0462535b";
-opc= "63bfa50ee6523365ff14c1f45f88737d";
-dnn= "oai";
-nssai_sst=222;
-nssai_sd=123;
-}
-
-L1s = (
-        {
-	num_cc = 1;
-	tr_n_preference = "nfapi";
-	local_n_if_name  = "ens3";
-	remote_n_address = "127.0.0.1"; //Proxy IP
-	local_n_address  = "127.0.0.1";
-	local_n_portc    = 50600;
-	remote_n_portc   = 50601;
-	local_n_portd    = 50610;
-	remote_n_portd   = 50611;
-        }  
-);
-
-RUs = (
-    {
-       local_rf       = "yes"
-       nb_tx          = 1
-       nb_rx          = 1
-       att_tx         = 90
-       att_rx         = 0;
-       bands          = [7,38,42,43];
-       max_pdschReferenceSignalPower = -27;
-       max_rxgain                    = 125;
-    }
-);
diff --git a/ci-scripts/conf_files/episci/episci_nr-ue1.nfapi.conf b/ci-scripts/conf_files/episci/episci_nr-ue1.nfapi.conf
deleted file mode 100644
index 3d1c008f2361836fac94e8634a8fb096701ae7ce..0000000000000000000000000000000000000000
--- a/ci-scripts/conf_files/episci/episci_nr-ue1.nfapi.conf
+++ /dev/null
@@ -1,45 +0,0 @@
-log_config = {
-  global_log_level                      ="info";
-  hw_log_level                          ="info";
-  phy_log_level                         ="info";
-  mac_log_level                         ="info";
-  rlc_log_level                         ="info";
-  pdcp_log_level                        ="info";
-  rrc_log_level                         ="info";
-};
-
-uicc0 = {
-imsi = "208950000000032";
-key = "0c0a34601d4f07677303652c0462535b";
-opc= "63bfa50ee6523365ff14c1f45f88737d";
-dnn= "oai";
-nssai_sst=222;
-nssai_sd=123;
-}
-
-L1s = (
-        {
-	num_cc = 1;
-	tr_n_preference = "nfapi";
-	local_n_if_name  = "ens3";
-	remote_n_address = "127.0.0.1"; //Proxy IP
-	local_n_address  = "127.0.0.1";
-	local_n_portc    = 50600;
-	remote_n_portc   = 50601;
-	local_n_portd    = 50610;
-	remote_n_portd   = 50611;
-        }  
-);
-
-RUs = (
-    {
-       local_rf       = "yes"
-       nb_tx          = 1
-       nb_rx          = 1
-       att_tx         = 90
-       att_rx         = 0;
-       bands          = [7,38,42,43];
-       max_pdschReferenceSignalPower = -27;
-       max_rxgain                    = 125;
-    }
-);
diff --git a/ci-scripts/conf_files/episci/episci_nr-ue2.nfapi.conf b/ci-scripts/conf_files/episci/episci_nr-ue2.nfapi.conf
deleted file mode 100644
index 73c3292809f0a27ca4cb752b3db33dec7fd8aee4..0000000000000000000000000000000000000000
--- a/ci-scripts/conf_files/episci/episci_nr-ue2.nfapi.conf
+++ /dev/null
@@ -1,45 +0,0 @@
-log_config = {
-  global_log_level                      ="info";
-  hw_log_level                          ="info";
-  phy_log_level                         ="info";
-  mac_log_level                         ="info";
-  rlc_log_level                         ="info";
-  pdcp_log_level                        ="info";
-  rrc_log_level                         ="info";
-};
-
-uicc0 = {
-imsi = "208950000000033";
-key = "0c0a34601d4f07677303652c0462535b";
-opc= "63bfa50ee6523365ff14c1f45f88737d";
-dnn= "oai";
-nssai_sst=222;
-nssai_sd=123;
-}
-
-L1s = (
-        {
-	num_cc = 1;
-	tr_n_preference = "nfapi";
-	local_n_if_name  = "ens3";
-	remote_n_address = "127.0.0.1"; //Proxy IP
-	local_n_address  = "127.0.0.1";
-	local_n_portc    = 50600;
-	remote_n_portc   = 50601;
-	local_n_portd    = 50610;
-	remote_n_portd   = 50611;
-        }  
-);
-
-RUs = (
-    {
-       local_rf       = "yes"
-       nb_tx          = 1
-       nb_rx          = 1
-       att_tx         = 90
-       att_rx         = 0;
-       bands          = [7,38,42,43];
-       max_pdschReferenceSignalPower = -27;
-       max_rxgain                    = 125;
-    }
-);
diff --git a/ci-scripts/conf_files/episci/episci_nr-ue3.nfapi.conf b/ci-scripts/conf_files/episci/episci_nr-ue3.nfapi.conf
deleted file mode 100644
index 1f8f7306c60eeea212660b5ab9d587694aee34c9..0000000000000000000000000000000000000000
--- a/ci-scripts/conf_files/episci/episci_nr-ue3.nfapi.conf
+++ /dev/null
@@ -1,45 +0,0 @@
-log_config = {
-  global_log_level                      ="info";
-  hw_log_level                          ="info";
-  phy_log_level                         ="info";
-  mac_log_level                         ="info";
-  rlc_log_level                         ="info";
-  pdcp_log_level                        ="info";
-  rrc_log_level                         ="info";
-};
-
-uicc0 = {
-imsi = "208950000000034";
-key = "0c0a34601d4f07677303652c0462535b";
-opc= "63bfa50ee6523365ff14c1f45f88737d";
-dnn= "oai";
-nssai_sst=222;
-nssai_sd=123;
-}
-
-L1s = (
-        {
-	num_cc = 1;
-	tr_n_preference = "nfapi";
-	local_n_if_name  = "ens3";
-	remote_n_address = "127.0.0.1"; //Proxy IP
-	local_n_address  = "127.0.0.1";
-	local_n_portc    = 50600;
-	remote_n_portc   = 50601;
-	local_n_portd    = 50610;
-	remote_n_portd   = 50611;
-        }  
-);
-
-RUs = (
-    {
-       local_rf       = "yes"
-       nb_tx          = 1
-       nb_rx          = 1
-       att_tx         = 90
-       att_rx         = 0;
-       bands          = [7,38,42,43];
-       max_pdschReferenceSignalPower = -27;
-       max_rxgain                    = 125;
-    }
-);
diff --git a/ci-scripts/conf_files/episci/episci_rcc.band78.tm1.106PRB.nfapi.conf b/ci-scripts/conf_files/episci/episci_rcc.band78.tm1.106PRB.nfapi.conf
index 9b3f205a0f36b69f3ddc66f8bf71236ca96f1a0f..eac0b746336cdd9901d1ae5a73e862843c05048b 100644
--- a/ci-scripts/conf_files/episci/episci_rcc.band78.tm1.106PRB.nfapi.conf
+++ b/ci-scripts/conf_files/episci/episci_rcc.band78.tm1.106PRB.nfapi.conf
@@ -22,9 +22,14 @@ gNBs =
     ////////// Physical parameters:
 
     ssb_SubcarrierOffset                                      = 31; //0;
-    pdsch_AntennaPorts                                        = 1;
-    pusch_AntennaPorts                                        = 1;
- 
+    min_rxtxtime = 6;
+
+     pdcch_ConfigSIB1 = (
+      {
+        controlResourceSetZero = 12;
+        searchSpaceZero = 0;
+      }
+      );
     servingCellConfigCommon = (
     {
  #spCellConfigCommon
@@ -54,15 +59,6 @@ gNBs =
       #pdcch-ConfigCommon
         initialDLBWPcontrolResourceSetZero                                      = 0;
         initialDLBWPsearchSpaceZero                                             = 0;
-      #pdsch-ConfigCommon
-        #pdschTimeDomainAllocationList (up to 16 entries)
-        initialDLBWPk0_0                    = 0;  #for DL slot
-        initialDLBWPmappingType_0           = 0;  #0=typeA,1=typeB
-        initialDLBWPstartSymbolAndLength_0  = 40; #this is SS=1,L=13
-
-        initialDLBWPk0_1                    = 0;  #for mixed slot
-        initialDLBWPmappingType_1           = 0;
-        initialDLBWPstartSymbolAndLength_1  = 57; #this is SS=1,L=5
 
   #uplinkConfigCommon 
      #frequencyInfoUL
@@ -117,18 +113,6 @@ gNBs =
 # restrictedSetConfig
 # 0=unrestricted, 1=restricted type A, 2=restricted type B
         restrictedSetConfig                                         = 0,
-      # pusch-ConfigCommon (up to 16 elements)
-        initialULBWPk2_0                      = 6;  # used for UL slot
-        initialULBWPmappingType_0             = 1
-        initialULBWPstartSymbolAndLength_0    = 41; # this is SS=0 L=13
-
-        initialULBWPk2_1                      = 6;  # used for mixed slot
-        initialULBWPmappingType_1             = 1;
-        initialULBWPstartSymbolAndLength_1    = 52; # this is SS=10 L=4
-
-        initialULBWPk2_2                      = 7;  # used for Msg.3 during RA
-        initialULBWPmappingType_2             = 1;
-        initialULBWPstartSymbolAndLength_2    = 52; # this is SS=10 L=4
 
         msg3_DeltaPreamble                                          = 1;
         p0_NominalWithGrant                                         =-90;
diff --git a/ci-scripts/conf_files/episci/proxy_gnb.band78.sa.fr1.106PRB.usrpn310.conf b/ci-scripts/conf_files/episci/proxy_gnb.band78.sa.fr1.106PRB.usrpn310.conf
index 0597e962455666686da6f69dd2331cd5714dac62..f80ce3751a93ed88e88c9fe95f1083c02052a454 100644
--- a/ci-scripts/conf_files/episci/proxy_gnb.band78.sa.fr1.106PRB.usrpn310.conf
+++ b/ci-scripts/conf_files/episci/proxy_gnb.band78.sa.fr1.106PRB.usrpn310.conf
@@ -33,9 +33,6 @@ gNBs =
     ////////// Physical parameters:
 
     ssb_SubcarrierOffset                                      = 0;
-    pdsch_AntennaPorts                                        = 1;
-    pusch_AntennaPorts                                        = 1;
-    ul_prbblacklist                                           = "51,52,53,54"
     min_rxtxtime = 6;
 
      pdcch_ConfigSIB1 = (
@@ -74,15 +71,6 @@ gNBs =
       #pdcch-ConfigCommon
         initialDLBWPcontrolResourceSetZero                              = 12;
         initialDLBWPsearchSpaceZero                                     = 0;
-      #pdsch-ConfigCommon
-        #pdschTimeDomainAllocationList (up to 16 entries)
-        initialDLBWPk0_0                    = 0;  #for DL slot
-        initialDLBWPmappingType_0           = 0;  #0=typeA,1=typeB
-        initialDLBWPstartSymbolAndLength_0  = 40; #this is SS=1,L=13
-
-        initialDLBWPk0_1                    = 0;  #for mixed slot
-        initialDLBWPmappingType_1           = 0;
-        initialDLBWPstartSymbolAndLength_1  = 57; #this is SS=1,L=5
 
   #uplinkConfigCommon
      #frequencyInfoUL
@@ -137,19 +125,6 @@ gNBs =
 # 0=unrestricted, 1=restricted type A, 2=restricted type B
         restrictedSetConfig                                         = 0,
 
-      # pusch-ConfigCommon (up to 16 elements)
-        initialULBWPk2_0                      = 6;  # used for UL slot
-        initialULBWPmappingType_0             = 1
-        initialULBWPstartSymbolAndLength_0    = 41; # this is SS=0 L=13
-
-        initialULBWPk2_1                      = 6;  # used for mixed slot
-        initialULBWPmappingType_1             = 1;
-        initialULBWPstartSymbolAndLength_1    = 52; # this is SS=10 L=4
-
-        initialULBWPk2_2                      = 7;  # used for Msg.3 during RA
-        initialULBWPmappingType_2             = 1;
-        initialULBWPstartSymbolAndLength_2    = 52; # this is SS=10 L=4
-
         msg3_DeltaPreamble                                          = 1;
         p0_NominalWithGrant                                         =-90;
 
@@ -265,7 +240,7 @@ RUs = (
          #beamforming 1x4 matrix:
          bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000];
          #clock_src = "external";
-         sdr_addrs = "mgmt_addr=192.168.18.240,addr=192.168.10.2,second_addr=192.168.20.2,clock_source=internal,time_source=internal"
+         sdr_addrs = "mgmt_addr=172.21.19.14,addr=192.168.10.2,second_addr=192.168.20.2,clock_source=internal,time_source=internal"
     }
 );
 
diff --git a/ci-scripts/conf_files/episci/proxy_rcc.band78.tm1.106PRB.nfapi.conf b/ci-scripts/conf_files/episci/proxy_rcc.band78.tm1.106PRB.nfapi.conf
index 341010419928648bea390634dfac1c81006724c0..f61039ff17349fe8b7abca2109e6d491f1ab2e85 100644
--- a/ci-scripts/conf_files/episci/proxy_rcc.band78.tm1.106PRB.nfapi.conf
+++ b/ci-scripts/conf_files/episci/proxy_rcc.band78.tm1.106PRB.nfapi.conf
@@ -22,7 +22,7 @@ gNBs =
     ////////// Physical parameters:
 
     ssb_SubcarrierOffset                                      = 0;
-    pdsch_AntennaPorts                                        = 1;
+    min_rxtxtime = 6;
 	
     servingCellConfigCommon = (
     {
@@ -53,29 +53,6 @@ gNBs =
       #pdcch-ConfigCommon
         initialDLBWPcontrolResourceSetZero                                      = 12;
         initialDLBWPsearchSpaceZero                                             = 0;
-      #pdsch-ConfigCommon
-        #pdschTimeDomainAllocationList (up to 16 entries)
-             initialDLBWPk0_0                    = 0;
-             #initialULBWPmappingType
-	     #0=typeA,1=typeB
-             initialDLBWPmappingType_0           = 0;
-             #this is SS=1,L=13
-             initialDLBWPstartSymbolAndLength_0  = 40;
-
-             initialDLBWPk0_1                    = 0;
-             initialDLBWPmappingType_1           = 0;
-             #this is SS=2,L=12 
-             initialDLBWPstartSymbolAndLength_1  = 53;
-
-             initialDLBWPk0_2                    = 0;
-             initialDLBWPmappingType_2           = 0;
-             #this is SS=1,L=12 
-             initialDLBWPstartSymbolAndLength_2  = 54;
-
-             initialDLBWPk0_3                    = 0;
-             initialDLBWPmappingType_3           = 0;
-             #this is SS=1,L=5
-             initialDLBWPstartSymbolAndLength_3  = 57;
 
   #uplinkConfigCommon 
      #frequencyInfoUL
@@ -130,22 +107,6 @@ gNBs =
 # 0=unrestricted, 1=restricted type A, 2=restricted type B
         restrictedSetConfig                                         = 0,
 
-      # pusch-ConfigCommon (up to 16 elements)
-        initialULBWPk2_0                      = 6;
-        initialULBWPmappingType_0             = 1
-        # this is SS=0 L=11
-        initialULBWPstartSymbolAndLength_0    = 55;
-
-        initialULBWPk2_1                      = 6;
-        initialULBWPmappingType_1             = 1;
-        # this is SS=0 L=12
-        initialULBWPstartSymbolAndLength_1    = 69;
-
-        initialULBWPk2_2                      = 7;
-        initialULBWPmappingType_2             = 1;
-        # this is SS=10 L=4
-        initialULBWPstartSymbolAndLength_2    = 52;
-
         msg3_DeltaPreamble                                          = 1;
         p0_NominalWithGrant                                         =-90;
 
diff --git a/ci-scripts/conf_files/gNB_SA_CU.conf b/ci-scripts/conf_files/gNB_SA_CU.conf
index 39c9a43ad44a86f92f9c78f8edc5d45b6fbed730..9d64ae1976f9ab49720ba9aa338f97af2c69404a 100644
--- a/ci-scripts/conf_files/gNB_SA_CU.conf
+++ b/ci-scripts/conf_files/gNB_SA_CU.conf
@@ -45,10 +45,7 @@ gNBs =
     remote_s_portc  = 500;
     remote_s_portd  = 2152;
     ssb_SubcarrierOffset                                      = 0;
-    pdsch_AntennaPorts                                        = 1;
-    pusch_AntennaPorts                                        = 1;
     min_rxtxtime                                              = 6;
-    sib1_tda                                                  = 0;
 
      pdcch_ConfigSIB1 = (
       {
diff --git a/ci-scripts/conf_files/gNB_SA_DU.conf b/ci-scripts/conf_files/gNB_SA_DU.conf
index 256d724f3ff9898e942244b2cdc8443de355e515..f95bdf91aee97e2c4c02f8b89db251622bacaf0c 100644
--- a/ci-scripts/conf_files/gNB_SA_DU.conf
+++ b/ci-scripts/conf_files/gNB_SA_DU.conf
@@ -38,7 +38,6 @@ gNBs =
 
     ssb_SubcarrierOffset                                      = 0;
     min_rxtxtime                                              = 6;
-    sib1_tda                                                  = 0;
 
     pdcch_ConfigSIB1 = (
       {
diff --git a/ci-scripts/conf_files/gNB_SA_n78_106PRB.2x2_usrpn310.conf b/ci-scripts/conf_files/gNB_SA_n78_106PRB.2x2_usrpn310.conf
index cd10783a06a76641cdc0c9f08d105b6bc365f5aa..04dc1b1373fbf7c843328f71d6d5efa928cb758a 100644
--- a/ci-scripts/conf_files/gNB_SA_n78_106PRB.2x2_usrpn310.conf
+++ b/ci-scripts/conf_files/gNB_SA_n78_106PRB.2x2_usrpn310.conf
@@ -209,9 +209,9 @@ gNBs =
         {
 
            GNB_INTERFACE_NAME_FOR_NG_AMF            = "em1";
-           GNB_IPV4_ADDRESS_FOR_NG_AMF              = "192.168.18.194/24";
+           GNB_IPV4_ADDRESS_FOR_NG_AMF              = "172.21.16.127/24";
            GNB_INTERFACE_NAME_FOR_NGU               = "em1";
-           GNB_IPV4_ADDRESS_FOR_NGU                 = "192.168.18.194/24";
+           GNB_IPV4_ADDRESS_FOR_NGU                 = "172.21.16.127/24";
            GNB_PORT_FOR_S1U                         = 2152; # Spec 2152
         };
 
@@ -258,7 +258,7 @@ RUs = (
          ## beamforming 4x4 matrix:
          #bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000, 0x00000000, 0x00007fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x00007fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x00007fff];
 
-         sdr_addrs = "mgmt_addr=192.168.18.252,addr=192.168.10.2,second_addr=192.168.20.2,clock_source=internal,time_source=internal"
+         sdr_addrs = "mgmt_addr=172.21.19.14,addr=192.168.10.2,second_addr=192.168.20.2,clock_source=internal,time_source=internal"
     }
 );  
 
diff --git a/ci-scripts/conf_files/gNB_SA_n78_133PRB.2x2_usrpn310.conf b/ci-scripts/conf_files/gNB_SA_n78_133PRB.2x2_usrpn310.conf
index 6c6045909286d350d0cb5b771fd0f90ea19d3ca2..fd52c7fed5471b486f2d8d36aaea3b6332200eb6 100644
--- a/ci-scripts/conf_files/gNB_SA_n78_133PRB.2x2_usrpn310.conf
+++ b/ci-scripts/conf_files/gNB_SA_n78_133PRB.2x2_usrpn310.conf
@@ -206,9 +206,9 @@ gNBs =
         {
 
            GNB_INTERFACE_NAME_FOR_NG_AMF            = "em1";
-           GNB_IPV4_ADDRESS_FOR_NG_AMF              = "192.168.18.194/24";
+           GNB_IPV4_ADDRESS_FOR_NG_AMF              = "172.21.16.127/24";
            GNB_INTERFACE_NAME_FOR_NGU               = "em1";
-           GNB_IPV4_ADDRESS_FOR_NGU                 = "192.168.18.194/24";
+           GNB_IPV4_ADDRESS_FOR_NGU                 = "172.21.16.127/24";
            GNB_PORT_FOR_S1U                         = 2152; # Spec 2152
         };
 
@@ -254,7 +254,7 @@ RUs = (
          ## beamforming 4x4 matrix:
          #bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000, 0x00000000, 0x00007fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x00007fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x00007fff];
 
-         sdr_addrs = "mgmt_addr=192.168.18.252,addr=192.168.10.2,second_addr=192.168.20.2,clock_source=internal,time_source=internal"
+         sdr_addrs = "mgmt_addr=172.21.19.14,addr=192.168.10.2,second_addr=192.168.20.2,clock_source=internal,time_source=internal"
     }
 );  
 
diff --git a/ci-scripts/conf_files/gnb.band78.nsa_2x2.106PRB.usrpn310.conf b/ci-scripts/conf_files/gnb.band78.nsa_2x2.106PRB.usrpn310.conf
index 223a0275c4e46a87614f69bc954c66be7e894862..03155b85d8371f2e3e15ce8ae494e247097d1dbc 100644
--- a/ci-scripts/conf_files/gnb.band78.nsa_2x2.106PRB.usrpn310.conf
+++ b/ci-scripts/conf_files/gnb.band78.nsa_2x2.106PRB.usrpn310.conf
@@ -199,12 +199,12 @@ gNBs =
 );
 
 MACRLCs = (
-	{
-	num_cc = 1;
-	tr_s_preference = "local_L1";
-	tr_n_preference = "local_RRC";
-	ulsch_max_frame_inactivity = 1;
-        }  
+{
+  num_cc                     = 1;
+  tr_s_preference            = "local_L1";
+  tr_n_preference            = "local_RRC";
+  ulsch_max_frame_inactivity = 0;
+}
 );
 
 L1s = (
@@ -213,6 +213,7 @@ L1s = (
   tr_n_preference = "local_mac";
   thread_pool_size = 8;
   prach_dtx_threshold = 120;
+  pucch0_dtx_threshold = 80;
 }
 );
 
@@ -230,7 +231,7 @@ RUs = (
          bf_weights = [0x00007fff, 0x00007fff];
          #clock_src = "external";
          sf_extension = 0 
-         sdr_addrs = "mgmt_addr=192.168.18.252,addr=192.168.10.2,second_addr=192.168.20.2,clock_source=internal,time_source=internal"
+         sdr_addrs = "mgmt_addr=172.21.19.14,addr=192.168.10.2,second_addr=192.168.20.2,clock_source=internal,time_source=internal"
     }
 );  
 
diff --git a/ci-scripts/conf_files/gnb.band78.sa.fr1.106PRB.2x2.usrpn310.asue.conf b/ci-scripts/conf_files/gnb.band78.sa.fr1.106PRB.2x2.usrpn310.asue.conf
new file mode 100644
index 0000000000000000000000000000000000000000..5e6b3fb217b52c512dc8e17e6ca6fb1acb81ec2f
--- /dev/null
+++ b/ci-scripts/conf_files/gnb.band78.sa.fr1.106PRB.2x2.usrpn310.asue.conf
@@ -0,0 +1,307 @@
+Active_gNBs = ( "gNB-OAI");
+# Asn1_verbosity, choice in: none, info, annoying
+Asn1_verbosity = "none";
+
+gNBs =
+(
+ {
+    ////////// Identification parameters:
+    gNB_CU_ID = 0xe00;
+
+#     cell_type =  "CELL_MACRO_GNB";
+
+    gNB_name  =  "gNB-OAI";
+
+    // Tracking area code, 0x0000 and 0xfffe are reserved values
+    tracking_area_code  =  1;
+
+    plmn_list = ({
+                  mcc = 208;
+                  mnc = 97;
+                  mnc_length = 2;
+                  snssaiList = (
+                                {
+                                  sst = 1;
+                                  sd  = 0x1; // 0 false, else true
+                                },
+                                {
+                                  sst = 1;
+                                  sd  = 0x010203; // 0 false, else true
+                                },
+                                                                                                                                                                   {
+                                  sst = 1;
+                                  sd  = 0x112233; // 0 false, else true
+                                }
+                               );
+                 });
+
+    nr_cellid = 12345678L
+
+#     tr_s_preference     = "local_mac"
+
+    ////////// Physical parameters:
+
+    ssb_SubcarrierOffset                                      = 0;
+    pusch_AntennaPorts                                        = 2;
+    ul_prbblacklist                                           = "51,52,53,54"
+    do_SRS                                                    = 1;
+
+    pdcch_ConfigSIB1 = (
+      {
+        controlResourceSetZero = 11;
+        searchSpaceZero = 0;
+      }
+    );
+
+    servingCellConfigCommon = (
+    {
+ #spCellConfigCommon
+
+      physCellId                                                    = 0;
+
+#  downlinkConfigCommon
+    #frequencyInfoDL
+      # this is 3301.68 MHz + 22*12*30e-3 MHz = 3309.6
+      #absoluteFrequencySSB                                          = 620640;
+      # this is 3300.60 MHz + 53*12*30e-3 MHz = 3319.68
+      absoluteFrequencySSB                                          = 621312;
+      # this is 3503.28 MHz + 22*12*30e-3 MHz = 3511.2
+      #absoluteFrequencySSB                                          = 634080;
+      # this is 3600.48 MHz
+      #absoluteFrequencySSB                                          = 640032;
+      #dl_frequencyBand                                                 = 78;
+      # this is 3301.68 MHz
+      #dl_absoluteFrequencyPointA                                       = 620112;
+      # this is 3300.60 MHz
+      dl_absoluteFrequencyPointA                                       = 620040;
+      # this is 3502.56 MHz
+      #dl_absoluteFrequencyPointA                                       = 633552;
+      # this is 3600.48 MHz
+      #dl_absoluteFrequencyPointA                                       = 640032;
+      #scs-SpecificCarrierList
+        dl_offstToCarrier                                              = 0;
+# subcarrierSpacing
+# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
+        dl_subcarrierSpacing                                           = 1;
+        dl_carrierBandwidth                                            = 106;
+     #initialDownlinkBWP
+      #genericParameters
+        # this is RBstart=0,L=106 (275*(L-1))+RBstart
+        initialDLBWPlocationAndBandwidth                                        = 28875;
+# subcarrierSpacing
+# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
+        initialDLBWPsubcarrierSpacing                                           = 1;
+      #pdcch-ConfigCommon
+        initialDLBWPcontrolResourceSetZero                                      = 11;
+        initialDLBWPsearchSpaceZero                                             = 0;
+
+  #uplinkConfigCommon
+     #frequencyInfoUL
+      ul_frequencyBand                                                 = 78;
+      #scs-SpecificCarrierList
+      ul_offstToCarrier                                              = 0;
+# subcarrierSpacing
+# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
+      ul_subcarrierSpacing                                           = 1;
+      ul_carrierBandwidth                                            = 106;
+      pMax                                                          = 20;
+     #initialUplinkBWP
+      #genericParameters
+        initialULBWPlocationAndBandwidth                                        = 28875;
+# subcarrierSpacing
+# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
+        initialULBWPsubcarrierSpacing                                           = 1;
+      #rach-ConfigCommon
+        #rach-ConfigGeneric
+          prach_ConfigurationIndex                                  = 98;
+#prach_msg1_FDM
+#0 = one, 1=two, 2=four, 3=eight
+          prach_msg1_FDM                                            = 0;
+          prach_msg1_FrequencyStart                                 = 0;
+          zeroCorrelationZoneConfig                                 = 12;
+          preambleReceivedTargetPower                               = -104;
+#preamblTransMax (0...10) = (3,4,5,6,7,8,10,20,50,100,200)
+          preambleTransMax                                          = 6;
+#powerRampingStep
+# 0=dB0,1=dB2,2=dB4,3=dB6
+        powerRampingStep                                            = 1;
+#ra_ReponseWindow
+#1,2,4,8,10,20,40,80
+        ra_ResponseWindow                                           = 4;
+#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR
+#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen
+        ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR                = 3;
+#oneHalf (0..15) 4,8,12,16,...60,64
+        ssb_perRACH_OccasionAndCB_PreamblesPerSSB                   = 15;
+#ra_ContentionResolutionTimer
+#(0..7) 8,16,24,32,40,48,56,64
+        ra_ContentionResolutionTimer                                = 7;
+        rsrp_ThresholdSSB                                           = 19;
+#prach-RootSequenceIndex_PR
+#1 = 839, 2 = 139
+        prach_RootSequenceIndex_PR                                  = 2;
+        prach_RootSequenceIndex                                     = 1;
+        # SCS for msg1, can only be 15 for 30 kHz < 6 GHz, takes precendence over the one derived from prach-ConfigIndex
+        #
+        msg1_SubcarrierSpacing                                      = 1,
+# restrictedSetConfig
+# 0=unrestricted, 1=restricted type A, 2=restricted type B
+        restrictedSetConfig                                         = 0,
+
+        msg3_DeltaPreamble                                          = 1;
+        p0_NominalWithGrant                                         =-90;
+
+# pucch-ConfigCommon setup :
+# pucchGroupHopping
+# 0 = neither, 1= group hopping, 2=sequence hopping
+        pucchGroupHopping                                           = 0;
+        hoppingId                                                   = 40;
+        p0_nominal                                                  = -90;
+# ssb_PositionsInBurs_BitmapPR
+# 1=short, 2=medium, 3=long
+      ssb_PositionsInBurst_PR                                       = 2;
+      ssb_PositionsInBurst_Bitmap                                   = 1;
+
+# ssb_periodicityServingCell
+# 0 = ms5, 1=ms10, 2=ms20, 3=ms40, 4=ms80, 5=ms160, 6=spare2, 7=spare1
+      ssb_periodicityServingCell                                    = 2;
+
+# dmrs_TypeA_position
+# 0 = pos2, 1 = pos3
+      dmrs_TypeA_Position                                           = 0;
+
+# subcarrierSpacing
+# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
+      subcarrierSpacing                                             = 1;
+
+
+  #tdd-UL-DL-ConfigurationCommon
+# subcarrierSpacing
+# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
+      referenceSubcarrierSpacing                                    = 1;
+      # pattern1
+      # dl_UL_TransmissionPeriodicity
+      # 0=ms0p5, 1=ms0p625, 2=ms1, 3=ms1p25, 4=ms2, 5=ms2p5, 6=ms5, 7=ms10
+      dl_UL_TransmissionPeriodicity                                 = 6;
+      nrofDownlinkSlots                                             = 7;
+      nrofDownlinkSymbols                                           = 6;
+      nrofUplinkSlots                                               = 2;
+      nrofUplinkSymbols                                             = 4;
+
+  ssPBCH_BlockPower                                             = -25;
+  }
+
+  );
+
+
+    # ------- SCTP definitions
+    SCTP :
+    {
+        # Number of streams to use in input/output
+        SCTP_INSTREAMS  = 2;
+        SCTP_OUTSTREAMS = 2;
+    };
+
+    ////////// AMF parameters:
+        amf_ip_address      = ( { ipv4       = "CI_MME_IP_ADDR";
+                                  ipv6       = "192:168:30::17";
+                                  active     = "yes";
+                                  preference = "ipv4";
+                                                                                                                              }
+                                                                                                                                          );
+
+        NETWORK_INTERFACES :
+        {
+
+           GNB_INTERFACE_NAME_FOR_NG_AMF            = "em1";
+           GNB_IPV4_ADDRESS_FOR_NG_AMF              = "CI_GNB_IP_ADDR";
+           GNB_INTERFACE_NAME_FOR_NGU               = "em1";
+           GNB_IPV4_ADDRESS_FOR_NGU                 = "CI_GNB_IP_ADDR";
+           GNB_PORT_FOR_S1U                         = 2152; # Spec 2152
+        };
+
+  }
+);
+
+MACRLCs = (
+  {
+    num_cc           = 1;
+    tr_s_preference  = "local_L1";
+    tr_n_preference  = "local_RRC";
+#    pusch_TargetSNRx10 = 200;
+#    pucch_TargetSNRx10 = 150;
+     ulsch_max_frame_inactivity = 0;
+  }
+);
+
+L1s = (
+{
+  num_cc = 1;
+  tr_n_preference = "local_mac";
+  thread_pool_size = 8;
+  prach_dtx_threshold = 120;
+#  pucch0_dtx_threshold = 150;
+}
+);
+
+RUs = (
+    {
+       local_rf       = "yes"
+         nb_tx          = 2
+         nb_rx          = 2
+         att_tx         = 0
+         att_rx         = 0;
+         bands          = [78];
+         max_pdschReferenceSignalPower = -27;
+         max_rxgain                    = 75;
+         eNB_instances  = [0];
+         ##beamforming 1x2 matrix: 1 layer x 2 antennas
+         bf_weights = [0x00007fff, 0x0000];
+         ##beamforming 1x4 matrix: 1 layer x 4 antennas
+         #bf_weights = [0x00007fff, 0x0000,0x0000, 0x0000];
+         ## beamforming 2x2 matrix:
+         # bf_weights = [0x00007fff, 0x00000000, 0x00000000, 0x00007fff];
+         ## beamforming 4x4 matrix:
+         #bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000, 0x00000000, 0x00007fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x00007fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x00007fff];
+         sf_extension = 0
+         sdr_addrs = "mgmt_addr=172.21.19.14,addr=192.168.10.2,second_addr=192.168.20.2,clock_source=internal,time_source=internal"
+    }
+);
+
+THREAD_STRUCT = (
+  {
+    #three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT"
+    parallel_config    = "PARALLEL_SINGLE_THREAD";
+    #two option for worker "WORKER_DISABLE" or "WORKER_ENABLE"
+    worker_config      = "WORKER_ENABLE";
+  }
+);
+
+#security = {
+  # preferred ciphering algorithms
+  # the first one of the list that an UE supports in chosen
+  # valid values: nea0, nea1, nea2, nea3
+#  ciphering_algorithms = ( "nea2" );
+
+  # preferred integrity algorithms
+  # the first one of the list that an UE supports in chosen
+  # valid values: nia0, nia1, nia2, nia3
+#  integrity_algorithms = ( "nia2", "nia0" );
+
+  # setting 'drb_ciphering' to "no" disables ciphering for DRBs, no matter
+  # what 'ciphering_algorithms' configures; same thing for 'drb_integrity'
+#  drb_ciphering = "yes";
+#  drb_integrity = "no";
+#};
+
+     log_config :
+     {
+       global_log_level                      ="info";
+       hw_log_level                          ="info";
+       phy_log_level                         ="info";
+       mac_log_level                         ="info";
+       rlc_log_level                         ="info";
+       pdcp_log_level                        ="info";
+       rrc_log_level                         ="info";
+       f1ap_log_level                         ="debug";
+    };
diff --git a/ci-scripts/conf_files/gnb.band78.sa.fr1.106PRB.2x2.usrpn310.conf b/ci-scripts/conf_files/gnb.band78.sa.fr1.106PRB.2x2.usrpn310.conf
index 178e99d56598d56f72f5ce8d15afcdf38c2880c5..09d9b503353d30ac51bdc951e5080889e2e6c038 100644
--- a/ci-scripts/conf_files/gnb.band78.sa.fr1.106PRB.2x2.usrpn310.conf
+++ b/ci-scripts/conf_files/gnb.band78.sa.fr1.106PRB.2x2.usrpn310.conf
@@ -261,7 +261,7 @@ RUs = (
          ## beamforming 4x4 matrix:
          #bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000, 0x00000000, 0x00007fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x00007fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x00007fff];
          sf_extension = 0
-         sdr_addrs = "mgmt_addr=192.168.18.252,addr=192.168.10.2,second_addr=192.168.20.2,clock_source=internal,time_source=internal"
+         sdr_addrs = "mgmt_addr=172.21.19.14,addr=192.168.10.2,second_addr=192.168.20.2,clock_source=internal,time_source=internal"
     }
 );
 
diff --git a/ci-scripts/conf_files/gnb.band78.sa.fr1.106PRB.usrpn310.conf b/ci-scripts/conf_files/gnb.band78.sa.fr1.106PRB.usrpn310.conf
index e2b331939b99082d2b90d2f7cb1b98688cf3061d..9e1f499f0342d00c41a66786e6a2e3763f689c28 100644
--- a/ci-scripts/conf_files/gnb.band78.sa.fr1.106PRB.usrpn310.conf
+++ b/ci-scripts/conf_files/gnb.band78.sa.fr1.106PRB.usrpn310.conf
@@ -263,7 +263,7 @@ RUs = (
          ## beamforming 4x4 matrix:
          #bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000, 0x00000000, 0x00007fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x00007fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x00007fff];
          sf_extension = 0
-         sdr_addrs = "mgmt_addr=192.168.18.252,addr=192.168.10.2,second_addr=192.168.20.2,clock_source=internal,time_source=internal"
+         sdr_addrs = "mgmt_addr=172.21.19.14,addr=192.168.10.2,second_addr=192.168.20.2,clock_source=internal,time_source=internal"
     }
 );
 
diff --git a/ci-scripts/conf_files/gnb.band78.sa.fr1.162PRB.2x2.usrpn310.conf b/ci-scripts/conf_files/gnb.band78.sa.fr1.162PRB.2x2.usrpn310.conf
index 33c93124ca6df5d7804772cdc0253107f17865d6..42fc89b2eda29798754f49d84dc4cc1f50d80226 100644
--- a/ci-scripts/conf_files/gnb.band78.sa.fr1.162PRB.2x2.usrpn310.conf
+++ b/ci-scripts/conf_files/gnb.band78.sa.fr1.162PRB.2x2.usrpn310.conf
@@ -262,7 +262,7 @@ RUs = (
          ## beamforming 4x4 matrix:
          #bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000, 0x00000000, 0x00007fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x00007fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x00007fff];
          sf_extension = 0
-         sdr_addrs = "mgmt_addr=192.168.18.252,addr=192.168.10.2,second_addr=192.168.20.2,clock_source=internal,time_source=internal"
+         sdr_addrs = "mgmt_addr=172.21.19.14,addr=192.168.10.2,second_addr=192.168.20.2,clock_source=internal,time_source=internal"
     }
 );
 
diff --git a/ci-scripts/conf_files/gnb.band78.tm1.fr1.106PRB.usrpb210.conf b/ci-scripts/conf_files/gnb.band78.tm1.fr1.106PRB.usrpb210.conf
index af581453229280fbb425992a4e5023c408f1f5b3..f3515d388248d851fe8bbcffbf2bec39883e42ce 100644
--- a/ci-scripts/conf_files/gnb.band78.tm1.fr1.106PRB.usrpb210.conf
+++ b/ci-scripts/conf_files/gnb.band78.tm1.fr1.106PRB.usrpb210.conf
@@ -203,7 +203,7 @@ MACRLCs = (
     tr_n_preference     = "local_RRC";
     pusch_TargetSNRx10  = 200;
     pucch_TargetSNRx10  = 200;
-    ulsch_max_frame_inactivity = 1;
+    ulsch_max_frame_inactivity = 0;
   }
 );
 
@@ -221,11 +221,11 @@ RUs = (
     local_rf       = "yes"
     nb_tx          = 1
     nb_rx          = 1
-    att_tx         = 3
-    att_rx         = 0;
+    att_tx         = 12
+    att_rx         = 12;
     bands          = [7];
     max_pdschReferenceSignalPower = -27;
-    max_rxgain     = 111;
+    max_rxgain     = 114;
     eNB_instances  = [0];
 #    sdr_addrs = "serial=30C51D4";
 #    clock_src      = "external";
diff --git a/ci-scripts/conf_files/gnb.sa.band66.fr1.106PRB.usrpn300.conf b/ci-scripts/conf_files/gnb.sa.band66.fr1.106PRB.usrpn300.conf
index 7f5a9d434371e4eeee7c56a5835d93b021141ff3..e26fc3030db87abba05336f1c8e012138909ff22 100644
--- a/ci-scripts/conf_files/gnb.sa.band66.fr1.106PRB.usrpn300.conf
+++ b/ci-scripts/conf_files/gnb.sa.band66.fr1.106PRB.usrpn300.conf
@@ -33,10 +33,7 @@ gNBs =
     ////////// Physical parameters:
 
     ssb_SubcarrierOffset                                      = 0;
-    pdsch_AntennaPorts                                        = 1;
-    pusch_AntennaPorts                                        = 1;
     min_rxtxtime                                              = 6;
-    sib1_tda                                                  = 0;
 
      pdcch_ConfigSIB1 = (
       {
diff --git a/ci-scripts/epc.py b/ci-scripts/epc.py
index 9ed9f06d8e9701e96b64a3343a6f5dde5ccbdd73..0fc37d4ead75759dfacecc3474be9e956afe1dc4 100644
--- a/ci-scripts/epc.py
+++ b/ci-scripts/epc.py
@@ -66,6 +66,8 @@ class EPCManagement():
 		self.mmeConfFile = 'mme.conf'
 		self.yamlPath = ''
 		self.isMagmaUsed = False
+		self.cfgDeploy = '--type start-mini --fqdn yes --scenario 1 --capture /tmp/oai-cn5g-v1.3.pcap' #from xml, 'mini' is default normal for docker-network.py 
+		self.cfgUnDeploy = '--type stop-mini --fqdn yes --scenario 1' #from xml, 'mini' is default normal for docker-network.py 
 
 
 #-----------------------------------------------------------
@@ -251,8 +253,8 @@ class EPCManagement():
 			logging.debug('Starting OAI CN5G')
 			mySSH.command('if [ -d ' + self.SourceCodePath + '/scripts ]; then echo ' + self.Password + ' | sudo -S rm -Rf ' + self.SourceCodePath + '/scripts ; fi', '\$', 5)
 			mySSH.command('mkdir -p ' + self.SourceCodePath + '/scripts', '\$', 5)
-			mySSH.command('cd /opt/oai-cn5g-fed/docker-compose', '\$', 5)
-			mySSH.command('./core-network.sh start nrf spgwu', '\$', 60)
+			mySSH.command('cd /opt/oai-cn5g-fed-v1.3/docker-compose', '\$', 5)
+			mySSH.command('python3 ./core-network.py '+self.cfgDeploy, '\$', 60)
 			time.sleep(2)
 			mySSH.command('docker-compose -p 5gcn ps -a', '\$', 60)
 			if mySSH.getBefore().count('Up (healthy)') != 6:
@@ -530,8 +532,8 @@ class EPCManagement():
 				mySSH.command('docker logs ' + c + ' > ' + self.SourceCodePath + '/logs/' + c + '.log', '\$', 5)
 
 			logging.debug('Terminating OAI CN5G')
-			mySSH.command('cd /opt/oai-cn5g-fed/docker-compose', '\$', 5)
-			mySSH.command('./core-network.sh stop nrf spgwu', '\$', 60)
+			mySSH.command('cd /opt/oai-cn5g-fed-v1.3/docker-compose', '\$', 5)
+			mySSH.command('python3 ./core-network.py '+self.cfgUnDeploy, '\$', 60)
 			mySSH.command('docker volume prune --force || true', '\$', 60)
 			time.sleep(2)
 			mySSH.command('tshark -r /tmp/oai-cn5g.pcap | egrep --colour=never "Tracking area update" ','\$', 30)
diff --git a/ci-scripts/main.py b/ci-scripts/main.py
index aa7d512b3dbc52352c429c047a1ca0f231010e49..03947bdfc968c83f83eed43a6f0ab05212b6c218 100644
--- a/ci-scripts/main.py
+++ b/ci-scripts/main.py
@@ -49,7 +49,7 @@ import cls_physim1          #class PhySim for physical simulators deploy and run
 import sshconnection 
 import epc
 import ran
-import html
+import cls_oai_html
 
 
 #-----------------------------------------------------------
@@ -376,6 +376,16 @@ def GetParametersFromXML(action):
 		if (string_field is not None):
 			EPC.yamlPath = string_field
 
+	elif action == 'Initialize_5GCN':
+		string_field = test.findtext('args')
+		if (string_field is not None):
+			EPC.cfgDeploy = string_field	
+
+	elif action == 'Terminate_5GCN':
+		string_field = test.findtext('args')
+		if (string_field is not None):
+			EPC.cfgUnDeploy = string_field	
+
 	elif action == 'Deploy_Object' or action == 'Undeploy_Object':
 		eNB_instance=test.findtext('eNB_instance')
 		if (eNB_instance is None):
@@ -391,7 +401,7 @@ def GetParametersFromXML(action):
 		if (string_field is not None):
 			CONTAINERS.yamlPath[CONTAINERS.eNB_instance] = string_field
 
-	elif action == 'DeployGenObject' or action == 'UndeployGenObject':
+	elif action == 'DeployGenObject' or action == 'UndeployGenObject' or action == 'StatsFromGenObject':
 		string_field=test.findtext('yaml_path')
 		if (string_field is not None):
 			CONTAINERS.yamlPath[0] = string_field
@@ -508,7 +518,7 @@ CiTestObj = cls_oaicitest.OaiCiTest()
 SSH = sshconnection.SSHConnection()
 EPC = epc.EPCManagement()
 RAN = ran.RANManagement()
-HTML = html.HTMLManagement()
+HTML = cls_oai_html.HTMLManagement()
 CONTAINERS = cls_containerize.Containerize()
 SCA = cls_static_code_analysis.StaticCodeAnalysis()
 PHYSIM = cls_physim1.PhySim()
@@ -769,19 +779,19 @@ elif re.match('^TesteNB$', mode, re.IGNORECASE) or re.match('^TestUE$', mode, re
 	HTML.CreateHtmlTabHeader()
 
 	# On CI bench w/ containers, we need to validate if IP routes are set
-	if EPC.IPAddress == '192.168.18.210':
+	if EPC.IPAddress == '172.21.16.136':
 		CONTAINERS.CheckAndAddRoute('porcepix', EPC.IPAddress, EPC.UserName, EPC.Password)
-	if CONTAINERS.eNBIPAddress == '192.168.18.194':
+	if CONTAINERS.eNBIPAddress == '172.21.16.127':
 		CONTAINERS.CheckAndAddRoute('asterix', CONTAINERS.eNBIPAddress, CONTAINERS.eNBUserName, CONTAINERS.eNBPassword)
-	if CONTAINERS.eNB1IPAddress == '192.168.18.194':
+	if CONTAINERS.eNB1IPAddress == '172.21.16.127':
 		CONTAINERS.CheckAndAddRoute('asterix', CONTAINERS.eNB1IPAddress, CONTAINERS.eNB1UserName, CONTAINERS.eNB1Password)
-	if CONTAINERS.eNBIPAddress == '192.168.18.193':
+	if CONTAINERS.eNBIPAddress == '172.21.16.128':
 		CONTAINERS.CheckAndAddRoute('obelix', CONTAINERS.eNBIPAddress, CONTAINERS.eNBUserName, CONTAINERS.eNBPassword)
-	if CONTAINERS.eNB1IPAddress == '192.168.18.193':
+	if CONTAINERS.eNB1IPAddress == '172.21.16.128':
 		CONTAINERS.CheckAndAddRoute('obelix', CONTAINERS.eNB1IPAddress, CONTAINERS.eNB1UserName, CONTAINERS.eNB1Password)
-	if CONTAINERS.eNBIPAddress == '192.168.18.209':
+	if CONTAINERS.eNBIPAddress == '172.21.16.137':
 		CONTAINERS.CheckAndAddRoute('nepes', CONTAINERS.eNBIPAddress, CONTAINERS.eNBUserName, CONTAINERS.eNBPassword)
-	if CONTAINERS.eNB1IPAddress == '192.168.18.209':
+	if CONTAINERS.eNB1IPAddress == '172.21.16.137':
 		CONTAINERS.CheckAndAddRoute('nepes', CONTAINERS.eNB1IPAddress, CONTAINERS.eNB1UserName, CONTAINERS.eNB1Password)
 
 	CiTestObj.FailReportCnt = 0
@@ -931,6 +941,8 @@ elif re.match('^TesteNB$', mode, re.IGNORECASE) or re.match('^TestUE$', mode, re
 					CONTAINERS.IperfFromContainer(HTML, RAN)
 					if CONTAINERS.exitStatus==1:
 						RAN.prematureExit = True
+				elif action == 'StatsFromGenObject':
+					CONTAINERS.StatsFromGenObject(HTML)
 				else:
 					sys.exit('Invalid class (action) from xml')
 				if RAN.prematureExit:
diff --git a/ci-scripts/provideUniqueImageTag.py b/ci-scripts/provideUniqueImageTag.py
index ee8306402fb7bdac08977a9f392c1c6f04de1f85..88d51ca6f88903aa0c69d6057352ba11f52949ab 100644
--- a/ci-scripts/provideUniqueImageTag.py
+++ b/ci-scripts/provideUniqueImageTag.py
@@ -5,15 +5,15 @@ import subprocess
 import sys
 
 AUTH_SERVICE = 'registry.docker.io'
-AUTH_SCOPE   = 'repository:rdefosseoai/oai-enb:pull'
+AUTH_SCOPE   = 'repository:oaisoftwarealliance/oai-enb:pull'
 
 def main() -> None:
     args = _parse_args()
 
-    cmd = 'curl -fsSL "https://auth.docker.io/token?service=' + AUTH_SERVICE + '&scope=' + AUTH_SCOPE + '" | jq --raw-output ".token"'
+    cmd = 'curl -fsSL "https://auth.docker.io/token?service=' + AUTH_SERVICE + '&scope=' + AUTH_SCOPE + '" 2>/dev/null | jq --raw-output ".token"'
     token = subprocess.check_output(cmd, shell=True, universal_newlines=True)
     token = str(token).strip()
-    cmd = 'curl -fsSL -H "Authorization: Bearer ' + token + '" "https://index.docker.io/v2/rdefosseoai/oai-enb/tags/list" | jq .'
+    cmd = 'curl -fsSL -H "Authorization: Bearer ' + token + '" "https://index.docker.io/v2/oaisoftwarealliance/oai-enb/tags/list" 2>/dev/null | jq .'
     listOfTags = subprocess.check_output(cmd, shell=True, universal_newlines=True)
 
     foundTag = False
diff --git a/ci-scripts/ran.py b/ci-scripts/ran.py
index beb89370d24cd0968e68a18f34b120b96345eb13..287a0a3c09b0af23497254827aa193603a20fe2f 100644
--- a/ci-scripts/ran.py
+++ b/ci-scripts/ran.py
@@ -677,13 +677,13 @@ class RANManagement():
 		# if T tracer was run with option 0 (no logs), analyze logs
 		# from textlog, otherwise do normal analysis (e.g., option 2)
 		result = re.search('T_stdout 0', str(self.Initialize_eNB_args))
-		enbLogFile = self.eNBLogFiles[int(self.eNB_instance)]
-		raw_record_file = enbLogFile.replace('.log', '_record.raw')
-		replay_log_file = enbLogFile.replace('.log', '_replay.log')
 		if (result is not None):
 			logging.debug('\u001B[1m Replaying RAW record file\u001B[0m')
 			mySSH.open(lIpAddr, lUserName, lPassWord)
 			mySSH.command('cd ' + lSourcePath + '/common/utils/T/tracer/', '\$', 5)
+			enbLogFile = self.eNBLogFiles[int(self.eNB_instance)]
+			raw_record_file = enbLogFile.replace('.log', '_record.raw')
+			replay_log_file = enbLogFile.replace('.log', '_replay.log')
 			extracted_txt_file = enbLogFile.replace('.log', '_extracted_messages.txt')
 			extracted_log_file = enbLogFile.replace('.log', '_extracted_messages.log')
 			mySSH.command('./extract_config -i ' + lSourcePath + '/cmake_targets/' + raw_record_file + ' > ' + lSourcePath + '/cmake_targets/' + extracted_txt_file, '\$', 5)
@@ -706,8 +706,6 @@ class RANManagement():
 				mySSH.copyin(lIpAddr, lUserName, lPassWord, lSourcePath + '/cmake_targets/*stats.log', '.')
 				mySSH.copyin(lIpAddr, lUserName, lPassWord, lSourcePath + '/cmake_targets/*.pickle', '.')
 				mySSH.copyin(lIpAddr, lUserName, lPassWord, lSourcePath + '/cmake_targets/*.png', '.')
-				mySSH.copyin(lIpAddr, lUserName, lPassWord, lSourcePath + '/cmake_targets/'+raw_record_file, '.')
-				mySSH.copyin(lIpAddr, lUserName, lPassWord, lSourcePath + '/cmake_targets/'+replay_log_file, '.')
 				#
 				copyin_res = mySSH.copyin(lIpAddr, lUserName, lPassWord, lSourcePath + '/cmake_targets/' + fileToAnalyze, '.')
 				if (copyin_res == -1):
@@ -723,9 +721,7 @@ class RANManagement():
 					mySSH.copyout(self.eNBIPAddress, self.eNBUserName, self.eNBPassword, './nrL1_stats.log', self.eNBSourceCodePath + '/cmake_targets/')
 					mySSH.copyout(self.eNBIPAddress, self.eNBUserName, self.eNBPassword, './nrMAC_stats.log', self.eNBSourceCodePath + '/cmake_targets/')
 					mySSH.copyout(self.eNBIPAddress, self.eNBUserName, self.eNBPassword, './gnb_stats_monitor.pickle', self.eNBSourceCodePath + '/cmake_targets/')
-					mySSH.copyout(self.eNBIPAddress, self.eNBUserName, self.eNBPassword, './gnb_stats_monitor.png', self.eNBSourceCodePath + '/cmake_targets/')#RH 21/02/2002 this does not work, there are more than 1 png file
-					mySSH.copyout(self.eNBIPAddress, self.eNBUserName, self.eNBPassword,'./'+raw_record_file, self.eNBSourceCodePath + '/cmake_targets/')
-					mySSH.copyout(self.eNBIPAddress, self.eNBUserName, self.eNBPassword,'./'+replay_log_file, self.eNBSourceCodePath + '/cmake_targets/')
+					mySSH.copyout(self.eNBIPAddress, self.eNBUserName, self.eNBPassword, './gnb_stats_monitor.png', self.eNBSourceCodePath + '/cmake_targets/')
 					#
 					mySSH.copyout(self.eNBIPAddress, self.eNBUserName, self.eNBPassword, './' + fileToAnalyze, self.eNBSourceCodePath + '/cmake_targets/')
 				logging.debug('\u001B[1m Analyzing ' + nodeB_prefix + 'NB logfile \u001B[0m ' + fileToAnalyze)
@@ -826,6 +822,8 @@ class RANManagement():
 		RealTimeProcessingIssue = False
 		DLRetxIssue = False
 		ULRetxIssue = False
+		nrRrcRcfgComplete = 0
+		harqFeedbackPast = 0
 	
 		line_cnt=0 #log file line counter
 		for line in enb_log_file.readlines():
@@ -999,8 +997,25 @@ class RANManagement():
 			for k in keys:
 				result = re.search(k, line)
 				if result is not None:
+					ue_prefix = 'ue0'
+					ue_res = re.search('UE ID 1|UE 1:', line)
+					if ue_res is not None:
+						ue_prefix = 'ue1'
+					ue_res = re.search('UE ID 2|UE 2:', line)
+					if ue_res is not None:
+						ue_prefix = 'ue2'
+					ue_res = re.search('UE ID 3|UE 3:', line)
+					if ue_res is not None:
+						ue_prefix = 'ue3'
 					#remove 1- all useless char before relevant info (ulsch or dlsch) 2- trailing char
-					dlsch_ulsch_stats[k]=re.sub(r'^.*\]\s+', r'' , line.rstrip())
+					dlsch_ulsch_stats[ue_prefix+k]=re.sub(r'^.*\]\s+', r'' , line.rstrip())
+
+			result = re.search('Received NR_RRCReconfigurationComplete from UE', str(line))
+			if result is not None:
+				nrRrcRcfgComplete += 1
+			result = re.search('HARQ feedback is in the past', str(line))
+			if result is not None:
+				harqFeedbackPast += 1
 
 
 			#count "problem receiving samples" msg
@@ -1089,6 +1104,14 @@ class RANManagement():
 				statMsg = nodeB_prefix + 'NB ran with TX Write thread enabled'
 				logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m')
 				htmleNBFailureMsg += statMsg + '\n'
+			if nrRrcRcfgComplete > 0:
+				statMsg = nodeB_prefix + 'NB showed ' + str(nrRrcRcfgComplete) + ' "Received NR_RRCReconfigurationComplete from UE" message(s)'
+				logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m')
+				htmleNBFailureMsg += statMsg + '\n'
+			if harqFeedbackPast > 0:
+				statMsg = nodeB_prefix + 'NB showed ' + str(harqFeedbackPast) + ' "HARQ feedback is in the past" message(s)'
+				logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m')
+				htmleNBFailureMsg += statMsg + '\n'
 			#FR1 NSA test : add new markers to make sure gNB is used
 			if NSA_RAPROC_PUSCH_check:
 				statMsg = '[RAPROC] PUSCH with TC_RNTI message check for ' + nodeB_prefix + 'NB : PASS '
diff --git a/ci-scripts/runTestOnVM.sh b/ci-scripts/runTestOnVM.sh
index 31ffa9d727053deb6577ae6e351f0418966b1dda..2472ffe3bcb89fd8abd7086e5d0ef751929e075b 100755
--- a/ci-scripts/runTestOnVM.sh
+++ b/ci-scripts/runTestOnVM.sh
@@ -1899,7 +1899,7 @@ function run_test_on_vm {
             CURRENT_NR_UE_LOG_FILE=tdd_${PRB}prb_${CN_CONFIG}_ue_sa_test.log
             #last argument = 2 is to enable --sa for SA test for 106PRB
             start_rf_sim_nr_ue $NR_UE_VM_CMDS $NR_UE_VM_IP_ADDR $GNB_VM_IP_ADDR $CURRENT_NR_UE_LOG_FILE $PRB $FREQUENCY $S1_NOS1_CFG 2
-            if [ $NR_UE_SYNC -eq 0 ]
+            if [ $GNB_SYNC -eq 0 ] || [ $NR_UE_SYNC -eq 0 ]
             then
                 echo "Problem w/ gNB and NR-UE not syncing"
                 terminate_enb_ue_basic_sim $NR_UE_VM_CMDS $NR_UE_VM_IP_ADDR 2
@@ -1939,6 +1939,12 @@ function run_test_on_vm {
                 SA_106PRB_STATUS=0
             fi
         done
+        #manage SYNC issue after try_cnt
+        if [ $SYNC_STATUS -ne 0 ]
+        then
+            echo "SA 106PRB test NOT OK, NOT SYNC'ED"
+            SA_106PRB_STATUS=-1
+        fi
         ########### end SA test
 
         sleep 30
@@ -1982,7 +1988,7 @@ function run_test_on_vm {
             CURRENT_NR_UE_LOG_FILE=tdd_${PRB}prb_${CN_CONFIG}_ue_sa_test.log
             #last argument = 3 is to enable --sa for SA test for 24PRB
             start_rf_sim_nr_ue $NR_UE_VM_CMDS $NR_UE_VM_IP_ADDR $GNB_VM_IP_ADDR $CURRENT_NR_UE_LOG_FILE $PRB $FREQUENCY $S1_NOS1_CFG 3
-            if [ $NR_UE_SYNC -eq 0 ]
+            if [ $GNB_SYNC -eq 0 ] || [ $NR_UE_SYNC -eq 0 ]
             then
                 echo "Problem w/ gNB and NR-UE not syncing"
                 terminate_enb_ue_basic_sim $NR_UE_VM_CMDS $NR_UE_VM_IP_ADDR 2
@@ -2022,6 +2028,12 @@ function run_test_on_vm {
                 SA_24PRB_STATUS=0
             fi
         done
+        #manage SYNC issue after try_cnt
+        if [ $SYNC_STATUS -ne 0 ]
+        then
+            echo "SA 24PRB test NOT OK, NOT SYNC'ED"
+            SA_24PRB_STATUS=-1
+        fi
         ########### end SA test
 
         sleep 30
@@ -2070,7 +2082,7 @@ function run_test_on_vm {
             CURRENT_NR_UE_LOG_FILE=tdd_${PRB}prb_${CN_CONFIG}_ue_ra_fr2_test.log
             #last argument = 1 is to enable --do-ra for RA test
             start_rf_sim_nr_ue $NR_UE_VM_CMDS $NR_UE_VM_IP_ADDR $GNB_VM_IP_ADDR $CURRENT_NR_UE_LOG_FILE $PRB $FREQUENCY $S1_NOS1_CFG 1
-            if [ $NR_UE_SYNC -eq 0 ]
+            if [ $GNB_SYNC -eq 0 ] || [ $NR_UE_SYNC -eq 0 ]
             then
                 echo "Problem w/ gNB and NR-UE not syncing"
                 terminate_enb_ue_basic_sim $NR_UE_VM_CMDS $NR_UE_VM_IP_ADDR 2
@@ -2110,6 +2122,12 @@ function run_test_on_vm {
                 try_cnt=$((try_cnt+10))
             fi
         done
+        #manage SYNC issue after try_cnt
+        if [ $SYNC_STATUS -ne 0 ]
+        then
+            echo "RA FR2 test NOT OK, NOT SYNC'ED"
+            RA_FR2_STATUS=-1
+        fi
         ########### end RA FR2 test
 
         sleep 30
@@ -2172,7 +2190,7 @@ function run_test_on_vm {
             CURRENT_NR_UE_LOG_FILE=${TMODE}_${PRB}prb_${CN_CONFIG}_ue_ra_test.log
             #last argument = 1 is to enable --do-ra for RA test
             start_rf_sim_nr_ue $NR_UE_VM_CMDS $NR_UE_VM_IP_ADDR $GNB_VM_IP_ADDR $CURRENT_NR_UE_LOG_FILE $PRB $FREQUENCY $S1_NOS1_CFG 1
-            if [ $NR_UE_SYNC -eq 0 ]
+            if [ $GNB_SYNC -eq 0 ] || [ $NR_UE_SYNC -eq 0 ]
             then
                 echo "Problem w/ gNB and NR-UE not syncing"
                 terminate_enb_ue_basic_sim $NR_UE_VM_CMDS $NR_UE_VM_IP_ADDR 2
@@ -2212,6 +2230,13 @@ function run_test_on_vm {
                 try_cnt=$((try_cnt+10))
             fi
           done
+          #manage SYNC issue after try_cnt
+          if [ $SYNC_STATUS -ne 0 ]
+          then
+            echo "RA FR1 test NOT OK, NOT SYNC'ED"
+            RA_FR1_STATUS=-1
+          fi
+
         done
         ########### end RA test
         
@@ -2253,7 +2278,7 @@ function run_test_on_vm {
             echo "############################################################"
             CURRENT_NR_UE_LOG_FILE=${TMODE}_${PRB}prb_${CN_CONFIG}_ue.log
             start_rf_sim_nr_ue $NR_UE_VM_CMDS $NR_UE_VM_IP_ADDR $GNB_VM_IP_ADDR $CURRENT_NR_UE_LOG_FILE $PRB $FREQUENCY $S1_NOS1_CFG 0
-            if [ $NR_UE_SYNC -eq 0 ]
+            if [ $GNB_SYNC -eq 0 ] || [ $NR_UE_SYNC -eq 0 ]
             then
                 echo "Problem w/ gNB and NR-UE not syncing"
                 terminate_enb_ue_basic_sim $NR_UE_VM_CMDS $NR_UE_VM_IP_ADDR 2
@@ -2332,6 +2357,13 @@ function run_test_on_vm {
                 try_cnt=$((try_cnt+10))
             fi
           done
+          #manage SYNC issue after try_cnt
+          if [ $SYNC_STATUS -ne 0 ]
+          then
+              echo "PHY test NOT OK, NOT SYNC'ED"
+              IPERF_STATUS=-1
+          fi
+
         done
         ######### end of loop
         full_l2_sim_destroy
@@ -2345,7 +2377,6 @@ function run_test_on_vm {
         if [ $SA_24PRB_STATUS -ne 0 ]; then NR_STATUS=-1; fi  
         if [ $RA_FR2_STATUS -ne 0 ]; then NR_STATUS=-1; fi        
         if [ $RA_FR1_STATUS -ne 0 ]; then NR_STATUS=-1; fi
-        if [ $SYNC_STATUS -ne 0 ]; then NR_STATUS=-1; fi
         if [ $PING_STATUS -ne 0 ]; then NR_STATUS=-1; fi
         if [ $IPERF_STATUS -ne 0 ]; then NR_STATUS=-1; fi
         if [ $NR_STATUS -eq 0 ]
diff --git a/ci-scripts/sshconnection.py b/ci-scripts/sshconnection.py
index d5b4a4c83e459ce8825977420949b2fe6588152f..dca3daa817ce8c1ab13cff291b29df605894092f 100644
--- a/ci-scripts/sshconnection.py
+++ b/ci-scripts/sshconnection.py
@@ -56,6 +56,7 @@ class SSHConnection():
 		self.picocom_closure = True
 
 	def open(self, ipaddress, username, password):
+		prompt = "#" if username == "root" else "\$"
 		count = 0
 		connect_status = False
 		while count < 4:
@@ -68,7 +69,7 @@ class SSHConnection():
 				self.sshresponse = self.ssh.expect(['password:', username + '@'])
 				if self.sshresponse == 0:
 					self.ssh.sendline(password)
-				self.sshresponse = self.ssh.expect(['\$', 'Permission denied', 'password:', pexpect.EOF, pexpect.TIMEOUT])
+				self.sshresponse = self.ssh.expect([prompt, 'Permission denied', 'password:', pexpect.EOF, pexpect.TIMEOUT])
 				if self.sshresponse == 0:
 					count = 10
 					connect_status = True
@@ -76,7 +77,7 @@ class SSHConnection():
 					logging.debug('self.sshresponse = ' + str(self.sshresponse))
 			elif self.sshresponse == 1:
 				self.ssh.sendline(password)
-				self.sshresponse = self.ssh.expect(['\$', 'Permission denied', 'password:', pexpect.EOF, pexpect.TIMEOUT])
+				self.sshresponse = self.ssh.expect([prompt, 'Permission denied', 'password:', pexpect.EOF, pexpect.TIMEOUT])
 				if self.sshresponse == 0:
 					count = 10
 					connect_status = True
@@ -84,7 +85,7 @@ class SSHConnection():
 					logging.debug('self.sshresponse = ' + str(self.sshresponse))
 			elif self.sshresponse == 2:
 				# Checking if we are really on the remote client defined by its IP address
-				self.command('stdbuf -o0 ifconfig | egrep --color=never "inet addr:|inet "', '\$', 5)
+				self.command('stdbuf -o0 ifconfig | egrep --color=never "inet addr:|inet "', prompt, 5)
 				result = re.search(str(ipaddress), str(self.ssh.before))
 				if result is None:
 					self.close()
@@ -100,7 +101,7 @@ class SSHConnection():
 				time.sleep(1)
 			count += 1
 		if connect_status:
-			self.command('unset HISTFILE', '\$', 5, silent=True)
+			self.command('unset HISTFILE', prompt, 5, silent=True)
 		else:
 			sys.exit('SSH Connection Failed')
 		self.ipaddress = ipaddress
diff --git a/ci-scripts/xml_class_list.yml b/ci-scripts/xml_class_list.yml
index 9e33ee468de70d1ef0eb6b1484e02a6f539f5204..d6f75191a8da8bc7818d9c7d55adc8b9aad5d21d 100755
--- a/ci-scripts/xml_class_list.yml
+++ b/ci-scripts/xml_class_list.yml
@@ -46,3 +46,4 @@
   - UndeployGenObject
   - PingFromContainer
   - IperfFromContainer
+  - StatsFromGenObject
diff --git a/ci-scripts/xml_files/container_5g_l2sim_tdd.xml b/ci-scripts/xml_files/container_5g_l2sim_tdd.xml
new file mode 100644
index 0000000000000000000000000000000000000000..be6b789b6bc87d9ffa31661c55f7d273bb786376
--- /dev/null
+++ b/ci-scripts/xml_files/container_5g_l2sim_tdd.xml
@@ -0,0 +1,115 @@
+<!--
+
+ 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>l2sim-5gnr-tdd</htmlTabRef>
+        <htmlTabName>Testing 5G NR L2 sim - TDD gNB</htmlTabName>
+        <htmlTabIcon>wrench</htmlTabIcon>
+        <repeatCount>2</repeatCount>
+        <TestCaseRequestedList>
+ 100001
+ 000000
+ 000001
+ 000002
+ 000003
+ 000011
+ 200000
+ 020001
+ 020002
+ 200001
+ 100001
+        </TestCaseRequestedList>
+        <TestCaseExclusionList></TestCaseExclusionList>
+
+        <testCase id="000000">
+                <class>DeployGenObject</class>
+                <desc>Deploy MySql Database</desc>
+                <yaml_path>yaml_files/5g_l2sim_tdd</yaml_path>
+                <services>mysql</services>
+                <nb_healthy>1</nb_healthy>
+        </testCase>
+
+        <testCase id="000001">
+                <class>DeployGenObject</class>
+                <desc>Deploy OAI 5G CoreNetwork</desc>
+                <yaml_path>yaml_files/5g_l2sim_tdd</yaml_path>
+                <services>oai-nrf oai-amf oai-smf oai-spgwu oai-ext-dn</services>
+                <nb_healthy>6</nb_healthy>
+        </testCase>
+
+        <testCase id="000002">
+                <class>DeployGenObject</class>
+                <desc>Deploy OAI 5G gNB L2 sim SA</desc>
+                <yaml_path>yaml_files/5g_l2sim_tdd</yaml_path>
+                <services>oai-gnb</services>
+                <nb_healthy>7</nb_healthy>
+        </testCase>
+
+        <testCase id="000003">
+                <class>DeployGenObject</class>
+                <desc>Deploy OAI 5G NR-UE L2 sim SA and Proxy</desc>
+                <yaml_path>yaml_files/5g_l2sim_tdd</yaml_path>
+                <services>proxy oai-nr-ue0</services>
+                <nb_healthy>9</nb_healthy>
+        </testCase>
+
+        <testCase id="000011">
+                <class>IdleSleep</class>
+                <desc>Sleep</desc>
+                <idle_sleep_time_in_sec>10</idle_sleep_time_in_sec>
+        </testCase>
+
+        <testCase id="020001">
+                <class>PingFromContainer</class>
+                <desc>Ping ext-dn from NR-UE</desc>
+                <container_name>l2sim-oai-nr-ue0</container_name>
+                <options>-I oaitun_ue1 -c 20 192.168.72.135</options>
+                <loss_threshold>5</loss_threshold>
+        </testCase>
+
+        <testCase id="020002">
+                <class>PingFromContainer</class>
+                <desc>Ping NR-UE from ext-dn</desc>
+                <container_name>l2sim-oai-ext-dn</container_name>
+                <options>-c 20 12.1.1.2</options>
+                <loss_threshold>5</loss_threshold>
+        </testCase>
+
+        <testCase id="100001">
+                <class>UndeployGenObject</class>
+                <desc>Undeploy all OAI 5G stack</desc>
+                <yaml_path>yaml_files/5g_l2sim_tdd</yaml_path>
+        </testCase>
+
+        <testCase id="200000">
+                <class>StatsFromGenObject</class>
+                <desc>Statistics before Traffic Test</desc>
+                <yaml_path>yaml_files/5g_l2sim_tdd</yaml_path>
+        </testCase>
+
+        <testCase id="200001">
+                <class>StatsFromGenObject</class>
+                <desc>Statistics after Traffic Test</desc>
+                <yaml_path>yaml_files/5g_l2sim_tdd</yaml_path>
+        </testCase>
+
+</testCaseList>
diff --git a/ci-scripts/xml_files/container_5g_l2sim_tdd_down.xml b/ci-scripts/xml_files/container_5g_l2sim_tdd_down.xml
new file mode 100644
index 0000000000000000000000000000000000000000..d3630cd9059aaa8927a4738fdcdde5b291f44702
--- /dev/null
+++ b/ci-scripts/xml_files/container_5g_l2sim_tdd_down.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>l2sim-5gnr-down</htmlTabRef>
+        <htmlTabName>CleanUp 5G L2 sim - TDD gNB</htmlTabName>
+        <htmlTabIcon>trash</htmlTabIcon>
+        <TestCaseRequestedList>
+ 100002
+        </TestCaseRequestedList>
+        <TestCaseExclusionList></TestCaseExclusionList>
+
+        <testCase id="100002">
+                <class>UndeployGenObject</class>
+                <desc>Undeploy all OAI 5G stack</desc>
+                <yaml_path>yaml_files/5g_l2sim_tdd</yaml_path>
+        </testCase>
+
+</testCaseList>
diff --git a/ci-scripts/xml_files/container_5g_rfsim.xml b/ci-scripts/xml_files/container_5g_rfsim.xml
index bab7f9637ad3ef6b187cec5e9edfd80deefca6d4..a1f50948a501baa6e5fe316e335333a55b7f2ba0 100644
--- a/ci-scripts/xml_files/container_5g_rfsim.xml
+++ b/ci-scripts/xml_files/container_5g_rfsim.xml
@@ -31,8 +31,11 @@
  000001
  000002
  000003
+ 000004
  020001
  020002
+ 020003
+ 020004
  030001
  030002
  100001
@@ -71,6 +74,14 @@
                 <nb_healthy>8</nb_healthy>
         </testCase>
 
+        <testCase id="000004">
+                <class>DeployGenObject</class>
+                <desc>Deploy Second OAI 5G NR-UE RF sim SA</desc>
+                <yaml_path>yaml_files/5g_rfsimulator</yaml_path>
+                <services>oai-nr-ue2</services>
+                <nb_healthy>9</nb_healthy>
+        </testCase>
+
         <testCase id="020001">
                 <class>PingFromContainer</class>
                 <desc>Ping ext-dn from NR-UE</desc>
@@ -87,6 +98,22 @@
                 <loss_threshold>5</loss_threshold>
         </testCase>
 
+        <testCase id="020003">
+                <class>PingFromContainer</class>
+                <desc>Ping ext-dn from Second NR-UE</desc>
+                <container_name>rfsim5g-oai-nr-ue2</container_name>
+                <options>-I oaitun_ue1 -c 20 192.168.72.135</options>
+                <loss_threshold>5</loss_threshold>
+        </testCase>
+
+        <testCase id="020004">
+                <class>PingFromContainer</class>
+                <desc>Ping Second NR-UE from ext-dn</desc>
+		<container_name>rfsim5g-oai-ext-dn</container_name>
+                <options>-c 20 12.1.1.3</options>
+                <loss_threshold>5</loss_threshold>
+        </testCase>
+
         <testCase id="030001">
                 <class>IperfFromContainer</class>
                 <desc>Iperf UDP Downlink</desc>
diff --git a/ci-scripts/xml_files/container_nsa_b200_quectel.xml b/ci-scripts/xml_files/container_nsa_b200_quectel.xml
index 610f0b019a447ff5e78e632cd9b016143c054f6b..47a939f63c51c18b395017a5ddb0411efff83beb 100644
--- a/ci-scripts/xml_files/container_nsa_b200_quectel.xml
+++ b/ci-scripts/xml_files/container_nsa_b200_quectel.xml
@@ -138,19 +138,19 @@
 
 	<testCase id="070000">
 		<class>Iperf</class>
-		<desc>iperf (DL/40Mbps/UDP)(60 sec)(single-ue profile)</desc>
-		<iperf_args>-u -b 40M -t 60 -i 1 -fm</iperf_args>
+		<desc>iperf (DL/125Mbps/UDP)(60 sec)(single-ue profile)</desc>
+		<iperf_args>-u -b 125M -t 60 -i 1 -fm</iperf_args>
 		<direction>DL</direction>
 		<id>idefix</id>
-		<iperf_packetloss_threshold>20</iperf_packetloss_threshold>
-		<iperf_bitrate_threshold>85</iperf_bitrate_threshold>
+		<iperf_packetloss_threshold>1</iperf_packetloss_threshold>
+		<iperf_bitrate_threshold>95</iperf_bitrate_threshold>
 		<iperf_profile>single-ue</iperf_profile>
 	</testCase>
 
 	<testCase id="070001">
 		<class>Iperf</class>
-		<desc>iperf (UL/3Mbps/UDP)(60 sec)(single-ue profile)</desc>
-		<iperf_args>-u -b 3M -t 60 -i 1 -fm</iperf_args>
+		<desc>iperf (UL/8Mbps/UDP)(60 sec)(single-ue profile)</desc>
+		<iperf_args>-u -b 8M -t 60 -i 1 -fm</iperf_args>
 		<direction>UL</direction>
 		<id>idefix</id>
 		<iperf_packetloss_threshold>1</iperf_packetloss_threshold>
diff --git a/ci-scripts/xml_files/fr1_nsa_2x2_quectel.xml b/ci-scripts/xml_files/fr1_nsa_2x2_quectel.xml
index 56694920ba593fbc6d048c7169e8df00c2940893..2ef2b7d7ce74f2ac6f7b5a4bce433fd35effbb9b 100644
--- a/ci-scripts/xml_files/fr1_nsa_2x2_quectel.xml
+++ b/ci-scripts/xml_files/fr1_nsa_2x2_quectel.xml
@@ -68,7 +68,7 @@
 		<air_interface>lte</air_interface>
 		<eNB_Trace>yes</eNB_Trace>
 		<eNB_Stats>yes</eNB_Stats>
-		<USRP_IPAddress>192.168.18.241</USRP_IPAddress>
+		<USRP_IPAddress>172.21.19.13</USRP_IPAddress>
 	</testCase>
 
 
@@ -81,7 +81,7 @@
 		<air_interface>nr</air_interface>
 		<eNB_Stats>yes</eNB_Stats>
 		<rt_stats_cfg>datalog_rt_stats.2x2.yaml</rt_stats_cfg>
-		<USRP_IPAddress>192.168.18.252</USRP_IPAddress>
+		<USRP_IPAddress>172.21.19.14</USRP_IPAddress>
 	</testCase>
 
 	<testCase id="000001">
@@ -115,11 +115,12 @@
 
 	<testCase id="070000">
 		<class>Iperf</class>
-		<desc>iperf (DL/60Mbps/UDP)(60 sec)(single-ue profile)</desc>
-		<iperf_args>-u -b 60M -t 60</iperf_args>
+		<desc>iperf (DL/125Mbps/UDP)(60 sec)(single-ue profile)</desc>
+		<iperf_args>-u -b 125M -t 60</iperf_args>
 		<direction>DL</direction>
 		<id>nrmodule2_quectel</id>
-		<iperf_packetloss_threshold>5</iperf_packetloss_threshold>
+		<iperf_packetloss_threshold>15</iperf_packetloss_threshold>
+		<iperf_bitrate_threshold>85</iperf_bitrate_threshold>
 		<iperf_profile>single-ue</iperf_profile>
 	</testCase>
 
diff --git a/ci-scripts/xml_files/fr1_nsa_2x2_quectel_attach_detach.xml b/ci-scripts/xml_files/fr1_nsa_2x2_quectel_attach_detach.xml
index 840521481e82fa69d058b59ed830eeec1dd77f93..335fe873a163afc0002ee94c663efcc1973b5e0d 100644
--- a/ci-scripts/xml_files/fr1_nsa_2x2_quectel_attach_detach.xml
+++ b/ci-scripts/xml_files/fr1_nsa_2x2_quectel_attach_detach.xml
@@ -87,7 +87,7 @@
 		<air_interface>lte</air_interface>
 		<eNB_Trace>yes</eNB_Trace>
 		<eNB_Stats>yes</eNB_Stats>
-		<USRP_IPAddress>192.168.18.241</USRP_IPAddress>
+		<USRP_IPAddress>172.21.19.13</USRP_IPAddress>
 	</testCase>
 
 
@@ -100,7 +100,7 @@
 		<air_interface>nr</air_interface>
 		<eNB_Stats>yes</eNB_Stats>
 		<rt_stats_cfg>datalog_rt_stats.2x2.yaml</rt_stats_cfg>
-		<USRP_IPAddress>192.168.18.252</USRP_IPAddress>
+		<USRP_IPAddress>172.21.19.14</USRP_IPAddress>
 	</testCase>
 
 	<testCase id="000001">
diff --git a/ci-scripts/xml_files/fr1_nsa_quectel.xml b/ci-scripts/xml_files/fr1_nsa_quectel.xml
index 55f6f4376ea275760a7c41aa5e7856a5c1860548..0f8c90abdf12b0e97e9c5fc1b343f45dfa311757 100644
--- a/ci-scripts/xml_files/fr1_nsa_quectel.xml
+++ b/ci-scripts/xml_files/fr1_nsa_quectel.xml
@@ -74,7 +74,7 @@
 	<testCase id="040000">
 		<class>Initialize_eNB</class>
 		<desc>Initialize gNB</desc>
-		<Initialize_eNB_args>-O ci-scripts/conf_files/gnb.band78.tm1.fr1.106PRB.usrpb210.conf -E -q --RUs.[0].sdr_addrs "serial=30C51D4" --log_config.global_log_options level,nocolor,time,line_num,function</Initialize_eNB_args>
+		<Initialize_eNB_args>-O ci-scripts/conf_files/gnb.band78.tm1.fr1.106PRB.usrpb210.conf -E -q --RUs.[0].sdr_addrs "serial=30C51D4" --continuous-tx --log_config.global_log_options level,nocolor,time,line_num,function</Initialize_eNB_args>
 		<eNB_instance>1</eNB_instance>
 		<eNB_serverId>1</eNB_serverId>
 		<air_interface>nr</air_interface>
@@ -117,37 +117,37 @@
 		<iperf_args>-u -b 30M -t 30</iperf_args>
 		<direction>DL</direction>
 		<id>idefix</id>
-		<iperf_packetloss_threshold>5</iperf_packetloss_threshold>
+		<iperf_packetloss_threshold>1</iperf_packetloss_threshold>
 		<iperf_bitrate_threshold>95</iperf_bitrate_threshold>
 		<iperf_profile>single-ue</iperf_profile>
 	</testCase>
 
 	<testCase id="070001">
 		<class>Iperf</class>
-		<desc>iperf (DL/40Mbps/UDP)(30 sec)(single-ue profile)</desc>
-		<iperf_args>-u -b 40M -t 30</iperf_args>
+		<desc>iperf (DL/90Mbps/UDP)(30 sec)(single-ue profile)</desc>
+		<iperf_args>-u -b 90M -t 30</iperf_args>
 		<direction>DL</direction>
 		<id>idefix</id>
-		<iperf_packetloss_threshold>5</iperf_packetloss_threshold>
+		<iperf_packetloss_threshold>1</iperf_packetloss_threshold>
 		<iperf_bitrate_threshold>95</iperf_bitrate_threshold>
 		<iperf_profile>single-ue</iperf_profile>
 	</testCase>
 
 	<testCase id="070002">
 		<class>Iperf</class>
-		<desc>iperf (DL/60Mbps/UDP)(60 sec)(single-ue profile)</desc>
-		<iperf_args>-u -b 60M -t 60</iperf_args>
+		<desc>iperf (DL/125Mbps/UDP)(60 sec)(single-ue profile)</desc>
+		<iperf_args>-u -b 125M -t 60</iperf_args>
 		<direction>DL</direction>
 		<id>idefix</id>
-		<iperf_packetloss_threshold>5</iperf_packetloss_threshold>
+		<iperf_packetloss_threshold>1</iperf_packetloss_threshold>
 		<iperf_bitrate_threshold>95</iperf_bitrate_threshold>
 		<iperf_profile>single-ue</iperf_profile>
 	</testCase>
 
 	<testCase id="070003">
 		<class>Iperf</class>
-		<desc>iperf (UL/3Mbps/UDP)(60 sec)(single-ue profile)</desc>
-		<iperf_args>-u -b 3M -t 60</iperf_args>
+		<desc>iperf (UL/8Mbps/UDP)(60 sec)(single-ue profile)</desc>
+		<iperf_args>-u -b 8M -t 60</iperf_args>
 		<direction>UL</direction>
 		<id>idefix</id>
 		<iperf_packetloss_threshold>1</iperf_packetloss_threshold>
diff --git a/ci-scripts/xml_files/fr1_sa_amarisoft_ue_1x.xml b/ci-scripts/xml_files/fr1_sa_amarisoft_ue_1x.xml
new file mode 100644
index 0000000000000000000000000000000000000000..ea031a0174ef631c6a063fc9b276b133ec9d3a9e
--- /dev/null
+++ b/ci-scripts/xml_files/fr1_sa_amarisoft_ue_1x.xml
@@ -0,0 +1,87 @@
+<!--
+
+ 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-SA-FR1-Tab1</htmlTabRef>
+	<htmlTabName>SA Ping DL UL with 1 AS UE</htmlTabName>
+	<htmlTabIcon>tasks</htmlTabIcon>
+	<repeatCount>1</repeatCount>
+	<TestCaseRequestedList>
+ 040000
+ 000001
+ 010000
+ 000002
+ 050000
+ 080000
+	</TestCaseRequestedList>
+	<TestCaseExclusionList></TestCaseExclusionList>
+
+	<testCase id="010000">
+		<class>Initialize_UE</class>
+		<desc>Run AS UE Scenario</desc>
+		<id>amarisoft_ue_1</id>
+	</testCase>
+
+
+	<testCase id="040000">
+		<class>Initialize_eNB</class>
+		<desc>Initialize gNB</desc>
+		<Initialize_eNB_args>-O ci-scripts/conf_files/gnb.band78.sa.fr1.106PRB.2x2.usrpn310.asue.conf --sa -q --usrp-tx-thread-config 1 --T_stdout 2 --log_config.global_log_options level,nocolor,time</Initialize_eNB_args>
+		<eNB_instance>0</eNB_instance>
+		<eNB_serverId>0</eNB_serverId>
+		<air_interface>nr</air_interface>
+		<eNB_Trace>yes</eNB_Trace>
+		<eNB_Stats>yes</eNB_Stats>
+		<rt_stats_cfg>datalog_rt_stats.2x2.yaml</rt_stats_cfg>
+		<USRP_IPAddress>172.21.19.14</USRP_IPAddress>
+	</testCase>
+
+	<testCase id="050000">
+		<class>Ping</class>
+		<desc>Ping Log Analysis</desc>
+		<id>amarisoft_ue_1</id>
+		<ping_packetloss_threshold>1</ping_packetloss_threshold>
+	</testCase>
+
+	<testCase id="000001">
+		<class>IdleSleep</class>
+		<desc>Sleep</desc>
+		<idle_sleep_time_in_sec>60</idle_sleep_time_in_sec>
+	</testCase>
+
+	<testCase id="000002">
+		<class>IdleSleep</class>
+		<desc>Sleep</desc>
+		<idle_sleep_time_in_sec>20</idle_sleep_time_in_sec>
+	</testCase>
+
+
+	<testCase id="080000">
+		<class>Terminate_eNB</class>
+		<desc>Terminate gNB</desc>
+		<eNB_instance>0</eNB_instance>
+		<eNB_serverId>0</eNB_serverId>
+		<air_interface>nr</air_interface>
+	</testCase>
+
+</testCaseList>
+
diff --git a/ci-scripts/xml_files/fr1_sa_oaiue_b200.xml b/ci-scripts/xml_files/fr1_sa_oaiue_b200.xml
index 55268b909d7451a55345acd44bbfbb157d86d5b0..5995f75a64460044866fea1db966b13f5e2b158b 100644
--- a/ci-scripts/xml_files/fr1_sa_oaiue_b200.xml
+++ b/ci-scripts/xml_files/fr1_sa_oaiue_b200.xml
@@ -60,7 +60,7 @@
 		<air_interface>nr</air_interface>
 		<eNB_Trace>yes</eNB_Trace>
 		<eNB_Stats>yes</eNB_Stats>
-		<USRP_IPAddress>192.168.18.252</USRP_IPAddress>
+		<USRP_IPAddress>172.21.19.14</USRP_IPAddress>
 	</testCase>
 
 	<testCase id="000001">
diff --git a/ci-scripts/xml_files/fr1_sa_oaiue_n310.xml b/ci-scripts/xml_files/fr1_sa_oaiue_n310.xml
index 53b696c6eb0fffbd8c198bfefedd445d12297bd8..468005f54f677f8208ded94f278a67a7088e746e 100644
--- a/ci-scripts/xml_files/fr1_sa_oaiue_n310.xml
+++ b/ci-scripts/xml_files/fr1_sa_oaiue_n310.xml
@@ -42,7 +42,7 @@
 		<class>Initialize_OAI_UE</class>
 		<desc>Initialize OAI UE (N310)</desc>
 		<air_interface>nr</air_interface>
-		<Initialize_OAI_UE_args>--sa -O ../../../ci-scripts/conf_files/ue.sa.conf --usrp-args "mgmt_addr=192.168.18.241,addr=192.168.10.2"  --numerology 1 -r 106 --band 78 -C 3319680000 --nokrnmod 1 --ue-txgain 0 --ue-rxgain 70 --ue-fo-compensation --log_config.global_log_options level,nocolor,time</Initialize_OAI_UE_args>
+		<Initialize_OAI_UE_args>--sa -O ../../../ci-scripts/conf_files/ue.sa.conf --usrp-args "mgmt_addr=172.21.19.13,addr=192.168.10.2"  --numerology 1 -r 106 --band 78 -C 3319680000 --nokrnmod 1 --ue-txgain 0 --ue-rxgain 70 --ue-fo-compensation --log_config.global_log_options level,nocolor,time</Initialize_OAI_UE_args>
 	</testCase>
 
 	<testCase id="010002">
@@ -60,7 +60,7 @@
 		<air_interface>nr</air_interface>
 		<eNB_Trace>yes</eNB_Trace>
 		<eNB_Stats>yes</eNB_Stats>
-		<USRP_IPAddress>192.168.18.252</USRP_IPAddress>
+		<USRP_IPAddress>172.21.19.14</USRP_IPAddress>
 	</testCase>
 
 	<testCase id="000001">
diff --git a/ci-scripts/xml_files/fr1_sa_oaiue_x300.xml b/ci-scripts/xml_files/fr1_sa_oaiue_x300.xml
index 8c2f7052e4eb52101575ba8646345d59f16f6f76..ef001a7518f2cc28392c28acff585cfdfa933712 100644
--- a/ci-scripts/xml_files/fr1_sa_oaiue_x300.xml
+++ b/ci-scripts/xml_files/fr1_sa_oaiue_x300.xml
@@ -60,7 +60,7 @@
 		<air_interface>nr</air_interface>
 		<eNB_Trace>yes</eNB_Trace>
 		<eNB_Stats>yes</eNB_Stats>
-		<USRP_IPAddress>192.168.18.252</USRP_IPAddress>
+		<USRP_IPAddress>172.21.19.14</USRP_IPAddress>
 	</testCase>
 
 	<testCase id="000001">
diff --git a/ci-scripts/xml_files/fr1_sa_quectel.xml b/ci-scripts/xml_files/fr1_sa_quectel.xml
index 576456ebc96959cd3e9e4284c84e02ecce1d1685..4d4edab56bd4be6c4e0b67836647dec1885269a3 100644
--- a/ci-scripts/xml_files/fr1_sa_quectel.xml
+++ b/ci-scripts/xml_files/fr1_sa_quectel.xml
@@ -70,7 +70,7 @@
 		<eNB_Trace>yes</eNB_Trace>
 		<eNB_Stats>yes</eNB_Stats>
 		<rt_stats_cfg>datalog_rt_stats.2x2.yaml</rt_stats_cfg>
-		<USRP_IPAddress>192.168.18.252</USRP_IPAddress>
+		<USRP_IPAddress>172.21.19.14</USRP_IPAddress>
 	</testCase>
 
 	<testCase id="000001">
diff --git a/ci-scripts/xml_files/fr1_sa_quectel_162prb.xml b/ci-scripts/xml_files/fr1_sa_quectel_162prb.xml
index c5f2ddad5f479a4691330392499fdb1d7226838d..23eaccfcfd2d5fe6f9b4d82685b3b11e4e6b2459 100644
--- a/ci-scripts/xml_files/fr1_sa_quectel_162prb.xml
+++ b/ci-scripts/xml_files/fr1_sa_quectel_162prb.xml
@@ -68,7 +68,7 @@
 		<eNB_Trace>yes</eNB_Trace>
 		<eNB_Stats>yes</eNB_Stats>
 		<rt_stats_cfg>datalog_rt_stats.2x2.yaml</rt_stats_cfg>
-		<USRP_IPAddress>192.168.18.252</USRP_IPAddress>
+		<USRP_IPAddress>172.21.19.14</USRP_IPAddress>
 	</testCase>
 
 	<testCase id="000001">
diff --git a/ci-scripts/xml_files/fr1_sa_quectel_stages.xml b/ci-scripts/xml_files/fr1_sa_quectel_stages.xml
index 2707fd4ebff998441de2c9a23d42458976fdcd05..603f3f919b47f0de104a4a5d0b7db8f8d117c84b 100644
--- a/ci-scripts/xml_files/fr1_sa_quectel_stages.xml
+++ b/ci-scripts/xml_files/fr1_sa_quectel_stages.xml
@@ -74,7 +74,7 @@
 		<eNB_Trace>yes</eNB_Trace>
 		<eNB_Stats>yes</eNB_Stats>
 		<rt_stats_cfg>datalog_rt_stats.2x2.yaml</rt_stats_cfg>
-		<USRP_IPAddress>192.168.18.252</USRP_IPAddress>
+		<USRP_IPAddress>172.21.19.14</USRP_IPAddress>
 	</testCase>
 
 	<testCase id="000001">
diff --git a/ci-scripts/xml_files/fr1_sa_quectel_stages_162prb.xml b/ci-scripts/xml_files/fr1_sa_quectel_stages_162prb.xml
index 661bcb32fe0c5112cb437921dce8c79b38ec6cc0..9371e46ec9f5835a4490e19bfc2b5c5ad644c9b4 100644
--- a/ci-scripts/xml_files/fr1_sa_quectel_stages_162prb.xml
+++ b/ci-scripts/xml_files/fr1_sa_quectel_stages_162prb.xml
@@ -74,7 +74,7 @@
 		<eNB_Trace>yes</eNB_Trace>
 		<eNB_Stats>yes</eNB_Stats>
 		<rt_stats_cfg>datalog_rt_stats.2x2.yaml</rt_stats_cfg>
-		<USRP_IPAddress>192.168.18.252</USRP_IPAddress>
+		<USRP_IPAddress>172.21.19.14</USRP_IPAddress>
 	</testCase>
 
 	<testCase id="000001">
diff --git a/ci-scripts/xml_files/lte_2x2_tm1_quectel.xml b/ci-scripts/xml_files/lte_2x2_tm1_quectel.xml
index 11c4abce1b2f0edcf7bac36f34154fe4f2c63d2f..6aa53200c85ec8e484da718b6ae1dc8a25f5514d 100644
--- a/ci-scripts/xml_files/lte_2x2_tm1_quectel.xml
+++ b/ci-scripts/xml_files/lte_2x2_tm1_quectel.xml
@@ -65,7 +65,7 @@
 		<air_interface>lte</air_interface>
 		<eNB_Trace>yes</eNB_Trace>
 		<eNB_Stats>yes</eNB_Stats>
-		<USRP_IPAddress>192.168.18.241</USRP_IPAddress>
+		<USRP_IPAddress>172.21.19.13</USRP_IPAddress>
 	</testCase>
 
 
diff --git a/ci-scripts/xml_files/lte_2x2_tm2_quectel.xml b/ci-scripts/xml_files/lte_2x2_tm2_quectel.xml
index 714cf51a9b5641ed7118fe57a0aa0eb5ca4d079b..84aa87aa235eaaa28d220111c8157b77616106e0 100644
--- a/ci-scripts/xml_files/lte_2x2_tm2_quectel.xml
+++ b/ci-scripts/xml_files/lte_2x2_tm2_quectel.xml
@@ -65,7 +65,7 @@
 		<air_interface>lte</air_interface>
 		<eNB_Trace>yes</eNB_Trace>
 		<eNB_Stats>yes</eNB_Stats>
-		<USRP_IPAddress>192.168.18.241</USRP_IPAddress>
+		<USRP_IPAddress>172.21.19.13</USRP_IPAddress>
 	</testCase>
 
 
diff --git a/ci-scripts/xml_files/sa_cn5g_asue_closure.xml b/ci-scripts/xml_files/sa_cn5g_asue_closure.xml
new file mode 100644
index 0000000000000000000000000000000000000000..b856134e367cefbe9cc7080f22a613e4ef2d775c
--- /dev/null
+++ b/ci-scripts/xml_files/sa_cn5g_asue_closure.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>cn5g-closure</htmlTabRef>
+	<htmlTabName>CN5G-Closure</htmlTabName>
+	<htmlTabIcon>log-out</htmlTabIcon>
+	<TestCaseRequestedList>
+060000
+	</TestCaseRequestedList>
+	<TestCaseExclusionList></TestCaseExclusionList>
+
+	<testCase id="060000">
+		<class>Terminate_5GCN</class>
+		<desc>Terminate 5G Core</desc>
+		<args>--type stop-mini-as-ue --fqdn yes --scenario 1</args>
+	</testCase>
+
+</testCaseList>
diff --git a/ci-scripts/xml_files/sa_cn5g_asue_start.xml b/ci-scripts/xml_files/sa_cn5g_asue_start.xml
new file mode 100644
index 0000000000000000000000000000000000000000..740022b1c9c74b341d56bacef9ac8cb0c5368a13
--- /dev/null
+++ b/ci-scripts/xml_files/sa_cn5g_asue_start.xml
@@ -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
+
+-->
+<testCaseList>
+	<htmlTabRef>cn5g-start-tab</htmlTabRef>
+	<htmlTabName>CN5G-Start</htmlTabName>
+	<htmlTabIcon>log-in</htmlTabIcon>
+	<TestCaseRequestedList>
+ 000100
+	</TestCaseRequestedList>
+	<TestCaseExclusionList>
+	</TestCaseExclusionList>
+
+	<testCase id="000100">
+		<class>Initialize_5GCN</class>
+		<desc>Initialize 5G Core</desc>
+		<args>--type start-mini-as-ue --fqdn yes --scenario 1 --capture /tmp/oai-cn5g-v1.3.pcap</args>
+	</testCase>
+
+</testCaseList>
diff --git a/ci-scripts/yaml_files/4g_rfsimulator_fdd_05MHz/README.md b/ci-scripts/yaml_files/4g_rfsimulator_fdd_05MHz/README.md
index 400559d26988ec1dd5d04aee886ad89e225ba493..1a947d0389019f611701fc62405c39251186b972 100644
--- a/ci-scripts/yaml_files/4g_rfsimulator_fdd_05MHz/README.md
+++ b/ci-scripts/yaml_files/4g_rfsimulator_fdd_05MHz/README.md
@@ -31,9 +31,7 @@ This page is only valid for an `Ubuntu18` host.
 
 # 1. Retrieving the images on Docker-Hub #
 
-Currently the images are hosted under the user account `rdefosseoai`.
-
-This may change in the future.
+Currently the images are hosted under the team account `oaisoftwarealliance`. They were previously hosted under the user account `rdefosseoai`.
 
 Once again you may need to log on [docker-hub](https://hub.docker.com/) if your organization has reached pulling limit as `anonymous`.
 
@@ -49,13 +47,13 @@ Now pull images.
 ```bash
 $ docker pull cassandra:2.1
 $ docker pull redis:6.0.5
-$ docker pull rdefosseoai/oai-hss:latest
-$ docker pull rdefosseoai/magma-mme:latest
-$ docker pull rdefosseoai/oai-spgwc:latest
-$ docker pull rdefosseoai/oai-spgwu-tiny:latest
+$ docker pull oaisoftwarealliance/oai-hss:latest
+$ docker pull oaisoftwarealliance/magma-mme:latest
+$ docker pull oaisoftwarealliance/oai-spgwc:latest
+$ docker pull oaisoftwarealliance/oai-spgwu-tiny:latest
 
-$ docker pull rdefosseoai/oai-enb:develop
-$ docker pull rdefosseoai/oai-lte-ue:develop
+$ docker pull oaisoftwarealliance/oai-enb:develop
+$ docker pull oaisoftwarealliance/oai-lte-ue:develop
 ```
 
 If the `redis` tag is not available, pick the newest available `6.0.x` tag at [Docker Hub Redis Tags](https://hub.docker.com/_/redis?tab=tags).
@@ -63,13 +61,13 @@ If the `redis` tag is not available, pick the newest available `6.0.x` tag at [D
 And **re-tag** them for tutorials' docker-compose file to work.
 
 ```bash
-$ docker image tag rdefosseoai/oai-spgwc:latest oai-spgwc:latest
-$ docker image tag rdefosseoai/oai-hss:latest oai-hss:latest
-$ docker image tag rdefosseoai/oai-spgwu-tiny:latest oai-spgwu-tiny:latest 
-$ docker image tag rdefosseoai/magma-mme:latest magma-mme:latest
+$ docker image tag oaisoftwarealliance/oai-spgwc:latest oai-spgwc:latest
+$ docker image tag oaisoftwarealliance/oai-hss:latest oai-hss:latest
+$ docker image tag oaisoftwarealliance/oai-spgwu-tiny:latest oai-spgwu-tiny:latest 
+$ docker image tag oaisoftwarealliance/magma-mme:latest magma-mme:latest
 
-$ docker image tag rdefosseoai/oai-enb:develop oai-enb:develop
-$ docker image tag rdefosseoai/oai-lte-ue:develop oai-lte-ue:develop
+$ docker image tag oaisoftwarealliance/oai-enb:develop oai-enb:develop
+$ docker image tag oaisoftwarealliance/oai-lte-ue:develop oai-lte-ue:develop
 ```
 
 ```bash
@@ -505,7 +503,7 @@ In my traffic test, I was able to ping outside of my local network.
 in SPGW-C config:
 
 ```yaml
-            DEFAULT_DNS_IPV4_ADDRESS: 192.168.18.129
+            DEFAULT_DNS_IPV4_ADDRESS: 172.21.3.100
             DEFAULT_DNS_SEC_IPV4_ADDRESS: 8.8.4.4
             PUSH_PROTOCOL_OPTION: 'true'
 ```
diff --git a/ci-scripts/yaml_files/4g_rfsimulator_fdd_05MHz/docker-compose.yml b/ci-scripts/yaml_files/4g_rfsimulator_fdd_05MHz/docker-compose.yml
index b15e794c1026a11657e4c1deaa9ef2b75aace8c6..a260857a34d7a607929cac21dc6ac04f9ba6ee19 100644
--- a/ci-scripts/yaml_files/4g_rfsimulator_fdd_05MHz/docker-compose.yml
+++ b/ci-scripts/yaml_files/4g_rfsimulator_fdd_05MHz/docker-compose.yml
@@ -115,7 +115,7 @@ services:
             TZ: Europe/Paris
             SGW_INTERFACE_NAME_FOR_S11: eth0
             PGW_INTERFACE_NAME_FOR_SX: eth0
-            DEFAULT_DNS_IPV4_ADDRESS: 192.168.18.129
+            DEFAULT_DNS_IPV4_ADDRESS: 172.21.3.100
             DEFAULT_DNS_SEC_IPV4_ADDRESS: 8.8.4.4
             PUSH_PROTOCOL_OPTION: 'true'
             APN_NI_1: oai.ipv4
diff --git a/ci-scripts/yaml_files/4g_rfsimulator_fdd_10MHz/docker-compose.yml b/ci-scripts/yaml_files/4g_rfsimulator_fdd_10MHz/docker-compose.yml
index e1e992c94c2a668cdd4f9fd2ab0c1449f25d753f..3f63953b0e6c0287f434a250236d15cbb563bc76 100644
--- a/ci-scripts/yaml_files/4g_rfsimulator_fdd_10MHz/docker-compose.yml
+++ b/ci-scripts/yaml_files/4g_rfsimulator_fdd_10MHz/docker-compose.yml
@@ -115,7 +115,7 @@ services:
             TZ: Europe/Paris
             SGW_INTERFACE_NAME_FOR_S11: eth0
             PGW_INTERFACE_NAME_FOR_SX: eth0
-            DEFAULT_DNS_IPV4_ADDRESS: 192.168.18.129
+            DEFAULT_DNS_IPV4_ADDRESS: 172.21.3.100
             DEFAULT_DNS_SEC_IPV4_ADDRESS: 8.8.4.4
             PUSH_PROTOCOL_OPTION: 'true'
             APN_NI_1: oai.ipv4
diff --git a/ci-scripts/yaml_files/4g_rfsimulator_fdd_20MHz/docker-compose.yml b/ci-scripts/yaml_files/4g_rfsimulator_fdd_20MHz/docker-compose.yml
index ad665813f2a5bb1a956e7f7056dadf63bc7c4d5b..1165400273e7f542dcec56d88572cbb6c0c387fb 100644
--- a/ci-scripts/yaml_files/4g_rfsimulator_fdd_20MHz/docker-compose.yml
+++ b/ci-scripts/yaml_files/4g_rfsimulator_fdd_20MHz/docker-compose.yml
@@ -115,7 +115,7 @@ services:
             TZ: Europe/Paris
             SGW_INTERFACE_NAME_FOR_S11: eth0
             PGW_INTERFACE_NAME_FOR_SX: eth0
-            DEFAULT_DNS_IPV4_ADDRESS: 192.168.18.129
+            DEFAULT_DNS_IPV4_ADDRESS: 172.21.3.100
             DEFAULT_DNS_SEC_IPV4_ADDRESS: 8.8.4.4
             PUSH_PROTOCOL_OPTION: 'true'
             APN_NI_1: oai.ipv4
diff --git a/ci-scripts/yaml_files/4g_rfsimulator_tdd_05MHz/docker-compose.yml b/ci-scripts/yaml_files/4g_rfsimulator_tdd_05MHz/docker-compose.yml
index ffa92bac4907046960d4f7a4bcaa4af6b488dafe..86f6c80b5982da70e61c07c8d712a29366fd4798 100644
--- a/ci-scripts/yaml_files/4g_rfsimulator_tdd_05MHz/docker-compose.yml
+++ b/ci-scripts/yaml_files/4g_rfsimulator_tdd_05MHz/docker-compose.yml
@@ -115,7 +115,7 @@ services:
             TZ: Europe/Paris
             SGW_INTERFACE_NAME_FOR_S11: eth0
             PGW_INTERFACE_NAME_FOR_SX: eth0
-            DEFAULT_DNS_IPV4_ADDRESS: 192.168.18.129
+            DEFAULT_DNS_IPV4_ADDRESS: 172.21.3.100
             DEFAULT_DNS_SEC_IPV4_ADDRESS: 8.8.4.4
             PUSH_PROTOCOL_OPTION: 'true'
             APN_NI_1: oai.ipv4
diff --git a/ci-scripts/yaml_files/5g_f1_rfsimulator/docker-compose.yaml b/ci-scripts/yaml_files/5g_f1_rfsimulator/docker-compose.yaml
index 74a23905f0abc4e5258e3837d88c1ae410696732..d52b228ec67cfa2520a0fea396927da60d4fde06 100644
--- a/ci-scripts/yaml_files/5g_f1_rfsimulator/docker-compose.yaml
+++ b/ci-scripts/yaml_files/5g_f1_rfsimulator/docker-compose.yaml
@@ -120,7 +120,7 @@ services:
             - SMF_INTERFACE_PORT_FOR_SBI=80
             - SMF_INTERFACE_HTTP2_PORT_FOR_SBI=9090
             - SMF_API_VERSION=v1
-            - DEFAULT_DNS_IPV4_ADDRESS=192.168.18.129
+            - DEFAULT_DNS_IPV4_ADDRESS=172.21.3.100
             - DEFAULT_DNS_SEC_IPV4_ADDRESS=4.4.4.4
             - AMF_IPV4_ADDRESS=0.0.0.0
             - AMF_PORT=80
diff --git a/ci-scripts/yaml_files/5g_fdd_rfsimulator/docker-compose.yaml b/ci-scripts/yaml_files/5g_fdd_rfsimulator/docker-compose.yaml
index 3e46adb9e7eac397a66fc33fe194bddd7ebe2608..7758c395927f5c71c24ff9e761544e5bac005143 100644
--- a/ci-scripts/yaml_files/5g_fdd_rfsimulator/docker-compose.yaml
+++ b/ci-scripts/yaml_files/5g_fdd_rfsimulator/docker-compose.yaml
@@ -120,7 +120,7 @@ services:
             - SMF_INTERFACE_PORT_FOR_SBI=80
             - SMF_INTERFACE_HTTP2_PORT_FOR_SBI=9090
             - SMF_API_VERSION=v1
-            - DEFAULT_DNS_IPV4_ADDRESS=192.168.18.129
+            - DEFAULT_DNS_IPV4_ADDRESS=172.21.3.100
             - DEFAULT_DNS_SEC_IPV4_ADDRESS=4.4.4.4
             - AMF_IPV4_ADDRESS=0.0.0.0
             - AMF_PORT=80
diff --git a/ci-scripts/yaml_files/5g_l2sim_tdd/README.md b/ci-scripts/yaml_files/5g_l2sim_tdd/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..c3f631cf7682620a603ab2dba67ef0476bb43e5f
--- /dev/null
+++ b/ci-scripts/yaml_files/5g_l2sim_tdd/README.md
@@ -0,0 +1,353 @@
+<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="../../../doc/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">OAI Full Stack 5G-NR L2 simulation with containers and a proxy</font></b>
+    </td>
+  </tr>
+</table>
+
+This page is only valid for an `Ubuntu18` host.
+
+This tutorial is only valid once this file is merged into the `develop` branch.
+
+# 1. Retrieving the images on Docker-Hub #
+
+Currently the images are hosted under the team account `oaisoftwarealliance`. They were previously hosted under the user account `rdefosseoai`.
+
+Once again you may need to log on [docker-hub](https://hub.docker.com/) if your organization has reached pulling limit as `anonymous`.
+
+```bash
+$ docker login
+Login with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com to create one.
+Username:
+Password:
+```
+
+Now pull images.
+
+```bash
+$ docker pull mysql:5.7
+$ docker pull oaisoftwarealliance/oai-amf:latest
+$ docker pull oaisoftwarealliance/oai-nrf:latest
+$ docker pull oaisoftwarealliance/oai-smf:latest
+$ docker pull oaisoftwarealliance/oai-spgwu-tiny:latest
+
+$ docker pull oaisoftwarealliance/oai-gnb:develop
+$ docker pull oaisoftwarealliance/oai-nr-ue:develop
+$ docker pull oaisoftwarealliance/proxy:latest
+```
+
+And **re-tag** them for tutorials' docker-compose file to work.
+
+```bash
+$ docker image tag oaisoftwarealliance/oai-amf:latest oai-amf:latest
+$ docker image tag oaisoftwarealliance/oai-nrf:latest oai-nrf:latest
+$ docker image tag oaisoftwarealliance/oai-smf:latest oai-smf:latest
+$ docker image tag oaisoftwarealliance/oai-spgwu-tiny:latest oai-spgwu-tiny:latest
+
+$ docker image tag oaisoftwarealliance/oai-gnb:develop oai-gnb:develop
+$ docker image tag oaisoftwarealliance/oai-nr-ue:develop oai-nr-ue:develop
+$ docker image tag oaisoftwarealliance/proxy:latest oai-lte-multi-ue-proxy:latest
+```
+
+```bash
+$ docker logout
+```
+
+Note that the proxy image is based on the source available at [https://github.com/EpiSci/oai-lte-5g-multi-ue-proxy](https://github.com/EpiSci/oai-lte-5g-multi-ue-proxy).
+
+At time of writing, the `latest` tag corresponded to `56cfdc046a5f96d5e67d42a2fc2bf6ba2fe58b41` commit.
+
+# 2. Deploy containers #
+
+**CAUTION: this SHALL be done in multiple steps.**
+
+**Just `docker-compose up -d` WILL NOT WORK!**
+
+All the following commands **SHALL** be run from the `ci-scripts/yaml_files/5g_l2sim_tdd` folder.
+
+The `gNB`, `proxy` and `NR-UE` containers will be deployed in `host`-mode. It will use the host loopback interface to connect.
+
+```bash
+sudo ifconfig lo: 127.0.0.2 netmask 255.0.0.0 up
+```
+
+## 2.1. Deploy OAI 5G Core Network ##
+
+```bash
+$ cd ci-scripts/yaml_files/5g_l2sim_tdd
+$ docker-compose up -d mysql oai-nrf oai-amf oai-smf oai-spgwu oai-ext-dn
+Creating network "l2sim-oai-public-net" with driver "bridge"
+Creating network "l2sim-oai-traffic_net-net" with driver "bridge"
+Creating l2sim-oai-nrf ... done
+Creating l2sim-mysql      ... done
+Creating l2sim-oai-spgwu ... done
+Creating l2sim-oai-amf   ... done
+Creating l2sim-oai-smf   ... done
+Creating l2sim-oai-ext-dn ... done
+```
+
+Wait for a bit.
+
+```bash
+$ docker-compose ps -a
+       Name                     Command                  State                  Ports
+-------------------------------------------------------------------------------------------------
+l2sim-mysql        docker-entrypoint.sh mysqld      Up (healthy)   3306/tcp, 33060/tcp         
+l2sim-oai-amf      /bin/bash /openair-amf/bin ...   Up (healthy)   38412/sctp, 80/tcp, 9090/tcp
+l2sim-oai-ext-dn   /bin/bash -c  apt update;  ...   Up (healthy)                               
+l2sim-oai-nrf      /bin/bash /openair-nrf/bin ...   Up (healthy)   80/tcp, 9090/tcp            
+l2sim-oai-smf      /bin/bash /openair-smf/bin ...   Up (healthy)   80/tcp, 8805/udp, 9090/tcp  
+l2sim-oai-spgwu    /openair-spgwu-tiny/bin/en ...   Up (healthy)   2152/udp, 8805/udp          
+```
+
+At this point, you can prepare a capture on the newly-created public docker bridges:
+
+```bash
+$ ifconfig
+...
+l2sim-public: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
+        inet 192.168.71.129  netmask 255.255.255.192  broadcast 192.168.71.191
+        inet6 fe80::42:c4ff:fe2b:3d38  prefixlen 64  scopeid 0x20<link>
+        ether 02:42:c4:2b:3d:38  txqueuelen 0  (Ethernet)
+        RX packets 4  bytes 112 (112.0 B)
+        RX errors 0  dropped 0  overruns 0  frame 0
+        TX packets 7  bytes 626 (626.0 B)
+        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
+
+l2sim-traffic: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
+        inet 192.168.72.129  netmask 255.255.255.192  broadcast 192.168.72.191
+        inet6 fe80::42:b5ff:fed3:e732  prefixlen 64  scopeid 0x20<link>
+        ether 02:42:b5:d3:e7:32  txqueuelen 0  (Ethernet)
+        RX packets 2652  bytes 142335 (142.3 KB)
+        RX errors 0  dropped 0  overruns 0  frame 0
+        TX packets 3999  bytes 23367972 (23.3 MB)
+        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
+...
+
+$ sudo nohup tshark -f "(host 192.168.72.135 and icmp) or (not host 192.168.72.135 and not arp and not port 53 and not port 2152 and not port 2153)" -i l2sim-public -i l2sim-traffic -w /tmp/capture_5g_l2sim_tdd.pcap > /tmp/tshark.log 2>&1 &
+```
+
+## 2.2. Deploy OAI gNB in Standalone Mode as a VNF ##
+
+**CAUTION: To execute this 2nd step, the whole `CN5G` SHALL be in `healthy` state (especially the `mysql` container).**
+
+```bash
+$ docker-compose up -d oai-gnb
+l2sim-oai-nrf is up-to-date
+l2sim-oai-spgwu is up-to-date
+l2sim-oai-ext-dn is up-to-date
+Creating l2sim-oai-gnb ... done
+```
+
+Wait for a bit.
+
+```bash
+$ docker-compose ps -a
+       Name                     Command                  State                  Ports
+-------------------------------------------------------------------------------------------------
+l2sim-mysql        docker-entrypoint.sh mysqld      Up (healthy)   3306/tcp, 33060/tcp         
+l2sim-oai-amf      /bin/bash /openair-amf/bin ...   Up (healthy)   38412/sctp, 80/tcp, 9090/tcp
+l2sim-oai-ext-dn   /bin/bash -c  apt update;  ...   Up (healthy)                               
+l2sim-oai-gnb      /opt/oai-gnb/bin/entrypoin ...   Up (healthy)                               
+l2sim-oai-nrf      /bin/bash /openair-nrf/bin ...   Up (healthy)   80/tcp, 9090/tcp            
+l2sim-oai-smf      /bin/bash /openair-smf/bin ...   Up (healthy)   80/tcp, 8805/udp, 9090/tcp  
+l2sim-oai-spgwu    /openair-spgwu-tiny/bin/en ...   Up (healthy)   2152/udp, 8805/udp          
+```
+
+You can verify that the `gNB` is connected with the `AMF`:
+
+```bagh
+$ docker logs rfsim5g-oai-amf
+...
+[AMF] [amf_app] [info ] |----------------------------------------------------gNBs' information-------------------------------------------|
+[AMF] [amf_app] [info ] |    Index    |      Status      |       Global ID       |       gNB Name       |               PLMN             |
+[AMF] [amf_app] [info ] |      1      |    Connected     |         0x0       |         gnb-l2sim-vnf    |            208, 99             |
+[AMF] [amf_app] [info ] |----------------------------------------------------------------------------------------------------------------|
+...
+```
+
+## 2.3. Deploy OAI NR-UE and proxy
+
+```bash
+$ docker-compose up -d proxy oai-nr-ue0
+l2sim-mysql is up-to-date
+l2sim-oai-nrf is up-to-date
+l2sim-oai-amf is up-to-date
+l2sim-oai-smf is up-to-date
+l2sim-oai-spgwu is up-to-date
+l2sim-oai-ext-dn is up-to-date
+l2sim-oai-gnb is up-to-date
+Creating l2sim-oai-nr-ue ... done
+Creating l2sim-proxy ... done
+```
+
+Wait for a bit.
+
+```bash
+$ docker-compose ps -a
+       Name                     Command                  State                  Ports
+-------------------------------------------------------------------------------------------------
+l2sim-mysql        docker-entrypoint.sh mysqld      Up (healthy)   3306/tcp, 33060/tcp         
+l2sim-oai-amf      /bin/bash /openair-amf/bin ...   Up (healthy)   38412/sctp, 80/tcp, 9090/tcp
+l2sim-oai-ext-dn   /bin/bash -c  apt update;  ...   Up (healthy)                               
+l2sim-oai-gnb      /opt/oai-gnb/bin/entrypoin ...   Up (healthy)                               
+l2sim-oai-nr-ue0   /opt/oai-nr-ue/bin/entrypo ...   Up (healthy)                               
+l2sim-oai-nrf      /bin/bash /openair-nrf/bin ...   Up (healthy)   80/tcp, 9090/tcp            
+l2sim-oai-smf      /bin/bash /openair-smf/bin ...   Up (healthy)   80/tcp, 8805/udp, 9090/tcp  
+l2sim-oai-spgwu    /openair-spgwu-tiny/bin/en ...   Up (healthy)   2152/udp, 8805/udp          
+l2sim-proxy        /oai-lte-multi-ue-proxy/bi ...   Up (healthy)                               
+
+$ docker stats --no-stream --format "table {{.Container}}\t{{.CPUPerc}}	{{.MemUsage}}\t{{.MemPerc}}" l2sim-mysql l2sim-oai-amf l2sim-oai-ext-dn l2sim-oai-gnb l2sim-oai-nr-ue0 l2sim-oai-nrf l2sim-oai-smf l2sim-oai-spgwu l2sim-proxy
+CONTAINER          CPU %     MEM USAGE / LIMIT     MEM %
+l2sim-mysql        0.03%     206.7MiB / 62.54GiB   0.32%
+l2sim-oai-amf      4.05%     29.49MiB / 62.54GiB   0.05%
+l2sim-oai-ext-dn   0.00%     31.27MiB / 62.54GiB   0.05%
+l2sim-oai-gnb      1.29%     1.853GiB / 62.54GiB   2.96%
+l2sim-oai-nr-ue0   1.43%     350.8MiB / 62.54GiB   0.55%
+l2sim-oai-nrf      0.21%     9.105MiB / 62.54GiB   0.01%
+l2sim-oai-smf      3.24%     30.23MiB / 62.54GiB   0.05%
+l2sim-oai-spgwu    0.00%     11.78MiB / 62.54GiB   0.02%
+l2sim-proxy        6.97%     290.4MiB / 62.54GiB   0.45%
+```
+
+**CAUTION: As you can see the CPU usage is not that important compared to a 5G RF simulator equivalent.**
+
+But the CPU speed matters; I am running on a fast server:
+
+```bash
+$ lscpu
+Architecture:        x86_64
+CPU(s):              16
+...
+Model name:          Intel(R) Xeon(R) Silver 4215R CPU @ 3.20GHz
+```
+
+I tried on a slower server with more CPUs and it did not work:
+
+```bash
+oaici@orion:~$ lscpu
+Architecture:        x86_64
+CPU(s):              48
+...
+Model name:          Intel(R) Xeon(R) CPU E5-2658 v3 @ 2.20GHz
+```
+
+We will work on this issue.
+
+
+Making sure the OAI UE is connected:
+
+```bash
+$ docker exec -it l2sim-oai-nr-ue /bin/bash
+root@bb4d400a832d:/opt/oai-nr-ue# ifconfig
+eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
+        inet 192.168.71.137  netmask 255.255.255.192  broadcast 192.168.71.191
+        ether 02:42:c0:a8:47:89  txqueuelen 0  (Ethernet)
+        RX packets 224259  bytes 5821372018 (5.8 GB)
+        RX errors 0  dropped 0  overruns 0  frame 0
+        TX packets 235916  bytes 7848786376 (7.8 GB)
+        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
+
+lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
+        inet 127.0.0.1  netmask 255.0.0.0
+        loop  txqueuelen 1000  (Local Loopback)
+        RX packets 0  bytes 0 (0.0 B)
+        RX errors 0  dropped 0  overruns 0  frame 0
+        TX packets 0  bytes 0 (0.0 B)
+        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
+
+oaitun_ue1: flags=4305<UP,POINTOPOINT,RUNNING,NOARP,MULTICAST>  mtu 1500
+        inet 12.1.1.2  netmask 255.255.255.0  destination 12.1.1.2
+        unspec 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00  txqueuelen 500  (UNSPEC)
+        RX packets 0  bytes 0 (0.0 B)
+        RX errors 0  dropped 0  overruns 0  frame 0
+        TX packets 0  bytes 0 (0.0 B)
+        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
+```
+
+# 3. Check traffic #
+
+## 3.1. Check your Internet connectivity ##
+
+You can also check with the `ext-dn` container (IP address is `192.168.72.135` in docker-compose)
+
+```bash
+$ docker exec -it l2sim-oai-nr-ue /bin/bash
+root@bb4d400a832d# ping -I oaitun_ue1 -c 20 192.168.72.135
+PING 192.168.72.135 (192.168.72.135) from 12.1.1.2 oaitun_ue1: 56(84) bytes of data.
+64 bytes from 192.168.72.135: icmp_seq=1 ttl=63 time=65.1 ms
+64 bytes from 192.168.72.135: icmp_seq=2 ttl=63 time=74.2 ms
+...
+64 bytes from 192.168.72.135: icmp_seq=19 ttl=63 time=25.0 ms
+64 bytes from 192.168.72.135: icmp_seq=20 ttl=63 time=34.7 ms
+
+--- 192.168.72.135 ping statistics ---
+20 packets transmitted, 20 received, 0% packet loss, time 19025ms
+rtt min/avg/max/mdev = 16.413/120.639/209.673/57.159 ms
+```
+
+# 4. Un-deployment #
+
+```bash
+$ docker-compose down
+Stopping l2sim-oai-nr-ue2 ... done
+Stopping l2sim-oai-nr-ue  ... done
+Stopping l2sim-oai-gnb    ... done
+Stopping l2sim-oai-ext-dn ... done
+Stopping l2sim-oai-spgwu  ... done
+Stopping l2sim-oai-smf    ... done
+Stopping l2sim-oai-amf    ... done
+Stopping l2sim-oai-nrf    ... done
+Stopping l2sim-mysql      ... done
+Removing l2sim-oai-nr-ue2 ... done
+Removing l2sim-oai-nr-ue  ... done
+Removing l2sim-oai-gnb    ... done
+Removing l2sim-oai-ext-dn ... done
+Removing l2sim-oai-spgwu  ... done
+Removing l2sim-oai-smf    ... done
+Removing l2sim-oai-amf    ... done
+Removing l2sim-oai-nrf    ... done
+Removing l2sim-mysql      ... done
+Removing network l2sim-oai-public-net
+Removing network l2sim-oai-traffic-net
+```
+
+# 5. Adapt the `docker-compose` to your environment #
+
+In the `SMF` section, provide your own DNS IP address:
+
+```yaml
+            DEFAULT_DNS_IPV4_ADDRESS=172.21.3.100
+```
+
+In the `gNB` section, provide your docker-host primary IP address and interface name: in our case `172.21.16.128` and `eno1`.
+
+```yaml
+            GNB_NGA_IF_NAME: eno1
+            GNB_NGA_IP_ADDRESS: 172.21.16.128
+            GNB_NGU_IF_NAME: eno1
+            GNB_NGU_IP_ADDRESS: 172.21.16.128
+```
+
+Same thing in the `nr-ue` section:
+
+```yaml
+            NR_UE_NFAPI_IF_NAME: eno1
+```
+
+This tutorial is a first draft. This nFAPI feature and the proxy are still under development.
+
+At time of writing, we were able to run in `host-mode`, 1 `NR-UE` and just ping traffic.
+
+Later development will include:
+
+  -  deploying `gNB-VNF`, `proxy` and `UE` in isolated containers (with their own IP address)
+  -  more UEs
+  -  more traffic (`UDP` and `TCP`)
diff --git a/ci-scripts/yaml_files/5g_l2sim_tdd/docker-compose.yaml b/ci-scripts/yaml_files/5g_l2sim_tdd/docker-compose.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..a28b640e1a5d7a79bd6e226034726c1d2e6a7721
--- /dev/null
+++ b/ci-scripts/yaml_files/5g_l2sim_tdd/docker-compose.yaml
@@ -0,0 +1,322 @@
+version: '3.8'
+services:
+    oai-nrf:
+        container_name: "l2sim-oai-nrf"
+        image: oai-nrf:latest
+        environment:
+            - NRF_INTERFACE_NAME_FOR_SBI=eth0
+            - NRF_INTERFACE_PORT_FOR_SBI=80
+            - NRF_INTERFACE_HTTP2_PORT_FOR_SBI=9090
+            - NRF_API_VERSION=v1
+            - INSTANCE=0
+            - PID_DIRECTORY=/var/run
+        networks:
+            public_net:
+                ipv4_address: 192.168.71.130
+        volumes:
+            - ../5g_rfsimulator/nrf-healthcheck.sh:/openair-nrf/bin/nrf-healthcheck.sh
+        healthcheck:
+            test: /bin/bash -c "/openair-nrf/bin/nrf-healthcheck.sh"
+            interval: 10s
+            timeout: 5s
+            retries: 5
+    mysql:
+        container_name: "l2sim-mysql"
+        image: mysql:5.7
+        volumes:
+            - ../5g_rfsimulator/oai_db.sql:/docker-entrypoint-initdb.d/oai_db.sql
+            - ../5g_rfsimulator/mysql-healthcheck.sh:/tmp/mysql-healthcheck.sh
+        environment:
+            - TZ=Europe/Paris
+            - MYSQL_DATABASE=oai_db
+            - MYSQL_USER=test
+            - MYSQL_PASSWORD=test
+            - MYSQL_ROOT_PASSWORD=linux
+        healthcheck:
+            test: /bin/bash -c "/tmp/mysql-healthcheck.sh"
+            interval: 10s
+            timeout: 5s
+            retries: 5
+        networks:
+            public_net:
+                ipv4_address: 192.168.71.131
+    oai-amf:
+        container_name: "l2sim-oai-amf"
+        image: oai-amf:latest
+        environment:
+            - TZ=Europe/paris
+            - INSTANCE=0
+            - PID_DIRECTORY=/var/run
+            - MCC=208
+            - MNC=99
+            - REGION_ID=128
+            - AMF_SET_ID=1
+            - SERVED_GUAMI_MCC_0=208
+            - SERVED_GUAMI_MNC_0=99
+            - SERVED_GUAMI_REGION_ID_0=128
+            - SERVED_GUAMI_AMF_SET_ID_0=1
+            - SERVED_GUAMI_MCC_1=460
+            - SERVED_GUAMI_MNC_1=11
+            - SERVED_GUAMI_REGION_ID_1=10
+            - SERVED_GUAMI_AMF_SET_ID_1=1
+            - PLMN_SUPPORT_MCC=208
+            - PLMN_SUPPORT_MNC=99
+            - PLMN_SUPPORT_TAC=0x0001
+            - SST_0=1
+            - SD_0=1
+            - SST_1=1
+            - SD_1=12
+            - AMF_INTERFACE_NAME_FOR_NGAP=eth0
+            - AMF_INTERFACE_NAME_FOR_N11=eth0
+            - SMF_INSTANCE_ID_0=1
+            - SMF_FQDN_0=oai-smf
+            - SMF_IPV4_ADDR_0=0.0.0.0
+            - SMF_HTTP_VERSION_0=v1
+            - SELECTED_0=true
+            - SMF_INSTANCE_ID_1=2
+            - SMF_FQDN_1=oai-smf
+            - SMF_IPV4_ADDR_1=0.0.0.0
+            - SMF_HTTP_VERSION_1=v1
+            - SELECTED_1=false
+            - MYSQL_SERVER=192.168.71.131
+            - MYSQL_USER=root
+            - MYSQL_PASS=linux
+            - MYSQL_DB=oai_db
+            - OPERATOR_KEY=c42449363bbad02b66d16bc975d77cc1
+            - NRF_IPV4_ADDRESS=192.168.71.130
+            - NRF_PORT=80
+            - NF_REGISTRATION=yes
+            - SMF_SELECTION=yes
+            - USE_FQDN_DNS=yes
+            - NRF_API_VERSION=v1
+            - NRF_FQDN=oai-nrf
+            - EXTERNAL_AUSF=no
+            - AUSF_IPV4_ADDRESS=0.0.0.0
+            - AUSF_PORT=80
+            - AUSF_API_VERSION=v1
+            - AUSF_FQDN=localhost
+        depends_on:
+            - oai-nrf
+            - mysql
+        volumes:
+            - ../5g_rfsimulator/amf-healthcheck.sh:/openair-amf/bin/amf-healthcheck.sh
+        healthcheck:
+            test: /bin/bash -c "/openair-amf/bin/amf-healthcheck.sh"
+            interval: 10s
+            timeout: 15s
+            retries: 5
+        networks:
+            public_net:
+                ipv4_address: 192.168.71.132
+    oai-smf:
+        container_name: "l2sim-oai-smf"
+        image: oai-smf:latest
+        environment:
+            - TZ=Europe/Paris
+            - INSTANCE=0
+            - PID_DIRECTORY=/var/run
+            - SMF_INTERFACE_NAME_FOR_N4=eth0
+            - SMF_INTERFACE_NAME_FOR_SBI=eth0
+            - SMF_INTERFACE_PORT_FOR_SBI=80
+            - SMF_INTERFACE_HTTP2_PORT_FOR_SBI=9090
+            - SMF_API_VERSION=v1
+            - DEFAULT_DNS_IPV4_ADDRESS=172.21.3.100
+            - DEFAULT_DNS_SEC_IPV4_ADDRESS=4.4.4.4
+            - AMF_IPV4_ADDRESS=0.0.0.0
+            - AMF_PORT=80
+            - AMF_API_VERSION=v1
+            - AMF_FQDN=oai-amf
+            - UDM_IPV4_ADDRESS=127.0.0.1
+            - UDM_PORT=80
+            - UDM_API_VERSION=v1
+            - UDM_FQDN=localhost
+            - UPF_IPV4_ADDRESS=192.168.71.134
+            - UPF_FQDN_0=oai-spgwu
+            - NRF_IPV4_ADDRESS=192.168.71.130
+            - NRF_PORT=80
+            - NRF_API_VERSION=v1
+            - NRF_FQDN=oai-nrf
+            - REGISTER_NRF=yes
+            - DISCOVER_UPF=yes
+            - USE_FQDN_DNS=yes
+            - DNN_NI0=oai
+            - DNN_NI2=oai.ipv4
+        depends_on:
+            - oai-nrf
+            - oai-amf
+        volumes:
+            - ../5g_rfsimulator/smf-healthcheck.sh:/openair-smf/bin/smf-healthcheck.sh
+        healthcheck:
+            test: /bin/bash -c "/openair-smf/bin/smf-healthcheck.sh"
+            interval: 10s
+            timeout: 5s
+            retries: 5
+        networks:
+            public_net:
+                ipv4_address: 192.168.71.133
+    oai-spgwu:
+        container_name: "l2sim-oai-spgwu"
+        image: oai-spgwu-tiny:latest
+        environment:
+            - TZ=Europe/Paris
+            - PID_DIRECTORY=/var/run
+            - SGW_INTERFACE_NAME_FOR_S1U_S12_S4_UP=eth0
+            - SGW_INTERFACE_NAME_FOR_SX=eth0
+            - PGW_INTERFACE_NAME_FOR_SGI=eth0
+            - NETWORK_UE_NAT_OPTION=yes
+            - NETWORK_UE_IP=12.1.1.0/24
+            - SPGWC0_IP_ADDRESS=192.168.71.133
+            - BYPASS_UL_PFCP_RULES=no
+            - MCC=208
+            - MNC=99
+            - MNC03=099
+            - TAC=1
+            - GTP_EXTENSION_HEADER_PRESENT=yes
+            - GW_ID=1
+            - REALM=openairinterface.org
+            - ENABLE_5G_FEATURES=yes
+            - REGISTER_NRF=yes
+            - USE_FQDN_NRF=yes
+            - UPF_FQDN_5G=oai-spgwu
+            - NRF_IPV4_ADDRESS=192.168.71.130
+            - NRF_PORT=80
+            - NRF_API_VERSION=v1
+            - NRF_FQDN=oai-nrf
+            - NSSAI_SST_0=1
+            - NSSAI_SD_0=1
+            - DNN_0=oai
+        depends_on:
+            - oai-nrf
+            - oai-smf
+        cap_add:
+            - NET_ADMIN
+            - SYS_ADMIN
+        cap_drop:
+            - ALL
+        privileged: true
+        volumes:
+            - ../5g_rfsimulator/spgwu-healthcheck.sh:/openair-spgwu-tiny/bin/spgwu-healthcheck.sh
+        healthcheck:
+            test: /bin/bash -c "/openair-spgwu-tiny/bin/spgwu-healthcheck.sh"
+            interval: 10s
+            timeout: 5s
+            retries: 5
+        networks:
+            public_net:
+                ipv4_address: 192.168.71.134
+            traffic_net:
+                ipv4_address: 192.168.72.134
+    oai-ext-dn:
+        image: ubuntu:bionic
+        privileged: true
+        container_name: "l2sim-oai-ext-dn"
+        entrypoint: /bin/bash -c \
+              "apt update; apt install -y procps iptables iproute2 iperf iputils-ping;"\
+              "ip route add 12.1.1.0/24 via 192.168.72.134 dev eth0; sleep infinity"
+        depends_on:
+            - oai-spgwu
+        networks:
+            traffic_net:
+                ipv4_address: 192.168.72.135
+        healthcheck:
+            test: /bin/bash -c "ping -c 2 192.168.72.134"
+            interval: 10s
+            timeout: 5s
+            retries: 5
+    oai-gnb:
+        image: oai-gnb:develop
+        privileged: true
+        container_name: "l2sim-oai-gnb"
+        network_mode: "host"
+        environment:
+            TZ: Europe/Paris
+            USE_SA_NFAPI_VNF: 'yes'
+            GNB_NAME: gnb-l2sim-vnf
+            TAC: 1
+            MCC: '208'
+            MNC: '99'
+            MNC_LENGTH: 2
+            NSSAI_SST: 1
+            NSSAI_SD0: 1
+            NSSAI_SD1: 112233
+            AMF_IP_ADDRESS: 192.168.71.132
+            GNB_NGA_IF_NAME: eno1
+            GNB_NGA_IP_ADDRESS: 172.21.16.128
+            GNB_NGU_IF_NAME: eno1
+            GNB_NGU_IP_ADDRESS: 172.21.16.128
+            LOCAL_S_IF_NAME: 'lo:'
+            REMOTE_S_ADDRESS: 127.0.0.1
+            LOCAL_S_ADDRESS: 127.0.0.2
+            USE_ADDITIONAL_OPTIONS: --sa --nfapi 2 --emulate-l1 --log_config.global_log_options level,time,thread_id,nocolor
+        depends_on:
+            - oai-spgwu
+            - oai-amf
+        healthcheck:
+            test: /bin/bash -c "pgrep nr-softmodem"
+            interval: 10s
+            timeout: 5s
+            retries: 5
+
+    proxy:
+        image: oai-lte-multi-ue-proxy:latest
+        privileged: true
+        container_name: "l2sim-proxy"
+        network_mode: "host"
+        environment:
+            TZ: Europe/Paris
+        command: "/oai-lte-multi-ue-proxy/bin/proxy 1 --nr"
+        depends_on:
+            - oai-gnb
+        healthcheck:
+            test: /bin/bash -c "pgrep proxy"
+            interval: 10s
+            timeout: 5s
+            retries: 5
+
+    oai-nr-ue0:
+        image: oai-nr-ue:develop
+        privileged: true
+        container_name: "l2sim-oai-nr-ue0"
+        network_mode: "host"
+        environment:
+            TZ: Europe/Paris
+            USE_NFAPI: 'yes'
+            OPENAIR_DIR: /opt/oai-nr-ue
+            FULL_IMSI: '208990100001100'
+            FULL_KEY: 'fec86ba6eb707ed08905757b1bb44b8f'
+            OPC: 'C42449363BBAD02B66D16BC975D77CC1'
+            DNN: oai
+            NSSAI_SST: 1
+            NSSAI_SD: 1
+            NR_UE_NFAPI_IF_NAME: eno1
+            GNB_IP_ADDRESS: 127.0.0.1
+            NR_UE_IP_ADDRESS: 127.0.0.1
+            USE_ADDITIONAL_OPTIONS: --nokrnmod 1  --nfapi 5 --node-number 2 --sa --emulate-l1 --log_config.global_log_options level,time,thread_id,nocolor
+        volumes:
+            - ../../../openair1/SIMULATION/LTE_PHY/BLER_SIMULATIONS/AWGN/AWGN_results:/opt/oai-nr-ue/openair1/SIMULATION/LTE_PHY/BLER_SIMULATIONS/AWGN/AWGN_results
+        depends_on:
+            - oai-gnb
+            - proxy
+        healthcheck:
+            test: /bin/bash -c "pgrep nr-uesoftmodem"
+            interval: 10s
+            timeout: 5s
+            retries: 5
+
+networks:
+    public_net:
+        driver: bridge
+        name: l2sim-oai-public-net
+        ipam:
+            config:
+                - subnet: 192.168.71.128/26
+        driver_opts:
+            com.docker.network.bridge.name: "l2sim-public"
+    traffic_net:
+        driver: bridge
+        name: l2sim-oai-traffic-net
+        ipam:
+            config:
+                - subnet: 192.168.72.128/26
+        driver_opts:
+            com.docker.network.bridge.name: "l2sim-traffic"
diff --git a/ci-scripts/yaml_files/5g_rfsimulator/README.md b/ci-scripts/yaml_files/5g_rfsimulator/README.md
index 64c9084500ce58c964875b8ad78313cb0506cab4..aa185717765e5f63b5b734ac24d864790e3c5351 100644
--- a/ci-scripts/yaml_files/5g_rfsimulator/README.md
+++ b/ci-scripts/yaml_files/5g_rfsimulator/README.md
@@ -35,9 +35,7 @@ This page is only valid for an `Ubuntu18` host.
 
 # 1. Retrieving the images on Docker-Hub #
 
-Currently the images are hosted under the user account `rdefosseoai`.
-
-This may change in the future.
+Currently the images are hosted under the team account `oaisoftwarealliance`. They were previously hosted under the user account `rdefosseoai`.
 
 Once again you may need to log on [docker-hub](https://hub.docker.com/) if your organization has reached pulling limit as `anonymous`.
 
@@ -52,25 +50,25 @@ Now pull images.
 
 ```bash
 $ docker pull mysql:5.7
-$ docker pull rdefosseoai/oai-amf:latest
-$ docker pull rdefosseoai/oai-nrf:latest
-$ docker pull rdefosseoai/oai-smf:latest
-$ docker pull rdefosseoai/oai-spgwu-tiny:latest
+$ docker pull oaisoftwarealliance/oai-amf:latest
+$ docker pull oaisoftwarealliance/oai-nrf:latest
+$ docker pull oaisoftwarealliance/oai-smf:latest
+$ docker pull oaisoftwarealliance/oai-spgwu-tiny:latest
 
-$ docker pull rdefosseoai/oai-gnb:develop
-$ docker pull rdefosseoai/oai-nr-ue:develop
+$ docker pull oaisoftwarealliance/oai-gnb:develop
+$ docker pull oaisoftwarealliance/oai-nr-ue:develop
 ```
 
 And **re-tag** them for tutorials' docker-compose file to work.
 
 ```bash
-$ docker image tag rdefosseoai/oai-amf:latest oai-amf:latest
-$ docker image tag rdefosseoai/oai-nrf:latest oai-nrf:latest
-$ docker image tag rdefosseoai/oai-smf:latest oai-smf:latest
-$ docker image tag rdefosseoai/oai-spgwu-tiny:latest oai-spgwu-tiny:latest
+$ docker image tag oaisoftwarealliance/oai-amf:latest oai-amf:latest
+$ docker image tag oaisoftwarealliance/oai-nrf:latest oai-nrf:latest
+$ docker image tag oaisoftwarealliance/oai-smf:latest oai-smf:latest
+$ docker image tag oaisoftwarealliance/oai-spgwu-tiny:latest oai-spgwu-tiny:latest
 
-$ docker image tag rdefosseoai/oai-gnb:develop oai-gnb:develop
-$ docker image tag rdefosseoai/oai-nr-ue:develop oai-nr-ue:develop
+$ docker image tag oaisoftwarealliance/oai-gnb:develop oai-gnb:develop
+$ docker image tag oaisoftwarealliance/oai-nr-ue:develop oai-nr-ue:develop
 ```
 
 ```bash
diff --git a/ci-scripts/yaml_files/5g_rfsimulator/docker-compose.yaml b/ci-scripts/yaml_files/5g_rfsimulator/docker-compose.yaml
index f27ec3050dc2116faf97f28d4e25f64abb8fcf02..696d8c66989da277c7ed3b3378f40978b1ef546c 100644
--- a/ci-scripts/yaml_files/5g_rfsimulator/docker-compose.yaml
+++ b/ci-scripts/yaml_files/5g_rfsimulator/docker-compose.yaml
@@ -120,7 +120,7 @@ services:
             - SMF_INTERFACE_PORT_FOR_SBI=80
             - SMF_INTERFACE_HTTP2_PORT_FOR_SBI=9090
             - SMF_API_VERSION=v1
-            - DEFAULT_DNS_IPV4_ADDRESS=192.168.18.129
+            - DEFAULT_DNS_IPV4_ADDRESS=172.21.3.100
             - DEFAULT_DNS_SEC_IPV4_ADDRESS=4.4.4.4
             - AMF_IPV4_ADDRESS=0.0.0.0
             - AMF_PORT=80
diff --git a/ci-scripts/yaml_files/fr1_epc_20897/docker-compose.yml b/ci-scripts/yaml_files/fr1_epc_20897/docker-compose.yml
index a3675dc78e10366cf72c794a7832e2701082f119..91d15b52514738d31e19fa5e280132cb6846fcfa 100644
--- a/ci-scripts/yaml_files/fr1_epc_20897/docker-compose.yml
+++ b/ci-scripts/yaml_files/fr1_epc_20897/docker-compose.yml
@@ -132,7 +132,7 @@ services:
             TZ: Europe/Paris
             SGW_INTERFACE_NAME_FOR_S11: eth0
             PGW_INTERFACE_NAME_FOR_SX: eth0
-            DEFAULT_DNS_IPV4_ADDRESS: 192.168.18.129
+            DEFAULT_DNS_IPV4_ADDRESS: 172.21.3.100
             DEFAULT_DNS_SEC_IPV4_ADDRESS: 8.8.4.4
             PUSH_PROTOCOL_OPTION: 'true'
             APN_NI_1: oai.ipv4
diff --git a/ci-scripts/yaml_files/magma_nsa_20897/docker-compose.yml b/ci-scripts/yaml_files/magma_nsa_20897/docker-compose.yml
index df14e900e75859a1f001719a5f207badb653101b..f320e7e3df792f4431e6f42dfeb2556f3dbc49f9 100644
--- a/ci-scripts/yaml_files/magma_nsa_20897/docker-compose.yml
+++ b/ci-scripts/yaml_files/magma_nsa_20897/docker-compose.yml
@@ -116,7 +116,7 @@ services:
             TZ: Europe/Paris
             SGW_INTERFACE_NAME_FOR_S11: eth0
             PGW_INTERFACE_NAME_FOR_SX: eth0
-            DEFAULT_DNS_IPV4_ADDRESS: 192.168.18.129
+            DEFAULT_DNS_IPV4_ADDRESS: 172.21.3.100
             DEFAULT_DNS_SEC_IPV4_ADDRESS: 8.8.4.4
             PUSH_PROTOCOL_OPTION: 'true'
             APN_NI_1: oai.ipv4
diff --git a/ci-scripts/yaml_files/nsa_b200_enb/docker-compose.yml b/ci-scripts/yaml_files/nsa_b200_enb/docker-compose.yml
index 92ccdf8a0ac3fe0e2251ad62e23177f2e060c533..2df5eac61bce953406b081cfe582f534136bfc2e 100644
--- a/ci-scripts/yaml_files/nsa_b200_enb/docker-compose.yml
+++ b/ci-scripts/yaml_files/nsa_b200_enb/docker-compose.yml
@@ -20,7 +20,7 @@ services:
             NB_PRB: 25
             ENABLE_MEASUREMENT_REPORTS: 'yes'
             ENABLE_X2: 'yes'
-            MME_S1C_IP_ADDRESS: 192.168.18.210
+            MME_S1C_IP_ADDRESS: 172.21.16.136
             ENB_S1C_IF_NAME: eth0
             ENB_S1C_IP_ADDRESS: 192.168.68.130
             ENB_S1U_IF_NAME: eth0
@@ -29,7 +29,7 @@ services:
             RRC_INACTIVITY_THRESHOLD: 0
             FLEXRAN_ENABLED: 'no'
             FLEXRAN_INTERFACE_NAME: eth0
-            FLEXRAN_IPV4_ADDRESS: 192.168.18.210
+            FLEXRAN_IPV4_ADDRESS: 172.21.16.136
             THREAD_PARALLEL_CONFIG: PARALLEL_SINGLE_THREAD
             USE_ADDITIONAL_OPTIONS: --log_config.global_log_options level,nocolor,time,line_num,function
         volumes:
diff --git a/ci-scripts/yaml_files/nsa_b200_gnb/docker-compose.yml b/ci-scripts/yaml_files/nsa_b200_gnb/docker-compose.yml
index c6096956a87ec2105ea7b341ae130fef0233d686..208e1564cd41189f52e677d4516a3a467a94b504 100644
--- a/ci-scripts/yaml_files/nsa_b200_gnb/docker-compose.yml
+++ b/ci-scripts/yaml_files/nsa_b200_gnb/docker-compose.yml
@@ -15,7 +15,7 @@ services:
             TAC: 1
             ENABLE_X2: 'yes'
             ENB_X2_IP_ADDRESS: 192.168.68.130
-            MME_S1C_IP_ADDRESS: 192.168.18.210
+            MME_S1C_IP_ADDRESS: 172.21.16.136
             GNB_S1C_IF_NAME: eth0
             GNB_S1C_IP_ADDRESS: 192.168.68.194
             GNB_S1U_IF_NAME: eth0
@@ -24,9 +24,9 @@ services:
             RRC_INACTIVITY_THRESHOLD: 0
             FLEXRAN_ENABLED: 'no'
             FLEXRAN_INTERFACE_NAME: eth0
-            FLEXRAN_IPV4_ADDRESS: 192.168.18.210
+            FLEXRAN_IPV4_ADDRESS: 172.21.16.136
             THREAD_PARALLEL_CONFIG: PARALLEL_RU_L1_TRX_SPLIT
-            USE_ADDITIONAL_OPTIONS: -E -q --RUs.[0].sdr_addrs serial=30C51D4 --log_config.global_log_options level,nocolor,time,line_num,function
+            USE_ADDITIONAL_OPTIONS: -E -q --RUs.[0].sdr_addrs serial=30C51D4 --continuous-tx --log_config.global_log_options level,nocolor,time,line_num,function
         volumes:
             - /dev:/dev
         networks:
diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt
index 721f78ecebf834b3d0447cee643f487aab1db9d0..80c0408e1398821f09275f7909eef8ba68295dee 100644
--- a/cmake_targets/CMakeLists.txt
+++ b/cmake_targets/CMakeLists.txt
@@ -1781,7 +1781,8 @@ set(NR_PDCP_SRC
   )
 
 set(NR_SDAP_SRC
-  ${OPENAIR2_DIR}/SDAP/nr_sdap/nr_sdap_gnb.c
+  ${OPENAIR2_DIR}/SDAP/nr_sdap/nr_sdap.c
+  ${OPENAIR2_DIR}/SDAP/nr_sdap/nr_sdap_entity.c
   )
   
 set(L2_SRC
@@ -1867,6 +1868,7 @@ set(NR_L2_SRC_UE
   ${NR_RRC_DIR}/nr_rrc_config.c
   ${NR_UE_RRC_DIR}/rrc_UE.c
   ${NR_UE_RRC_DIR}/rrc_nsa.c
+  ${NR_RRC_DIR}/nr_rrc_config.c
   )
 
 set (MAC_SRC
diff --git a/cmake_targets/autotests/test_case_list.xml b/cmake_targets/autotests/test_case_list.xml
index ce1b9dcdf4981b968de86b36245fcfd47d5044f5..b55228bdc925b76486e8a8f689225b9c06e4754f 100755
--- a/cmake_targets/autotests/test_case_list.xml
+++ b/cmake_targets/autotests/test_case_list.xml
@@ -1093,7 +1093,7 @@
                                  (Test8: 217 PRB 100 PDSCH-PRBs 110 PDSCH-Offset),
                                  (Test9: 106 PRBs 50 PDSCH-PRBs MCS Index 27),
                                  (Test10: 106 PRBs 50 PDSCH-PRBs MCS Index 16),
-                                 (Test11: 106 MCS-TABLE 256 QAM MCS Index 27),
+                                 (Test11: 106 MCS-TABLE 256 QAM MCS Index 26),
                                  (Test12: HARQ test 25% TP 4 rounds),
                                  (Test13: HARQ test 33% TP 3 rounds),
                                  (Test14: HARQ test 50% TP 2 rounds),
@@ -1121,7 +1121,7 @@
                   -n100 -R217 -a110 -s5 -b100
                   -n100 -e27 -s30
                   -n100 -e16 -s10
-                  -n100 -q1 -e27 -s30
+                  -n100 -q1 -e26 -s30
                   -n100 -s1 -t25
                   -n100 -s1 -t33
                   -n100 -s1 -t50
diff --git a/cmake_targets/phy_simulators b/cmake_targets/phy_simulators
deleted file mode 120000
index 2a12e92f3e9e3938cd869184ab1b8d3f78aa1240..0000000000000000000000000000000000000000
--- a/cmake_targets/phy_simulators
+++ /dev/null
@@ -1 +0,0 @@
-ran_build/
\ No newline at end of file
diff --git a/common/utils/LOG/log.c b/common/utils/LOG/log.c
index 5b047c082d057b2bcd795a7d9c98084b5ad34fd3..8be35680342b8ff7793af73607bab9efded6c5f7 100644
--- a/common/utils/LOG/log.c
+++ b/common/utils/LOG/log.c
@@ -478,6 +478,7 @@ int logInit (void)
   register_log_component("NAS","log",NAS);
   register_log_component("UDP","",UDP_);
   register_log_component("GTPU","",GTPU);
+  register_log_component("SDAP","",SDAP);
   register_log_component("S1AP","",S1AP);
   register_log_component("F1AP","",F1AP);
   register_log_component("M2AP","",M2AP);
diff --git a/common/utils/LOG/log.h b/common/utils/LOG/log.h
index 1fbf42f62d43c02952ffcc487acc00636fc8f735..89b9c5e94d258e4662920f7a2cdf01505dcb62d4 100644
--- a/common/utils/LOG/log.h
+++ b/common/utils/LOG/log.h
@@ -215,6 +215,7 @@ typedef enum {
   OCM,
   UDP_,
   GTPU,
+  SDAP,
   SPGW,
   S1AP,
   F1AP,
diff --git a/common/utils/T/T_messages.txt b/common/utils/T/T_messages.txt
index a8b919e5252459e007c696744515a42ef7ac7e9c..b3c06d6be8a195ea81dba9748fd96ee1a9cf839c 100644
--- a/common/utils/T/T_messages.txt
+++ b/common/utils/T/T_messages.txt
@@ -944,6 +944,27 @@ ID = LEGACY_GTPU_TRACE
     GROUP = ALL:LEGACY_GTPU:LEGACY_GROUP_TRACE:LEGACY
     FORMAT = string,log
 
+ID = LEGACY_SDAP_INFO
+    DESC = SDAP legacy logs - info level
+    GROUP = ALL:LEGACY_SDAP:LEGACY_GROUP_INFO:LEGACY
+    FORMAT = string,log
+ID = LEGACY_SDAP_ERROR
+    DESC = SDAP legacy logs - error level
+    GROUP = ALL:LEGACY_SDAP:LEGACY_GROUP_ERROR:LEGACY
+    FORMAT = string,log
+ID = LEGACY_SDAP_WARNING
+    DESC = SDAP legacy logs - warning level
+    GROUP = ALL:LEGACY_SDAP:LEGACY_GROUP_WARNING:LEGACY
+    FORMAT = string,log
+ID = LEGACY_SDAP_DEBUG
+    DESC = SDAP legacy logs - debug level
+    GROUP = ALL:LEGACY_SDAP:LEGACY_GROUP_DEBUG:LEGACY
+    FORMAT = string,log
+ID = LEGACY_SDAP_TRACE
+    DESC = SDAP legacy logs - trace level
+    GROUP = ALL:LEGACY_SDAP:LEGACY_GROUP_TRACE:LEGACY
+    FORMAT = string,log
+
 ID = LEGACY_TMR_INFO
     DESC = TMR legacy logs - info level
     GROUP = ALL:LEGACY_TMR:LEGACY_GROUP_INFO:LEGACY
diff --git a/common/utils/assertions.h b/common/utils/assertions.h
index 573036b1d949e23730cb15cc44d46e3023305d9f..c8959d0adb15b0bbc4478cde7a162851361432eb 100644
--- a/common/utils/assertions.h
+++ b/common/utils/assertions.h
@@ -44,9 +44,9 @@
 #define _Assert_(cOND, aCTION, fORMAT, aRGS...)             \
 do {                                                        \
     if (!(cOND)) {                                          \
-        fprintf(stderr, "\nAssertion ("#cOND") failed!\n"   \
+        fprintf(stderr, "\nAssertion (%s) failed!\n"   \
                 "In %s() %s:%d\n" fORMAT,                   \
-                __FUNCTION__, __FILE__, __LINE__, ##aRGS);  \
+                #cOND, __FUNCTION__, __FILE__, __LINE__, ##aRGS);  \
         aCTION;                                             \
     }						\
 } while(0)
diff --git a/common/utils/lte/ue_power.c b/common/utils/lte/ue_power.c
index b377abf2ff91719f1d4107902c4ce5ba6912fe8a..aaa2826275fb1643c4d513929e29260034d390de 100644
--- a/common/utils/lte/ue_power.c
+++ b/common/utils/lte/ue_power.c
@@ -33,10 +33,8 @@
 #include <stdint.h>
 #include <stdio.h>
 #include "PHY/defs_eNB.h"
-#include "PHY/TOOLS/dB_routines.h"
-
-extern int16_t hundred_times_delta_TF[100];
-extern uint16_t hundred_times_log10_NPRB[100];
+#include <openair1/PHY/TOOLS/tools_defs.h>
+#include <openair1/SCHED/sched_common_extern.h>
 
 int16_t estimate_ue_tx_power(int norm,uint32_t tbs, uint32_t nb_rb, uint8_t control_only, int ncp, uint8_t use_srs)
 {
diff --git a/common/utils/nr/nr_common.c b/common/utils/nr/nr_common.c
index 49743b3bdc8f82f1795d721fae4d35fc2c1e077a..0aeeaf3afdd497fce65eaba91d5c0c14408a7990 100644
--- a/common/utils/nr/nr_common.c
+++ b/common/utils/nr/nr_common.c
@@ -336,9 +336,9 @@ int get_dmrs_port(int nl, uint16_t dmrs_ports) {
   return p;
 }
 
-lte_frame_type_t get_frame_type(uint16_t current_band, uint8_t scs_index)
+frame_type_t get_frame_type(uint16_t current_band, uint8_t scs_index)
 {
-  lte_frame_type_t current_type;
+  frame_type_t current_type;
   int32_t delta_duplex = get_delta_duplex(current_band, scs_index);
 
   if (delta_duplex == 0)
diff --git a/common/utils/nr/nr_common.h b/common/utils/nr/nr_common.h
index 0150cf59f8b7edf983edfea180628d0a2d187611..a09532a56523cfd5cdcd0ce05865294da4b3b8d5 100644
--- a/common/utils/nr/nr_common.h
+++ b/common/utils/nr/nr_common.h
@@ -63,7 +63,7 @@ void get_coreset_rballoc(uint8_t *FreqDomainResource,int *n_rb,int *rb_offset);
 uint16_t config_bandwidth(int mu, int nb_rb, int nr_band);
 int get_nr_table_idx(int nr_bandP, uint8_t scs_index);
 int32_t get_delta_duplex(int nr_bandP, uint8_t scs_index);
-lte_frame_type_t get_frame_type(uint16_t nr_bandP, uint8_t scs_index);
+frame_type_t get_frame_type(uint16_t nr_bandP, uint8_t scs_index);
 uint16_t get_band(uint64_t downlink_frequency, int32_t delta_duplex);
 int NRRIV2BW(int locationAndBandwidth,int N_RB);
 int NRRIV2PRBOFFSET(int locationAndBandwidth,int N_RB);
diff --git a/doc/FEATURE_SET.md b/doc/FEATURE_SET.md
index eaa691d6ef07142ba399cb1e308b7b9926183c3a..a289c6d17eb491005f037b05f8037e72d9b606c8 100644
--- a/doc/FEATURE_SET.md
+++ b/doc/FEATURE_SET.md
@@ -351,6 +351,14 @@ The following features are valid for the gNB and the 5G-NR UE.
   - Interfaces with RRC, RLC 
   - Interfaces with gtp-u (data Tx/Rx over N3 and F1-U interfaces)
 
+**gNB SDAP**
+- Send/Receive operations according to 37.324 Rel.15
+  - Establishment/Handling of SDAP entities.
+  - Transfer of User Plane Data
+  - Mapping between a QoS flow and a DRB for both DL and UL
+  - Marking QoS flow ID in both DL and UL packets
+  - Reflective QoS flow to DRB mapping for UL SDAP data PDUs
+
 **gNB RRC**
 - NR RRC (38.331) Rel 16 messages using new asn1c 
 - LTE RRC (36.331) also updated to Rel 15 
@@ -400,6 +408,7 @@ The following features are valid for the gNB and the 5G-NR UE.
 - New gtp-u implementation supporting both N3 and F1-U interfaces according to 29.281 Rel.15
   - Interfaces with RRC, F1AP for tunnel creation
   - Interfaces with PDCP and RLC for data send/receive at the CU and DU respectively (F1-U interface)
+  - Interface with SDAP for data send/receive, capture of GTP-U Optional Header, GTP-U Extension Header and PDU Session Container.
 
 # OpenAirInterface 5G-NR UE Feature Set #
 
@@ -502,6 +511,13 @@ The following features are valid for the gNB and the 5G-NR UE.
    - Radio bearer establishment/handling and association with PDCP entities
    - Interfaces with RRC, RLC 
 
+**UE SDAP**
+*  Tx/Rx operations operations according to 37.324 Rel.15
+  - Establishment/Handling of SDAP entities.
+  - Transfer of User Plane Data
+  - Reflective Mapping
+  - RRC Signaling Mapping
+
 **UE RRC**
 * Integration of RRC messages and procedures supporting UE 5G SA connection according to 38.331 Rel.16 
    - RRCSetupRequest/RRCSetup/RRCSetupComplete
diff --git a/doc/L2NFAPI.md b/doc/L2NFAPI.md
index 5b8c0f546cf1c1e323e0004d7e85029d355fc1ba..77f9e5cb783ccae80805fb937be918138d2e98e5 100644
--- a/doc/L2NFAPI.md
+++ b/doc/L2NFAPI.md
@@ -46,6 +46,8 @@ This proxy allows to perform L2 nFAPI simulator for:
 * 5G-NSA
 * 5G-SA
 
+Another tutorial for 5G SA mode with 1 User is available [here](../ci-scripts/yaml_files/5g_l2sim_tdd/README.md).
+
 ----
 
 [oai wiki home](https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/home)
diff --git a/doc/TESTING_5GSA_setup.md b/doc/TESTING_5GSA_setup.md
index f8c85bf2ca51f012ed578fd99cf145d12f6b649c..9b27549df438ffda963222e04c23435aecbba53c 100644
--- a/doc/TESTING_5GSA_setup.md
+++ b/doc/TESTING_5GSA_setup.md
@@ -36,6 +36,8 @@ At the moment of writing this document interoperability with the following COTS
  - [Quectel RM500Q-GL](https://www.quectel.com/product/5g-rm500q-gl/)
  - [Simcom SIMCOM8200EA](https://www.simcom.com/product/SIM8200EA_M2.html)
  - Huawei Mate 30 Pro
+ - Oneplus 8
+ - Google Pixel 5
 
  End-to-end control plane signaling to achieve a 5G SA connection, UE registration and PDU session establishment with the CN, as well as some basic user-plane traffic tests have been validated so far using SIMCOM/Quectel modules and Huawei Mate 30 pro. In terms of interoperability with different 5G Core Networks, so far this setup has been tested with:
  
diff --git a/docker/Dockerfile.nrUE.rhel8.2 b/docker/Dockerfile.nrUE.rhel8.2
index 498e6bedcf09085dbd88fb4e902b64cfe0750a69..dfb28cfd1d78e48b2affee2a2e1bb682d7d17308 100644
--- a/docker/Dockerfile.nrUE.rhel8.2
+++ b/docker/Dockerfile.nrUE.rhel8.2
@@ -29,7 +29,8 @@ FROM ran-base:latest AS nr-ue-base
 
 FROM ran-build:latest AS nr-ue-build 
 
-RUN cp /oai-ran/docker/scripts/nr_ue_entrypoint.sh /oai-ran/docker/scripts/entrypoint.sh
+RUN python3 ./docker/scripts/generateTemplate.py ./docker/scripts/nr_ue_parameters.yaml && \
+    cp /oai-ran/docker/scripts/nr_ue_entrypoint.sh /oai-ran/docker/scripts/entrypoint.sh
 
 #start from scratch for target executable
 FROM registry.access.redhat.com/ubi8/ubi:latest as oai-nr-ue
@@ -62,7 +63,10 @@ COPY --from=nr-ue-build \
     ./
 
 WORKDIR /opt/oai-nr-ue/etc
-COPY --from=nr-ue-build /oai-ran/ci-scripts/conf_files/nr-ue-sim.conf .
+COPY --from=nr-ue-build \
+    /oai-ran/ci-scripts/conf_files/nr-ue-sim.conf \
+    /oai-ran/docker/etc/nr-ue.nfapi.conf \
+    ./
 
 COPY --from=nr-ue-build \
     /oai-ran/cmake_targets/ran_build/build/liboai_eth_transpro.so \
@@ -118,5 +122,5 @@ WORKDIR /opt/oai-nr-ue/etc
 COPY --from=nr-ue-build /oai-ran/ci-scripts/conf_files/ue.* .
 
 WORKDIR /opt/oai-nr-ue
-CMD ["/opt/oai-nr-ue/bin/nr-uesoftmodem.Rel15", "-O", "/opt/oai-nr-ue/etc/nr-ue-sim.conf"]
+CMD ["/opt/oai-nr-ue/bin/nr-uesoftmodem.Rel15", "-O", "/opt/oai-nr-ue/etc/nr-ue.conf"]
 ENTRYPOINT ["/opt/oai-nr-ue/bin/entrypoint.sh"]
diff --git a/docker/Dockerfile.nrUE.ubuntu18 b/docker/Dockerfile.nrUE.ubuntu18
index 0edfdd21605f4498aa3007ae8acec4b1153e9317..9f68b947cd10d1a9324b2c2ba9e2b1d210da9ffc 100644
--- a/docker/Dockerfile.nrUE.ubuntu18
+++ b/docker/Dockerfile.nrUE.ubuntu18
@@ -29,7 +29,8 @@ FROM ran-base:latest AS nr-ue-base
 
 FROM ran-build:latest AS nr-ue-build
 
-RUN cp /oai-ran/docker/scripts/nr_ue_entrypoint.sh /oai-ran/docker/scripts/entrypoint.sh
+RUN python3 ./docker/scripts/generateTemplate.py ./docker/scripts/nr_ue_parameters.yaml && \
+    cp /oai-ran/docker/scripts/nr_ue_entrypoint.sh /oai-ran/docker/scripts/entrypoint.sh
 
 #start from scratch for target executable
 FROM ubuntu:bionic as oai-nr-ue
@@ -67,7 +68,10 @@ COPY --from=nr-ue-build \
     ./
 
 WORKDIR /opt/oai-nr-ue/etc
-COPY --from=nr-ue-build /oai-ran/ci-scripts/conf_files/nr-ue-sim.conf .
+COPY --from=nr-ue-build \
+    /oai-ran/ci-scripts/conf_files/nr-ue-sim.conf \
+    /oai-ran/docker/etc/nr-ue.nfapi.conf \
+    ./
 
 COPY --from=nr-ue-build \
     /oai-ran/cmake_targets/ran_build/build/liboai_eth_transpro.so \
@@ -106,5 +110,5 @@ RUN /bin/bash -c "ln -s /usr/local/lib/liboai_usrpdevif.so /usr/local/lib/liboai
     ldconfig
 
 WORKDIR /opt/oai-nr-ue
-CMD ["/opt/oai-nr-ue/bin/nr-uesoftmodem.Rel15", "-O", "/opt/oai-nr-ue/etc/nr-ue-sim.conf"]
+CMD ["/opt/oai-nr-ue/bin/nr-uesoftmodem.Rel15", "-O", "/opt/oai-nr-ue/etc/nr-ue.conf"]
 ENTRYPOINT ["/opt/oai-nr-ue/bin/entrypoint.sh"]
diff --git a/docker/scripts/generateTemplate.py b/docker/scripts/generateTemplate.py
index 297c202a03d497287345922bf5835eabc2cae176..850bb535a52abd6bc08159d72e0593d78b03bc2d 100644
--- a/docker/scripts/generateTemplate.py
+++ b/docker/scripts/generateTemplate.py
@@ -23,6 +23,7 @@
 #-----------------------------------------------------------
 # Import
 #-----------------------------------------------------------
+import glob
 import re
 import yaml
 import os
@@ -33,7 +34,8 @@ def main():
   #read yaml input parameters
   f = open(f'{sys.argv[1]}',)
   data = yaml.full_load(f)
-  dir = os.listdir(f'{data[0]["paths"]["source_dir"]}')
+  initial_path = f'{data[0]["paths"]["source_dir"]}'
+  dir = glob.glob(initial_path + '/**/*.conf', recursive=True)
 
   #identify configs, read and replace corresponding values
   for config in data[1]["configurations"]:
@@ -42,7 +44,10 @@ def main():
     print('================================================')
     print('filePrefix = ' + filePrefix)
     print('outputfilename = ' + outputfilename)
+    found = False
     for inputfile in dir:
+      if found:
+        continue
       if inputfile.find(filePrefix) >=0:
         prefix_outputfile = {"cu.band7.tm1.25PRB": f'{data[0]["paths"]["dest_dir"]}/{outputfilename}', 
                              "du.band7.tm1.25PRB": f'{data[0]["paths"]["dest_dir"]}/{outputfilename}',
@@ -58,10 +63,13 @@ def main():
                              "gnb.sa.band66.fr1.106PRB.usrpn300.conf": f'{data[0]["paths"]["dest_dir"]}/{outputfilename}',
                              "gNB_SA_CU.conf": f'{data[0]["paths"]["dest_dir"]}/{outputfilename}',
                              "gNB_SA_DU.conf": f'{data[0]["paths"]["dest_dir"]}/{outputfilename}',
+                             "proxy_gnb.band78.sa.fr1.106PRB.usrpn310.conf": f'{data[0]["paths"]["dest_dir"]}/{outputfilename}',
+                             "proxy_nr-ue.nfapi.conf": f'{data[0]["paths"]["dest_dir"]}/{outputfilename}',
                              "ue.nfapi": f'{data[0]["paths"]["dest_dir"]}/{outputfilename}',
                              "ue_sim_ci": f'{data[0]["paths"]["dest_dir"]}/{outputfilename}'
                              }
         print('inputfile = ' + inputfile)
+        found = True
         if filePrefix in prefix_outputfile:
           outputfile1 = prefix_outputfile[filePrefix]  
 
@@ -69,7 +77,7 @@ def main():
         if not os.path.exists(directory):
           os.makedirs(directory, exist_ok=True)
 
-        with open(f'{data[0]["paths"]["source_dir"]}{inputfile}', mode='r') as inputfile, \
+        with open(f'{inputfile}', mode='r') as inputfile, \
              open(outputfile1, mode='w') as outputfile:
           for line in inputfile:
             count = 0
diff --git a/docker/scripts/gnb_entrypoint.sh b/docker/scripts/gnb_entrypoint.sh
index aec5c4805052187d8d31095aaaac223809043e56..dd6256609c8085aec0b6b0c68e63caa2fe61d601 100755
--- a/docker/scripts/gnb_entrypoint.sh
+++ b/docker/scripts/gnb_entrypoint.sh
@@ -11,8 +11,9 @@ THREAD_PARALLEL_CONFIG=${THREAD_PARALLEL_CONFIG:-PARALLEL_SINGLE_THREAD}
 if [[ -v USE_NSA_TDD_MONO ]]; then cp $PREFIX/etc/gnb.nsa.tdd.conf $PREFIX/etc/gnb.conf; fi
 if [[ -v USE_SA_TDD_MONO ]]; then cp $PREFIX/etc/gnb.sa.tdd.conf $PREFIX/etc/gnb.conf; fi
 if [[ -v USE_SA_FDD_MONO ]]; then cp $PREFIX/etc/gnb.sa.fdd.conf $PREFIX/etc/gnb.conf; fi
-if [[ -v USE_SA_CU ]]; then ln -s $PREFIX/etc/gnb.sa.cu.conf $PREFIX/etc/gnb.conf; fi
+if [[ -v USE_SA_CU ]]; then cp $PREFIX/etc/gnb.sa.cu.conf $PREFIX/etc/gnb.conf; fi
 if [[ -v USE_SA_TDD_CU ]]; then cp $PREFIX/etc/gnb.sa.du.tdd.conf $PREFIX/etc/gnb.conf; fi
+if [[ -v USE_SA_NFAPI_VNF ]]; then cp $PREFIX/etc/gnb.sa.nfapi.vnf.conf $PREFIX/etc/gnb.conf; fi
 # Sometimes, the templates are not enough. We mount a conf file on $PREFIX/etc. It can be a template itself.
 if [[ -v USE_VOLUMED_CONF ]]; then cp $PREFIX/etc/mounted.conf $PREFIX/etc/gnb.conf; fi
 
diff --git a/docker/scripts/gnb_parameters.yaml b/docker/scripts/gnb_parameters.yaml
index 8547d48e676af3629f4c659ea27db75dc259d059..d5942f2c9b4559d6db4b8e0eb76b1b7a01d27e53 100644
--- a/docker/scripts/gnb_parameters.yaml
+++ b/docker/scripts/gnb_parameters.yaml
@@ -202,3 +202,39 @@
     - key: remote_n_portd
       env: "@F1_CU_D_PORT@"
 
+  - filePrefix: proxy_gnb.band78.sa.fr1.106PRB.usrpn310.conf
+    outputfilename: "gnb.sa.nfapi.vnf.conf"
+    config:
+    - key: Active_gNBs
+      env: "@GNB_NAME@"
+    - key: gNB_name
+      env: "@GNB_NAME@"
+    - key: mcc
+      env: "@MCC@"
+    - key: mnc
+      env: "@MNC@"
+    - key: mnc_length
+      env: "@MNC_LENGTH@"
+    - key: tracking_area_code
+      env: "@TAC@"
+    - key: sst
+      env: "@NSSAI_SST@"
+    - key: ipv4
+      env: "@AMF_IP_ADDRESS@"
+    - key: GNB_INTERFACE_NAME_FOR_NG_AMF
+      env: "@GNB_NGA_IF_NAME@"
+    - key: GNB_IPV4_ADDRESS_FOR_NG_AMF
+      env: "@GNB_NGA_IP_ADDRESS@"
+    - key: GNB_INTERFACE_NAME_FOR_NGU
+      env: "@GNB_NGU_IF_NAME@"
+    - key: GNB_IPV4_ADDRESS_FOR_NGU
+      env: "@GNB_NGU_IP_ADDRESS@"
+    - key: parallel_config
+      env: "@THREAD_PARALLEL_CONFIG@"
+    - key: local_s_if_name
+      env: "@LOCAL_S_IF_NAME@"
+    - key: remote_s_address
+      env: "@REMOTE_S_ADDRESS@"
+    - key: local_s_address
+      env: "@LOCAL_S_ADDRESS@"
+
diff --git a/docker/scripts/nr_ue_entrypoint.sh b/docker/scripts/nr_ue_entrypoint.sh
index af2b8a83333d140aefdbaae0527322d7af2de269..38b080a41b73b6c911826ada9d4ee943a1335fb1 100755
--- a/docker/scripts/nr_ue_entrypoint.sh
+++ b/docker/scripts/nr_ue_entrypoint.sh
@@ -5,12 +5,22 @@ set -euo pipefail
 PREFIX=/opt/oai-nr-ue
 
 # Based another env var, pick one template to use
-#if [[ -v USE_NFAPI ]]; then cp $PREFIX/etc/ue.nfapi.conf $PREFIX/etc/ue.conf; fi
+if [[ -v USE_NFAPI ]]; then cp $PREFIX/etc/nr-ue.nfapi.conf $PREFIX/etc/nr-ue.conf; fi
+# Sometimes, the templates are not enough. We mount a conf file on $PREFIX/etc. It can be a template itself.
+if [[ -v USE_VOLUMED_CONF ]]; then cp $PREFIX/etc/mounted.conf $PREFIX/etc/nr-ue.conf; fi
+# if none, pick the default
+if [ ! -f $PREFIX/etc/nr-ue.conf ]; then cp $PREFIX/etc/nr-ue-sim.conf $PREFIX/etc/nr-ue.conf; fi
 
-# Only this template will be manipulated and the USIM one!
-CONFIG_FILES=`ls $PREFIX/etc/ue.conf $PREFIX/etc/nr-ue-sim.conf || true`
+# Only this template will be manipulated
+CONFIG_FILES=`ls $PREFIX/etc/nr-ue.conf || true`
 
 for c in ${CONFIG_FILES}; do
+    # Sometimes templates have no pattern to be replaced.
+    if ! grep -oP '@[a-zA-Z0-9_]+@' ${c}; then
+        echo "Configuration is already set"
+        break
+    fi
+
     # grep variable names (format: ${VAR}) from template to be rendered
     VARS=$(grep -oP '@[a-zA-Z0-9_]+@' ${c} | sort | uniq | xargs)
 
diff --git a/docker/scripts/nr_ue_parameters.yaml b/docker/scripts/nr_ue_parameters.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..afdba880e1eb2ccc02ab714309a5aa7c59715369
--- /dev/null
+++ b/docker/scripts/nr_ue_parameters.yaml
@@ -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
+# */
+
+---
+- paths:
+    source_dir: "ci-scripts/conf_files/"
+    dest_dir: docker/etc
+    
+- configurations:
+  - filePrefix: proxy_nr-ue.nfapi.conf
+    outputfilename: "nr-ue.nfapi.conf"
+    config:
+    - key: imsi
+      env: "@FULL_IMSI@"
+    - key: key
+      env: "@FULL_KEY@"
+    - key: opc
+      env: "@OPC@"
+    - key: dnn
+      env: "@DNN@"
+    - key: nssai_sst
+      env: "@NSSAI_SST@"
+    - key: nssai_sd
+      env: "@NSSAI_SD@"
+    - key: remote_n_address
+      env: "@GNB_IP_ADDRESS@"
+    - key: local_n_address
+      env: "@NR_UE_IP_ADDRESS@"
+    - key: local_n_if_name
+      env: "@NR_UE_NFAPI_IF_NAME@"
+
diff --git a/executables/nr-gnb.c b/executables/nr-gnb.c
index ff0d3c5a4786e6bef0a7016d7ab6ae1ad9e1aac7..576a4d92b03c614f0122b15182812701aeca65b8 100644
--- a/executables/nr-gnb.c
+++ b/executables/nr-gnb.c
@@ -457,6 +457,7 @@ void init_gNB_Tpool(int inst) {
   for (int i=0; i < 2; i++) {
     notifiedFIFO_elt_t *msgL1Tx = newNotifiedFIFO_elt(sizeof(processingData_L1tx_t),0,gNB->L1_tx_out,tx_func);
     processingData_L1tx_t *msgDataTx = (processingData_L1tx_t *)NotifiedFifoData(msgL1Tx);
+    memset(msgDataTx,0, sizeof(processingData_L1tx_t));
     init_DLSCH_struct(gNB, msgDataTx);
     memset(msgDataTx->ssb, 0, 64*sizeof(NR_gNB_SSB_t));
     pushNotifiedFIFO(gNB->L1_tx_free,msgL1Tx); // to unblock the process in the beginning
diff --git a/executables/nr-softmodem-common.h b/executables/nr-softmodem-common.h
index 47fd816db5a95f4ac5cd642f109f1af8904c8c5b..6e36dcf6c7f749d7f18400ab655a304c726bb315 100644
--- a/executables/nr-softmodem-common.h
+++ b/executables/nr-softmodem-common.h
@@ -51,7 +51,6 @@
 #define CONFIG_HLP_UEFO          "set UE to enable estimation and compensation of frequency offset\n"
 #define CONFIG_HLP_DUMPFRAME     "dump UE received frame to rxsig_frame0.dat and exit\n"
 #define CONFIG_HLP_DLSHIFT       "dynamic shift for LLR compuation for TM3/4 (default 0)\n"
-#define CONFIG_HLP_UELOOP        "get softmodem (UE) to loop through memory instead of acquiring from HW\n"
 #define CONFIG_HLP_PHYTST        "test UE phy layer, mac disabled\n"
 #define CONFIG_HLP_DORA          "test gNB  and UE with RA procedures\n"
 #define CONFIG_HLP_DMAMAP        "sets flag for improved EXMIMO UE performance\n"
diff --git a/executables/nr-ue.c b/executables/nr-ue.c
index 3cc71b8b3a0f3ef9d577176e64ab1f404557fe3c..f643344a2b69396509d86e5debdc1334c36cddf0 100644
--- a/executables/nr-ue.c
+++ b/executables/nr-ue.c
@@ -19,7 +19,7 @@
  *      contact@openairinterface.org
  */
 
-#define _GNU_SOURCE
+#define _GNU_SOURCE // For pthread_setname_np
 #include <pthread.h>
 #include <openair1/PHY/impl_defs_top.h>
 #include "executables/nr-uesoftmodem.h"
@@ -239,84 +239,21 @@ static void L1_nsa_prach_procedures(frame_t frame, int slot, fapi_nr_ul_config_p
   LOG_D(NR_MAC, "We have successfully filled the rach_ind queue with the recently filled rach ind\n");
 }
 
-static bool sfn_slot_matcher(void *wanted, void *candidate)
-{
-  nfapi_p7_message_header_t *msg = candidate;
-  int sfn_sf = *(int*)wanted;
-
-  switch (msg->message_id)
-  {
-    case NFAPI_NR_PHY_MSG_TYPE_RACH_INDICATION:
-    {
-      nfapi_nr_rach_indication_t *ind = candidate;
-      return NFAPI_SFNSLOT2SFN(sfn_sf) == ind->sfn && NFAPI_SFNSLOT2SLOT(sfn_sf) == ind->slot;
-    }
-
-    case NFAPI_NR_PHY_MSG_TYPE_RX_DATA_INDICATION:
-    {
-      nfapi_nr_rx_data_indication_t *ind = candidate;
-      return NFAPI_SFNSLOT2SFN(sfn_sf) == ind->sfn && NFAPI_SFNSLOT2SLOT(sfn_sf) == ind->slot;
-    }
-
-    case NFAPI_NR_PHY_MSG_TYPE_CRC_INDICATION:
-    {
-      nfapi_nr_crc_indication_t *ind = candidate;
-      return NFAPI_SFNSLOT2SFN(sfn_sf) == ind->sfn && NFAPI_SFNSLOT2SLOT(sfn_sf) == ind->slot;
-    }
-
-    case NFAPI_NR_PHY_MSG_TYPE_UCI_INDICATION:
-    {
-      nfapi_nr_uci_indication_t *ind = candidate;
-      return NFAPI_SFNSLOT2SFN(sfn_sf) == ind->sfn && NFAPI_SFNSLOT2SLOT(sfn_sf) == ind->slot;
-    }
-
-    case NFAPI_NR_PHY_MSG_TYPE_DL_TTI_REQUEST:
-    {
-      nfapi_nr_dl_tti_request_t *ind = candidate;
-      return NFAPI_SFNSLOT2SFN(sfn_sf) == ind->SFN && NFAPI_SFNSLOT2SLOT(sfn_sf) == ind->Slot;
-    }
-
-    case NFAPI_NR_PHY_MSG_TYPE_TX_DATA_REQUEST:
-    {
-      nfapi_nr_tx_data_request_t *ind = candidate;
-      return NFAPI_SFNSLOT2SFN(sfn_sf) == ind->SFN && NFAPI_SFNSLOT2SLOT(sfn_sf) == ind->Slot;
-    }
-
-    case NFAPI_NR_PHY_MSG_TYPE_UL_DCI_REQUEST:
-    {
-      nfapi_nr_ul_dci_request_t *ind = candidate;
-      return NFAPI_SFNSLOT2SFN(sfn_sf) == ind->SFN && NFAPI_SFNSLOT2SLOT(sfn_sf) == ind->Slot;
-    }
-
-    case NFAPI_NR_PHY_MSG_TYPE_UL_TTI_REQUEST:
-    {
-      nfapi_nr_ul_tti_request_t *ind = candidate;
-      return NFAPI_SFNSLOT2SFN(sfn_sf) == ind->SFN && NFAPI_SFNSLOT2SLOT(sfn_sf) == ind->Slot;
-    }
-
-    default:
-      LOG_E(NR_MAC, "sfn_slot_match bad ID: %d\n", msg->message_id);
-
-  }
-
-  return false;
-}
-
 static void process_queued_nr_nfapi_msgs(NR_UE_MAC_INST_t *mac, int sfn_slot)
 {
   nfapi_nr_rach_indication_t *rach_ind = unqueue_matching(&nr_rach_ind_queue, MAX_QUEUE_SIZE, sfn_slot_matcher, &sfn_slot);
-  nfapi_nr_rx_data_indication_t *rx_ind = unqueue_matching(&nr_rx_ind_queue, MAX_QUEUE_SIZE, sfn_slot_matcher, &sfn_slot);
-  nfapi_nr_crc_indication_t *crc_ind = unqueue_matching(&nr_crc_ind_queue, MAX_QUEUE_SIZE, sfn_slot_matcher, &sfn_slot);
   nfapi_nr_dl_tti_request_t *dl_tti_request = get_queue(&nr_dl_tti_req_queue);
   nfapi_nr_ul_dci_request_t *ul_dci_request = get_queue(&nr_ul_dci_req_queue);
 
-  LOG_D(NR_MAC, "Try to get a ul_tti_req for sfn/slot %d %d from queue with %lu items\n",
-        NFAPI_SFNSLOT2SFN(mac->nr_ue_emul_l1.active_harq_sfn_slot),NFAPI_SFNSLOT2SLOT(mac->nr_ue_emul_l1.active_harq_sfn_slot), nr_ul_tti_req_queue.num_items);
-  nfapi_nr_ul_tti_request_t *ul_tti_request = unqueue_matching(&nr_ul_tti_req_queue, MAX_QUEUE_SIZE, sfn_slot_matcher, &mac->nr_ue_emul_l1.active_harq_sfn_slot);
-  if (!ul_tti_request)
-  {
-      LOG_D(NR_MAC, "Try to get a ul_tti_req from seprate queue because dl_tti_req was late\n");
-      ul_tti_request = unqueue_matching(&nr_wait_ul_tti_req_queue, MAX_QUEUE_SIZE, sfn_slot_matcher, &mac->nr_ue_emul_l1.active_harq_sfn_slot);
+  for (int i = 0; i < NR_MAX_HARQ_PROCESSES; i++) {
+    LOG_D(NR_MAC, "Try to get a ul_tti_req by matching CRC active SFN %d/SLOT %d from queue with %lu items\n",
+            NFAPI_SFNSLOT2SFN(mac->nr_ue_emul_l1.harq[i].active_ul_harq_sfn_slot),
+            NFAPI_SFNSLOT2SLOT(mac->nr_ue_emul_l1.harq[i].active_ul_harq_sfn_slot), nr_ul_tti_req_queue.num_items);
+    nfapi_nr_ul_tti_request_t *ul_tti_request_crc = unqueue_matching(&nr_ul_tti_req_queue, MAX_QUEUE_SIZE, sfn_slot_matcher, &mac->nr_ue_emul_l1.harq[i].active_ul_harq_sfn_slot);
+    if (ul_tti_request_crc && ul_tti_request_crc->n_pdus > 0)
+    {
+      check_and_process_dci(NULL, NULL, NULL, ul_tti_request_crc);
+    }
   }
 
   if (rach_ind && rach_ind->number_of_pdus > 0)
@@ -333,24 +270,6 @@ static void process_queued_nr_nfapi_msgs(NR_UE_MAC_INST_t *mac, int sfn_slot)
       free(rach_ind);
       nr_Msg1_transmitted(0, 0, NFAPI_SFNSLOT2SFN(sfn_slot), 0);
   }
-  if (crc_ind && crc_ind->number_crcs > 0)
-  {
-    NR_UL_IND_t UL_INFO = {
-      .crc_ind = *crc_ind,
-    };
-    send_nsa_standalone_msg(&UL_INFO, crc_ind->header.message_id);
-    free(crc_ind->crc_list);
-    free(crc_ind);
-  }
-  if (rx_ind && rx_ind->number_of_pdus > 0)
-  {
-    NR_UL_IND_t UL_INFO = {
-      .rx_ind = *rx_ind,
-    };
-    send_nsa_standalone_msg(&UL_INFO, rx_ind->header.message_id);
-    free(rx_ind->pdu_list);
-    free(rx_ind);
-  }
   if (dl_tti_request)
   {
     int dl_tti_sfn_slot = NFAPI_SFNSLOT2HEX(dl_tti_request->SFN, dl_tti_request->Slot);
@@ -380,10 +299,6 @@ static void process_queued_nr_nfapi_msgs(NR_UE_MAC_INST_t *mac, int sfn_slot)
   {
     check_and_process_dci(NULL, NULL, ul_dci_request, NULL);
   }
-  if (ul_tti_request && ul_tti_request->n_pdus > 0)
-  {
-    check_and_process_dci(NULL, NULL, NULL, ul_tti_request);
-  }
 }
 
 static void check_nr_prach(NR_UE_MAC_INST_t *mac, nr_uplink_indication_t *ul_info, NR_PRACH_RESOURCES_t *prach_resources)
@@ -434,7 +349,6 @@ static void *NRUE_phy_stub_standalone_pnf_task(void *arg)
   reset_queue(&nr_tx_req_queue);
   reset_queue(&nr_ul_dci_req_queue);
   reset_queue(&nr_ul_tti_req_queue);
-  reset_queue(&nr_wait_ul_tti_req_queue);
 
   NR_PRACH_RESOURCES_t prach_resources;
   memset(&prach_resources, 0, sizeof(prach_resources));
@@ -443,6 +357,13 @@ static void *NRUE_phy_stub_standalone_pnf_task(void *arg)
   int last_sfn_slot = -1;
   uint16_t sfn_slot = 0;
 
+  module_id_t mod_id = 0;
+  NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id);
+  for (int i = 0; i < NR_MAX_HARQ_PROCESSES; i++) {
+      mac->nr_ue_emul_l1.harq[i].active = false;
+      mac->nr_ue_emul_l1.harq[i].active_ul_harq_sfn_slot = -1;
+  }
+
   while (!oai_exit)
   {
     if (sem_wait(&sfn_slot_semaphore) != 0)
@@ -459,9 +380,11 @@ static void *NRUE_phy_stub_standalone_pnf_task(void *arg)
     }
     if (slot_ind) {
       sfn_slot = *slot_ind;
+      free_and_zero(slot_ind);
     }
     else if (ch_info) {
       sfn_slot = ch_info->sfn_slot;
+      free_and_zero(ch_info);
     }
 
     frame_t frame = NFAPI_SFNSLOT2SFN(sfn_slot);
@@ -477,8 +400,6 @@ static void *NRUE_phy_stub_standalone_pnf_task(void *arg)
     LOG_D(NR_MAC, "The received sfn/slot [%d %d] from proxy\n",
           frame, slot);
 
-    module_id_t mod_id = 0;
-    NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id);
     if (get_softmodem_params()->sa && mac->mib == NULL)
     {
       LOG_D(NR_MAC, "We haven't gotten MIB. Lets see if we received it\n");
@@ -533,8 +454,10 @@ static void *NRUE_phy_stub_standalone_pnf_task(void *arg)
                       mac->scc_SIB->tdd_UL_DL_ConfigurationCommon,
                       ul_info.slot_tx, mac->frame_type))
     {
-      LOG_D(NR_MAC, "Slot %d. calling nr_ue_ul_ind() from %s\n", ul_info.slot_tx, __FUNCTION__);
-      nr_ue_ul_indication(&ul_info);
+      LOG_D(NR_MAC, "Slot %d. calling nr_ue_ul_ind() and nr_ue_pucch_scheduler() from %s\n", ul_info.slot_tx, __FUNCTION__);
+      nr_ue_scheduler(NULL, &ul_info);
+      nr_ue_prach_scheduler(mod_id, ul_info.frame_tx, ul_info.slot_tx, ul_info.thread_id);
+      nr_ue_pucch_scheduler(mod_id, ul_info.frame_tx, ul_info.slot_tx, ul_info.thread_id);
       check_nr_prach(mac, &ul_info, &prach_resources);
     }
     if (!IS_SOFTMODEM_NOS1 && get_softmodem_params()->sa) {
@@ -544,10 +467,6 @@ static void *NRUE_phy_stub_standalone_pnf_task(void *arg)
       pdcp_run(&ctxt);
     }
     process_queued_nr_nfapi_msgs(mac, sfn_slot);
-    free(slot_ind);
-    slot_ind = NULL;
-    free(ch_info);
-    ch_info = NULL;
   }
   return NULL;
 }
@@ -654,17 +573,7 @@ static void UE_synch(void *arg) {
               openair0_cfg[UE->rf_map.card].rx_freq[0],
               openair0_cfg[UE->rf_map.card].tx_freq[0]);
 
-        if (UE->mode != loop_through_memory) {
-          UE->rfdevice.trx_set_freq_func(&UE->rfdevice,&openair0_cfg[0],0);
-          //UE->rfdevice.trx_set_gains_func(&openair0,&openair0_cfg[0]);
-          //UE->rfdevice.trx_stop_func(&UE->rfdevice);
-          // sleep(1);
-          /*if (UE->rfdevice.trx_start_func(&UE->rfdevice) != 0 ) {
-            LOG_E(HW,"Could not start the device\n");
-            oai_exit=1;
-            }*/
-        }
-
+        UE->rfdevice.trx_set_freq_func(&UE->rfdevice,&openair0_cfg[0],0);
         if (UE->UE_scan_carrier == 1) {
           UE->UE_scan_carrier = 0;
         } else {
@@ -683,8 +592,7 @@ static void UE_synch(void *arg) {
 
           LOG_I(PHY, "Initial sync failed: trying carrier off %d Hz\n", freq_offset);
 
-          if (UE->mode != loop_through_memory)
-            UE->rfdevice.trx_set_freq_func(&UE->rfdevice,&openair0_cfg[0],0);
+          UE->rfdevice.trx_set_freq_func(&UE->rfdevice,&openair0_cfg[0],0);
         }
 
         break;
@@ -729,7 +637,7 @@ void processSlotTX(void *arg) {
       stop_meas(&UE->ue_ul_indication_stats);
     }
 
-    if ((UE->mode != loop_through_memory) && (rxtxD->ue_sched_mode != NOT_PUSCH)) {
+    if (rxtxD->ue_sched_mode != NOT_PUSCH) {
       phy_procedures_nrUE_TX(UE,proc,0);
     }
   }
@@ -744,6 +652,7 @@ void processSlotRX(void *arg) {
   int rx_slot_type = nr_ue_slot_select(cfg, proc->frame_rx, proc->nr_slot_rx);
   int tx_slot_type = nr_ue_slot_select(cfg, proc->frame_tx, proc->nr_slot_tx);
   uint8_t gNB_id = 0;
+  NR_UE_PDCCH_CONFIG phy_pdcch_config={0};
 
   if (IS_SOFTMODEM_NOS1 || get_softmodem_params()->sa) {
     /* send tick to RLC and PDCP every ms */
@@ -759,7 +668,7 @@ void processSlotRX(void *arg) {
 
     if(UE->if_inst != NULL && UE->if_inst->dl_indication != NULL) {
       nr_downlink_indication_t dl_indication;
-      nr_fill_dl_indication(&dl_indication, NULL, NULL, proc, UE, gNB_id);
+      nr_fill_dl_indication(&dl_indication, NULL, NULL, proc, UE, gNB_id, &phy_pdcch_config);
       UE->if_inst->dl_indication(&dl_indication, NULL);
     }
 
@@ -768,7 +677,7 @@ void processSlotRX(void *arg) {
     phy_procedures_slot_parallelization_nrUE_RX( UE, proc, 0, 0, 1, no_relay, NULL );
 #else
     uint64_t a=rdtsc_oai();
-    phy_procedures_nrUE_RX(UE, proc, gNB_id, get_nrUE_params()->nr_dlsch_parallel, &rxtxD->txFifo);
+    phy_procedures_nrUE_RX(UE, proc, gNB_id, get_nrUE_params()->nr_dlsch_parallel, &phy_pdcch_config, &rxtxD->txFifo);
     LOG_D(PHY, "In %s: slot %d, time %llu\n", __FUNCTION__, proc->nr_slot_rx, (rdtsc_oai()-a)/3500);
 #endif
 
@@ -818,9 +727,10 @@ void processSlotRX(void *arg) {
 
 void dummyWrite(PHY_VARS_NR_UE *UE,openair0_timestamp timestamp, int writeBlockSize) {
   void *dummy_tx[UE->frame_parms.nb_antennas_tx];
-
+  int16_t dummy_tx_data[UE->frame_parms.nb_antennas_tx][2*writeBlockSize]; // 2 because the function we call use pairs of int16_t implicitly as complex numbers
+  memset(dummy_tx_data, 0, sizeof(dummy_tx_data));
   for (int i=0; i<UE->frame_parms.nb_antennas_tx; i++)
-    dummy_tx[i]=malloc16_clear(writeBlockSize*4);
+    dummy_tx[i]=dummy_tx_data[i];
 
   AssertFatal( writeBlockSize ==
                UE->rfdevice.trx_write_func(&UE->rfdevice,
@@ -830,8 +740,6 @@ void dummyWrite(PHY_VARS_NR_UE *UE,openair0_timestamp timestamp, int writeBlockS
                UE->frame_parms.nb_antennas_tx,
                4),"");
 
-  for (int i=0; i<UE->frame_parms.nb_antennas_tx; i++)
-    free(dummy_tx[i]);
 }
 
 void readFrame(PHY_VARS_NR_UE *UE,  openair0_timestamp *timestamp, bool toTrash) {
@@ -873,7 +781,7 @@ void syncInFrame(PHY_VARS_NR_UE *UE, openair0_timestamp *timestamp) {
     *timestamp += UE->frame_parms.get_samples_per_slot(1,&UE->frame_parms);
     for ( int size=UE->rx_offset ; size > 0 ; size -= UE->frame_parms.samples_per_subframe ) {
       int unitTransfer=size>UE->frame_parms.samples_per_subframe ? UE->frame_parms.samples_per_subframe : size ;
-      // we write before read becasue gNB waits for UE to write and both executions halt
+      // we write before read because gNB waits for UE to write and both executions halt
       // this happens here as the read size is samples_per_subframe which is very much larger than samp_per_slot
       if (IS_SOFTMODEM_RFSIM) dummyWrite(UE,*timestamp, unitTransfer);
       AssertFatal(unitTransfer ==
diff --git a/executables/nr-uesoftmodem.c b/executables/nr-uesoftmodem.c
index 23615b2c9803c6ba46fe520e677a0cf39559a2ec..b1960faf7d555057cba80704529d2f71ccd9eef0 100644
--- a/executables/nr-uesoftmodem.c
+++ b/executables/nr-uesoftmodem.c
@@ -50,6 +50,7 @@
 #include "LAYER2/MAC/mac_vars.h"
 #include "RRC/LTE/rrc_vars.h"
 #include "PHY_INTERFACE/phy_interface_vars.h"
+#include "NR_IF_Module.h"
 #include "openair1/SIMULATION/TOOLS/sim.h"
 
 #ifdef SMBV
@@ -156,6 +157,9 @@ uint32_t       N_RB_DL    = 106;
  */
 uint8_t abstraction_flag=0;
 
+nr_bler_struct nr_bler_data[NR_NUM_MCS];
+
+static void init_bler_table(void);
 
 /*---------------------BMC: timespec helpers -----------------------------*/
 
@@ -241,16 +245,18 @@ nrUE_params_t *get_nrUE_params(void) {
 }
 /* initialie thread pools used for NRUE processing paralleliation */ 
 void init_tpools(uint8_t nun_dlsch_threads) {
-  char *params = NULL;
-  params = calloc(1,(NR_RX_NB_TH*NR_NB_TH_SLOT*3)+1);
+  char params[NR_RX_NB_TH*NR_NB_TH_SLOT*3+1]={0};
   for (int i=0; i<NR_RX_NB_TH*NR_NB_TH_SLOT; i++) {
     memcpy(params+(i*3),"-1,",3);
   }
-  initTpool(params, &(nrUE_params.Tpool), false);
-  free(params);
-  init_dlsch_tpool( nun_dlsch_threads);
+  if (getenv("noThreads")) {
+     initTpool("n", &(nrUE_params.Tpool), false);
+     init_dlsch_tpool(0);
+   } else {
+     initTpool(params, &(nrUE_params.Tpool), false);
+     init_dlsch_tpool( nun_dlsch_threads);
+   }
 }
-
 static void get_options(void) {
 
   nrUE_params.ofdm_offset_divisor = 8;
@@ -472,6 +478,7 @@ int main( int argc, char **argv ) {
   PHY_vars_UE_g[0] = malloc(sizeof(PHY_VARS_NR_UE *)*MAX_NUM_CCs);
   if (get_softmodem_params()->emulate_l1) {
     RCconfig_nr_ue_L1();
+    init_bler_table();
   }
 
   if (get_softmodem_params()->do_ra)
@@ -552,3 +559,56 @@ int main( int argc, char **argv ) {
 
   return 0;
 }
+
+// Read in each MCS file and build BLER-SINR-TB table
+static void init_bler_table(void) {
+  memset(nr_bler_data, 0, sizeof(nr_bler_data));
+
+  const char *awgn_results_dir = getenv("AWGN_RESULTS_DIR");
+  if (!awgn_results_dir) {
+    LOG_W(NR_MAC, "No $AWGN_RESULTS_DIR\n");
+    return;
+  }
+
+  for (unsigned int i = 0; i < NR_NUM_MCS; i++) {
+    char fName[1024];
+    snprintf(fName, sizeof(fName), "%s/mcs%d_awgn_5G.csv", awgn_results_dir, i);
+    FILE *pFile = fopen(fName, "r");
+    if (!pFile) {
+      LOG_E(NR_MAC, "%s: open %s: %s\n", __func__, fName, strerror(errno));
+      continue;
+    }
+    size_t bufSize = 1024;
+    char * line = NULL;
+    char * token;
+    char * temp = NULL;
+    int nlines = 0;
+    while (getline(&line, &bufSize, pFile) > 0) {
+      if (!strncmp(line, "SNR", 3)) {
+        continue;
+      }
+
+      if (nlines > NUM_SINR) {
+        LOG_E(NR_MAC, "BLER FILE ERROR - num lines greater than expected - file: %s\n", fName);
+        abort();
+      }
+
+      token = strtok_r(line, ";", &temp);
+      int ncols = 0;
+      while (token != NULL) {
+        if (ncols > NUM_BLER_COL) {
+          LOG_E(NR_MAC, "BLER FILE ERROR - num of cols greater than expected\n");
+          abort();
+        }
+
+        nr_bler_data[i].bler_table[nlines][ncols] = strtof(token, NULL);
+        ncols++;
+
+        token = strtok_r(NULL, ";", &temp);
+      }
+      nlines++;
+    }
+    nr_bler_data[i].length = nlines;
+    fclose(pFile);
+  }
+}
diff --git a/executables/softmodem-common.h b/executables/softmodem-common.h
index 48ce73149f1612e04412ace6737abda0f0b40a6c..eb0c1a54f74025e5c3cb31d159790883c4e59ea7 100644
--- a/executables/softmodem-common.h
+++ b/executables/softmodem-common.h
@@ -53,7 +53,6 @@ extern "C"
 
 
 #define CONFIG_HLP_DUMPFRAME     "dump UE received frame to rxsig_frame0.dat and exit\n"
-#define CONFIG_HLP_UELOOP        "get softmodem (UE) to loop through memory instead of acquiring from HW\n"
 #define CONFIG_HLP_PHYTST        "test UE phy layer, mac disabled\n"
 #define CONFIG_HLP_DORA          "test gNB  and UE with RA procedures\n"
 #define CONFIG_HLP_SA            "run gNB in standalone mode\n"
diff --git a/nfapi/oai_integration/nfapi_vnf.c b/nfapi/oai_integration/nfapi_vnf.c
index 44ee05940fc3aa6879867582f57fe65773b0f8d2..6bc5a736de53b9f67a546bd85c71f6da9516071a 100644
--- a/nfapi/oai_integration/nfapi_vnf.c
+++ b/nfapi/oai_integration/nfapi_vnf.c
@@ -244,13 +244,13 @@ void oai_create_gnb(void) {
 
   if (RC.gNB == NULL) {
     RC.gNB = (PHY_VARS_gNB **) calloc(1, sizeof(PHY_VARS_gNB *));
-    LOG_I(PHY,"gNB L1 structure RC.gNB allocated @ %p\n",RC.gNB);
+    LOG_D(PHY,"gNB L1 structure RC.gNB allocated @ %p\n",RC.gNB);
   }
 
 
   if (RC.gNB[0] == NULL) {
     RC.gNB[0] = (PHY_VARS_gNB *) calloc(1, sizeof(PHY_VARS_gNB));
-    LOG_I(PHY,"[nr-gnb.c] gNB structure RC.gNB[%d] allocated @ %p\n",0,RC.gNB[0]);
+    LOG_D(PHY,"[nr-gnb.c] gNB structure RC.gNB[%d] allocated @ %p\n",0,RC.gNB[0]);
   }
   
   PHY_VARS_gNB *gNB = RC.gNB[0];
@@ -491,7 +491,7 @@ int wake_gNB_rxtx(PHY_VARS_gNB *gNB, uint16_t sfn, uint16_t slot) {
   L1_proc->frame_tx     = (L1_proc->slot_rx > (19-slot_ahead)) ? (L1_proc->frame_rx+1)&1023 : L1_proc->frame_rx;
   L1_proc->slot_tx      = (L1_proc->slot_rx + slot_ahead)%20;
 
-  //LOG_I(PHY, "sfn/sf:%d%d proc[rx:%d%d] rx:%d%d] About to wake rxtx thread\n\n", sfn, slot, proc->frame_rx, proc->slot_rx, L1_proc->frame_rx, L1_proc->slot_rx);
+  //LOG_D(PHY, "sfn/sf:%d%d proc[rx:%d%d] rx:%d%d] About to wake rxtx thread\n\n", sfn, slot, proc->frame_rx, proc->slot_rx, L1_proc->frame_rx, L1_proc->slot_rx);
   //NFAPI_TRACE(NFAPI_TRACE_INFO, "\nEntering wake_gNB_rxtx sfn %d slot %d\n",L1_proc->frame_rx,L1_proc->slot_rx);
   // the thread can now be woken up
   if (pthread_cond_signal(&L1_proc->cond) != 0) {
@@ -757,7 +757,7 @@ int phy_nr_rach_indication(nfapi_nr_rach_indication_t *ind)
 int phy_nr_uci_indication(nfapi_nr_uci_indication_t *ind)
 {
 
-  LOG_I(NR_MAC, "In %s() NFAPI SFN/SF: %d/%d number_of_pdus :%u\n",
+  LOG_D(NR_MAC, "In %s() NFAPI SFN/SF: %d/%d number_of_pdus :%u\n",
           __FUNCTION__,ind->sfn, ind->slot, ind->num_ucis);
   if(NFAPI_MODE == NFAPI_MODE_VNF)
   {
@@ -787,12 +787,12 @@ int phy_nr_uci_indication(nfapi_nr_uci_indication_t *ind)
           if (ind_pdu->harq) {
             uci_ind_pdu->harq = CALLOC(1, sizeof(*uci_ind_pdu->harq));
             AssertFatal(uci_ind_pdu->harq != NULL, "Memory not allocated for uci_ind_pdu->harq in phy_nr_uci_indication.");
-
             *uci_ind_pdu->harq = *ind_pdu->harq;
+
             uci_ind_pdu->harq->harq_list = CALLOC(uci_ind_pdu->harq->num_harq, sizeof(*uci_ind_pdu->harq->harq_list));
             AssertFatal(uci_ind_pdu->harq->harq_list != NULL, "Memory not allocated for uci_ind_pdu->harq->harq_list in phy_nr_uci_indication.");
             for (int j = 0; j < uci_ind_pdu->harq->num_harq; j++)
-                uci_ind_pdu->harq->harq_list[j].harq_value =  ind_pdu->harq->harq_list[j].harq_value;
+                uci_ind_pdu->harq->harq_list[j].harq_value = ind_pdu->harq->harq_list[j].harq_value;
           }
           break;
         }
@@ -800,21 +800,27 @@ int phy_nr_uci_indication(nfapi_nr_uci_indication_t *ind)
         case NFAPI_NR_UCI_FORMAT_2_3_4_PDU_TYPE: {
           nfapi_nr_uci_pucch_pdu_format_2_3_4_t *uci_ind_pdu = &uci_ind->uci_list[i].pucch_pdu_format_2_3_4;
           nfapi_nr_uci_pucch_pdu_format_2_3_4_t *ind_pdu = &ind->uci_list[i].pucch_pdu_format_2_3_4;
-          
-          uci_ind_pdu->harq.harq_payload = CALLOC(1, sizeof(*uci_ind_pdu->harq.harq_payload));
-          AssertFatal(uci_ind_pdu->harq.harq_payload != NULL, "Memory not allocated for uci_ind_pdu->harq.harq_payload in phy_nr_uci_indication.");
-          *uci_ind_pdu->harq.harq_payload =  *ind_pdu->harq.harq_payload;
-
-
-          uci_ind_pdu->csi_part1.csi_part1_payload = CALLOC(1, sizeof(*uci_ind_pdu->csi_part1.csi_part1_payload));
-          AssertFatal(uci_ind_pdu->csi_part1.csi_part1_payload != NULL, "Memory not allocated for uci_ind_pdu->csi_part1.csi_part1_payload in phy_nr_uci_indication.");
-          *uci_ind_pdu->csi_part1.csi_part1_payload =  *ind_pdu->csi_part1.csi_part1_payload;
-
-
-          uci_ind_pdu->csi_part2.csi_part2_payload = CALLOC(1, sizeof(*uci_ind_pdu->csi_part2.csi_part2_payload));
-          AssertFatal(uci_ind_pdu->csi_part2.csi_part2_payload != NULL, "Memory not allocated for uci_ind_pdu->csi_part2.csi_part2_payload in phy_nr_uci_indication.");
-          *uci_ind_pdu->csi_part2.csi_part2_payload =  *ind_pdu->csi_part2.csi_part2_payload;
-
+          *uci_ind_pdu = *ind_pdu;
+          if (ind_pdu->harq.harq_payload) {
+            uci_ind_pdu->harq.harq_payload = CALLOC(1, sizeof(*uci_ind_pdu->harq.harq_payload));
+            AssertFatal(uci_ind_pdu->harq.harq_payload != NULL, "Memory not allocated for uci_ind_pdu->harq.harq_payload in phy_nr_uci_indication.");
+            *uci_ind_pdu->harq.harq_payload = *ind_pdu->harq.harq_payload;
+          }
+          if (ind_pdu->sr.sr_payload) {
+            uci_ind_pdu->sr.sr_payload = CALLOC(1, sizeof(*uci_ind_pdu->sr.sr_payload));
+            AssertFatal(uci_ind_pdu->sr.sr_payload != NULL, "Memory not allocated for uci_ind_pdu->sr.sr_payload in phy_nr_uci_indication.");
+            *uci_ind_pdu->sr.sr_payload = *ind_pdu->sr.sr_payload;
+          }
+          if (ind_pdu->csi_part1.csi_part1_payload) {
+            uci_ind_pdu->csi_part1.csi_part1_payload = CALLOC(1, sizeof(*uci_ind_pdu->csi_part1.csi_part1_payload));
+            AssertFatal(uci_ind_pdu->csi_part1.csi_part1_payload != NULL, "Memory not allocated for uci_ind_pdu->csi_part1.csi_part1_payload in phy_nr_uci_indication.");
+            *uci_ind_pdu->csi_part1.csi_part1_payload = *ind_pdu->csi_part1.csi_part1_payload;
+          }
+          if (ind_pdu->csi_part2.csi_part2_payload) {
+            uci_ind_pdu->csi_part2.csi_part2_payload = CALLOC(1, sizeof(*uci_ind_pdu->csi_part2.csi_part2_payload));
+            AssertFatal(uci_ind_pdu->csi_part2.csi_part2_payload != NULL, "Memory not allocated for uci_ind_pdu->csi_part2.csi_part2_payload in phy_nr_uci_indication.");
+            *uci_ind_pdu->csi_part2.csi_part2_payload = *ind_pdu->csi_part2.csi_part2_payload;
+          }
           break;
         }
       }
@@ -944,7 +950,7 @@ int phy_crc_indication(struct nfapi_vnf_p7_config *config, nfapi_crc_indication_
 
 int phy_nr_crc_indication(nfapi_nr_crc_indication_t *ind) {
 
-  LOG_I(NR_MAC, "In %s() NFAPI SFN/SF: %d/%d number_of_pdus :%u\n",
+  LOG_D(NR_MAC, "In %s() NFAPI SFN/SF: %d/%d number_of_pdus :%u\n",
           __FUNCTION__,ind->sfn, ind->slot, ind->number_crcs);
 
   if(NFAPI_MODE == NFAPI_MODE_VNF)
@@ -967,7 +973,7 @@ int phy_nr_crc_indication(nfapi_nr_crc_indication_t *ind) {
       crc_ind->crc_list[j].tb_crc_status = ind->crc_list[j].tb_crc_status;
       crc_ind->crc_list[j].timing_advance = ind->crc_list[j].timing_advance;
       crc_ind->crc_list[j].ul_cqi = ind->crc_list[j].ul_cqi;
-      LOG_I(NR_MAC, "Received crc_ind.harq_id = %d for %d index SFN SLot %u %u with rnti %x\n",
+      LOG_D(NR_MAC, "Received crc_ind.harq_id = %d for %d index SFN SLot %u %u with rnti %x\n",
                     ind->crc_list[j].harq_id, j, ind->sfn, ind->slot, ind->crc_list[j].rnti);
     }
     if (!put_queue(&gnb_crc_ind_queue, crc_ind))
@@ -1063,7 +1069,7 @@ int phy_rx_indication(struct nfapi_vnf_p7_config *config, nfapi_rx_indication_t
 
 int phy_nr_rx_data_indication(nfapi_nr_rx_data_indication_t *ind) {
 
-  LOG_I(NR_MAC, "In %s() NFAPI SFN/SF: %d/%d number_of_pdus :%u, and pdu %p\n",
+  LOG_D(NR_MAC, "In %s() NFAPI SFN/SF: %d/%d number_of_pdus :%u, and pdu %p\n",
           __FUNCTION__,ind->sfn, ind->slot, ind->number_of_pdus, ind->pdu_list[0].pdu);
 
   if(NFAPI_MODE == NFAPI_MODE_VNF)
@@ -1165,7 +1171,7 @@ static void analyze_cqi_pdus_for_duplicates(nfapi_cqi_indication_t *ind)
   {
     nfapi_cqi_indication_pdu_t *src_pdu = &ind->cqi_indication_body.cqi_pdu_list[i];
 
-    LOG_I(MAC, "CQI_IND[PDU:%d][rnti:%x cqi:%d channel:%d]\n", i, src_pdu->rx_ue_information.rnti,
+    LOG_D(MAC, "CQI_IND[PDU:%d][rnti:%x cqi:%d channel:%d]\n", i, src_pdu->rx_ue_information.rnti,
           src_pdu->ul_cqi_information.ul_cqi, src_pdu->ul_cqi_information.channel);
 
     for (int j = i + 1; j < num_cqis; j++)
@@ -1887,7 +1893,7 @@ int oai_nfapi_dl_config_req(nfapi_dl_config_request_t *dl_config_req) {
   nfapi_vnf_p7_config_t *p7_config = vnf.p7_vnfs[0].config;
   dl_config_req->header.phy_id = 1; // DJP HACK TODO FIXME - need to pass this around!!!!
   dl_config_req->header.message_id = NFAPI_DL_CONFIG_REQUEST;
-  LOG_I(PHY, "[VNF] %s() DL_CONFIG_REQ sfn_sf:%d_%d number_of_pdus:%d\n", __FUNCTION__,
+  LOG_D(PHY, "[VNF] %s() DL_CONFIG_REQ sfn_sf:%d_%d number_of_pdus:%d\n", __FUNCTION__,
         NFAPI_SFNSF2SFN(dl_config_req->sfn_sf),NFAPI_SFNSF2SF(dl_config_req->sfn_sf), dl_config_req->dl_config_request_body.number_pdu);
   if (dl_config_req->dl_config_request_body.number_pdu > 0)
   {
@@ -1898,7 +1904,7 @@ int oai_nfapi_dl_config_req(nfapi_dl_config_request_t *dl_config_req) {
             {
                 uint16_t dl_rnti = dl_config_req->dl_config_request_body.dl_config_pdu_list[i].dlsch_pdu.dlsch_pdu_rel8.rnti;
                 uint16_t numPDUs = dl_config_req->dl_config_request_body.number_pdu;
-                LOG_I(MAC, "(OAI eNB) Sending dl_config_req at VNF during Frame: %d and Subframe: %d,"
+                LOG_D(MAC, "(OAI eNB) Sending dl_config_req at VNF during Frame: %d and Subframe: %d,"
                            " with a RNTI value of: %x and with number of PDUs: %u\n",
                       NFAPI_SFNSF2SFN(dl_config_req->sfn_sf),NFAPI_SFNSF2SF(dl_config_req->sfn_sf), dl_rnti, numPDUs);
             }
@@ -1919,8 +1925,7 @@ int oai_nfapi_dl_config_req(nfapi_dl_config_request_t *dl_config_req) {
 
 int oai_nfapi_dl_tti_req(nfapi_nr_dl_tti_request_t *dl_config_req)
 {
-  //LOG_I(PHY, "sfn:%d,slot:%d\n",dl_config_req->SFN,dl_config_req->Slot);
-  //printf("\nEntering oai_nfapi_nr_dl_config_req sfn:%d,slot:%d\n",dl_config_req->SFN,dl_config_req->Slot);
+  LOG_D(NR_PHY, "Entering oai_nfapi_nr_dl_config_req sfn:%d,slot:%d\n", dl_config_req->SFN, dl_config_req->Slot);
   nfapi_vnf_p7_config_t *p7_config = vnf.p7_vnfs[0].config;
   dl_config_req->header.message_id= NFAPI_NR_PHY_MSG_TYPE_DL_TTI_REQUEST;
   dl_config_req->header.phy_id = 1; // DJP HACK TODO FIXME - need to pass this around!!!!
@@ -1939,6 +1944,7 @@ int oai_nfapi_dl_tti_req(nfapi_nr_dl_tti_request_t *dl_config_req)
 
 int oai_nfapi_tx_data_req(nfapi_nr_tx_data_request_t *tx_data_req)
 {
+  LOG_D(NR_PHY, "Entering oai_nfapi_nr_tx_data_req sfn:%d,slot:%d\n", tx_data_req->SFN, tx_data_req->Slot);
   nfapi_vnf_p7_config_t *p7_config = vnf.p7_vnfs[0].config;
   tx_data_req->header.phy_id = 1; // DJP HACK TODO FIXME - need to pass this around!!!!
   tx_data_req->header.message_id = NFAPI_NR_PHY_MSG_TYPE_TX_DATA_REQUEST;
@@ -2056,7 +2062,7 @@ int oai_nfapi_ul_config_req(nfapi_ul_config_request_t *ul_config_req) {
   {
     uint8_t pdu_type = pdu_list[i].pdu_type;
 
-    LOG_I(MAC, "ul_config_req num_pdus: %u pdu_number: %d pdu_type: %u SFN.SF: %d.%d\n",
+    LOG_D(MAC, "ul_config_req num_pdus: %u pdu_number: %d pdu_type: %u SFN.SF: %d.%d\n",
           num_pdus, i, pdu_type, ul_config_req->sfn_sf >> 4, ul_config_req->sfn_sf & 15);
 
     if (pdu_type != NFAPI_UL_CONFIG_ULSCH_CQI_RI_PDU_TYPE)
diff --git a/nfapi/open-nFAPI/nfapi/inc/nfapi.h b/nfapi/open-nFAPI/nfapi/inc/nfapi.h
index 0f09efa78ab7d41032c4b3d68df3aac4e4c38139..c1f423a8db808fe8dd1140ff082afac10ff59bfb 100644
--- a/nfapi/open-nFAPI/nfapi/inc/nfapi.h
+++ b/nfapi/open-nFAPI/nfapi/inc/nfapi.h
@@ -44,13 +44,21 @@ uint8_t pulls32(uint8_t **in, int32_t *out, uint8_t *end);
 uint32_t pullarray8(uint8_t **in, uint8_t out[], uint32_t max_len, uint32_t len, uint8_t *end);
 uint32_t pullarray16(uint8_t **in, uint16_t out[], uint32_t max_len, uint32_t len, uint8_t *end);
 uint32_t pullarrays16(uint8_t **in, int16_t out[], uint32_t max_len, uint32_t len, uint8_t *end);
-uint32_t pullarray32(uint8_t **in, uint32_t out[], uint32_t max_len, uint32_t len, uint8_t *end);
+uint32_t pullarray32(uint8_t **values_to_pull,
+                     uint32_t out[],
+                     uint32_t max_num_values_to_pull,
+                     uint32_t num_values_to_pull,
+                     uint8_t *out_end);
 uint32_t pullarrays32(uint8_t **in, int32_t out[], uint32_t max_len, uint32_t len, uint8_t *end);
 
 uint32_t pusharray8(uint8_t in[], uint32_t max_len, uint32_t len, uint8_t **out, uint8_t *end);
 uint32_t pusharray16(uint16_t in[], uint32_t max_len, uint32_t len, uint8_t **out, uint8_t *end);
 uint32_t pusharrays16(int16_t in[], uint32_t max_len, uint32_t len, uint8_t **out, uint8_t *end);
-uint32_t pusharray32(uint32_t in[], uint32_t max_len, uint32_t len, uint8_t **out, uint8_t *end);
+uint32_t pusharray32(const uint32_t *values_to_push,
+                     uint32_t max_num_values_to_push,
+                     uint32_t num_values_to_push,
+                     uint8_t **out,
+                     uint8_t *out_end);
 uint32_t pusharrays32(int32_t in[], uint32_t max_len, uint32_t len, uint8_t **out, uint8_t *end);
 
 typedef uint8_t (*pack_array_elem_fn)(void* elem, uint8_t **ppWritePackedMsg, uint8_t *end);
diff --git a/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h b/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h
index 284ef22fc4c8fe9f72007c82aee0e3a63d49930e..5f8a856028ca212a2aa612da244d3af67988e555 100644
--- a/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h
+++ b/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h
@@ -464,7 +464,8 @@ typedef struct {
   uint8_t nEpreRatioOfPDSCHToPTRS;
   /// MCS table for this DLSCH
   uint8_t mcs_table;
-
+  uint8_t nscid;
+  uint16_t dlDmrsScramblingId;
   uint16_t pduBitmap;
 } fapi_nr_dl_config_dlsch_pdu_rel15_t;
 
diff --git a/nfapi/open-nFAPI/nfapi/src/nfapi.c b/nfapi/open-nFAPI/nfapi/src/nfapi.c
index 2783781e2c39b9ceb46d00df2609bb087b453194..09c0229db0bbe528f9c97759a414173e8b970c93 100644
--- a/nfapi/open-nFAPI/nfapi/src/nfapi.c
+++ b/nfapi/open-nFAPI/nfapi/src/nfapi.c
@@ -1,783 +1,855 @@
-/*
- * Copyright (c) 2001-2016, Cisco Systems, Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials provided
- * with the distribution.
- *
- * Neither the name of the Cisco Systems, Inc. nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <signal.h>
-#include <sys/time.h>
-#include <sys/socket.h>
-#include <sys/types.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <sched.h>
-#include <time.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <errno.h>
-#include <pthread.h>
-
-#include <nfapi_interface.h>
-#include <nfapi.h>
-#include <debug.h>
-
-
-// Fundamental routines
-
-uint8_t push8(uint8_t in, uint8_t **out, uint8_t *end) {
-  uint8_t *pOut = *out;
-
-  if((end - pOut) >= 1) {
-    pOut[0] = in;
-    (*out)+=1;
-    return 1;
-  } else {
-    NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__);
-    return 0;
-  }
-}
-
-uint8_t pushs8(int8_t in, uint8_t **out, uint8_t *end) {
-  uint8_t *pOut = *out;
-
-  if((end - pOut) >= 1) {
-    pOut[0] = in;
-    (*out)+=1;
-    return 1;
-  } else {
-    NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__);
-    return 0;
-  }
-}
-
-uint8_t push16(uint16_t in, uint8_t **out, uint8_t *end) {
-  uint8_t *pOut = *out;
-
-  if((end - pOut) >= 2) {
-    pOut[0] = (in & 0xFF00) >> 8;
-    pOut[1] = (in & 0xFF);
-    (*out)+=2;
-    return 2;
-  } else {
-    NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__);
-    return 0;
-  }
-}
-
-uint8_t pushs16(int16_t in, uint8_t **out, uint8_t *end) {
-  uint8_t *pOut = *out;
-
-  if((end - pOut) >= 2) {
-    pOut[0] = (in & 0xFF00) >> 8;
-    pOut[1] = (in & 0xFF);
-    (*out)+=2;
-    return 2;
-  } else {
-    NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__);
-    return 0;
-  }
-}
-
-uint8_t push32(uint32_t in, uint8_t **out, uint8_t *end) {
-  uint8_t *pOut = *out;
-
-  if((end - pOut) >= 4) {
-    pOut[0] = (in & 0xFF000000) >> 24;
-    pOut[1] = (in & 0xFF0000) >> 16;
-    pOut[2] = (in & 0xFF00) >> 8;
-    pOut[3] = (in & 0xFF);
-    (*out)+=4;
-    return 4;
-  } else {
-    NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__);
-    return 0;
-  }
-}
-
-uint8_t pushs32(int32_t in, uint8_t **out, uint8_t *end) {
-  uint8_t *pOut = *out;
-
-  if((end - pOut) >= 4) {
-    pOut[0] = (in & 0xFF000000) >> 24;
-    pOut[1] = (in & 0xFF0000) >> 16;
-    pOut[2] = (in & 0xFF00) >> 8;
-    pOut[3] = (in & 0xFF);
-    (*out)+=4;
-    return 4;
-  } else {
-    NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__);
-    return 0;
-  }
-}
-
-uint8_t pull8(uint8_t **in, uint8_t *out, uint8_t *end) {
-  uint8_t *pIn = *in;
-
-  if((end - pIn) >= 1 ) {
-    *out = *pIn;
-    (*in)+=1;
-    return 1;
-  } else {
-    NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__);
-    return 0;
-  }
-}
-
-uint8_t pulls8(uint8_t **in, int8_t *out, uint8_t *end) {
-  uint8_t *pIn = *in;
-
-  if((end - pIn) >= 1 ) {
-    *out = *pIn;
-    (*in)+=1;
-    return 1;
-  } else {
-    NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__);
-    return 0;
-  }
-}
-
-uint8_t pull16(uint8_t **in, uint16_t *out, uint8_t *end) {
-  uint8_t *pIn = *in;
-
-  if((end - pIn) >=2 ) {
-    *out = ((pIn[0]) << 8) | pIn[1];
-    (*in)+=2;
-    return 2;
-  } else {
-    NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__);
-    return 0;
-  }
-}
-
-uint8_t pulls16(uint8_t **in, int16_t *out, uint8_t *end) {
-  uint8_t *pIn = *in;
-
-  if((end - pIn) >=2 ) {
-    *out = ((pIn[0]) << 8) | pIn[1];
-    (*in)+=2;
-    return 2;
-  } else {
-    NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__);
-    return 0;
-  }
-}
-
-uint8_t pull32(uint8_t **in, uint32_t *out, uint8_t *end) {
-  uint8_t *pIn = *in;
-
-  if((end - pIn) >=4 ) {
-    *out = (pIn[0] << 24) | (pIn[1] << 16) | (pIn[2] << 8) | pIn[3];
-    (*in)+=4;
-    return 4;
-  } else {
-    NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n",  __FUNCTION__);
-    return 0;
-  }
-}
-
-uint8_t pulls32(uint8_t **in, int32_t *out, uint8_t *end) {
-  uint8_t *pIn = *in;
-
-  if((end - pIn) >=4 ) {
-    *out = (pIn[0] << 24) | (pIn[1] << 16) | (pIn[2] << 8) | pIn[3];
-    (*in)+=4;
-    return 4;
-  } else {
-    NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__);
-    return 0;
-  }
-}
-
-/*
-inline void pusharray16(uint8_t **, uint16_t, uint32_t len)
-{
-}
-*/
-
-uint32_t pullarray16(uint8_t **in, uint16_t out[], uint32_t max_len, uint32_t len, uint8_t *end) {
-  if(len == 0)
-    return 1;
-
-  if(len > max_len) {
-    NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s exceed array size (%d > %d)\n", __FUNCTION__, len, max_len);
-    return 0;
-  }
-
-  if((end - (*in)) >= sizeof(uint16_t) * len) {
-    uint32_t idx;
-
-    for(idx = 0; idx < len; ++idx) {
-      if(!pull16(in, &out[idx], end))
-        return 0;
-    }
-
-    return sizeof(uint16_t) * len;
-  } else {
-    NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__);
-    return 0;
-  }
-}
-
-uint32_t pullarrays16(uint8_t **in, int16_t out[], uint32_t max_len, uint32_t len, uint8_t *end) {
-  if(len == 0)
-    return 1;
-
-  if(len > max_len) {
-    NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s exceed array size (%d > %d)\n", __FUNCTION__, len, max_len);
-    return 0;
-  }
-
-  if((end - (*in)) >= sizeof(uint16_t) * len) {
-    uint32_t idx;
-
-    for(idx = 0; idx < len; ++idx) {
-      if(!pulls16(in, &out[idx], end))
-        return 0;
-    }
-
-    return sizeof(uint16_t) * len;
-  } else {
-    NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__);
-    return 0;
-  }
-}
-uint32_t pusharray16(uint16_t in[], uint32_t max_len, uint32_t len, uint8_t **out, uint8_t *end) {
-  if(len == 0)
-    return 1;
-
-  if(len > max_len) {
-    NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s exceed array size (%d > %d)\n", __FUNCTION__, len, max_len);
-    return 0;
-  }
-
-  if((end - (*out)) >= sizeof(uint16_t) * len) {
-    uint32_t idx;
-
-    for(idx = 0; idx < len; ++idx) {
-      if(!push16(in[idx], out, end))
-        return 0;
-    }
-
-    return sizeof(uint16_t) * len;
-  } else {
-    NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__);
-    return 0;
-  }
-}
-uint32_t pusharrays16(int16_t in[], uint32_t max_len, uint32_t len, uint8_t **out, uint8_t *end) {
-  if(len == 0)
-    return 1;
-
-  if(len > max_len) {
-    NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s exceed array size (%d > %d)\n", __FUNCTION__, len, max_len);
-    return 0;
-  }
-
-  if((end - (*out)) >= sizeof(uint16_t) * len) {
-    uint32_t idx;
-
-    for(idx = 0; idx < len; ++idx) {
-      pushs16(in[idx], out, end);
-    }
-
-    return sizeof(uint16_t) * len;
-  } else {
-    NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__);
-    return 0;
-  }
-}
-uint32_t pullarray32(uint8_t **in, uint32_t out[], uint32_t max_len, uint32_t len, uint8_t *end) {
-  if(len == 0)
-    return 1;
-
-  if(len > max_len) {
-    NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s exceed array size (%d > %d)\n", __FUNCTION__, len, max_len);
-    return 0;
-  }
-
-  if((end - (*in)) >= sizeof(uint32_t) * len) {
-    uint32_t idx;
-
-    for(idx = 0; idx < len; ++idx) {
-      if(!pull32(in, &out[idx], end))
-        return 0;
-    }
-
-    return sizeof(uint32_t) * len;
-  } else {
-    NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__);
-    return 0;
-  }
-}
-
-uint32_t pullarrays32(uint8_t **in, int32_t out[], uint32_t max_len, uint32_t len, uint8_t *end) {
-  if(len == 0)
-    return 1;
-
-  if(len > max_len) {
-    NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s exceed array size (%d > %d)\n", __FUNCTION__, len, max_len);
-    return 0;
-  }
-
-  if((end - (*in)) >= sizeof(uint32_t) * len) {
-    uint32_t idx;
-
-    for(idx = 0; idx < len; ++idx) {
-      if(!pulls32(in, &out[idx], end))
-        return 0;
-    }
-
-    return sizeof(uint32_t) * len;
-  } else {
-    NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__);
-    return 0;
-  }
-}
-uint32_t pusharray32(uint32_t in[], uint32_t max_len, uint32_t len, uint8_t **out, uint8_t *end) {
-  if(len == 0)
-    return 1;
-
-  if(len > max_len) {
-    NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s exceed array size (%d > %d)\n", __FUNCTION__, len, max_len);
-    return 0;
-  }
-
-  if((end - (*out)) >= sizeof(uint32_t) * len) {
-    uint32_t idx;
-
-    for(idx = 0; idx < len; ++idx) {
-      if(!push32(in[idx], out, end))
-        return 0;
-    }
-
-    return sizeof(uint32_t) * len;
-  } else {
-    NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__);
-    return 0;
-  }
-}
-uint32_t pusharrays32(int32_t in[], uint32_t max_len, uint32_t len, uint8_t **out, uint8_t *end) {
-  if(len == 0)
-    return 1;
-
-  if(len > max_len) {
-    NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s exceed array size (%d > %d)\n", __FUNCTION__, len, max_len);
-    return 0;
-  }
-
-  if((end - (*out)) >= sizeof(uint32_t) * len) {
-    uint32_t idx;
-
-    for(idx = 0; idx < len; ++idx) {
-      pushs32(in[idx], out, end);
-    }
-
-    return sizeof(uint32_t) * len;
-  } else {
-    NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__);
-    return 0;
-  }
-}
-uint32_t pullarray8(uint8_t **in, uint8_t out[], uint32_t max_len, uint32_t len, uint8_t *end) {
-  if(len == 0)
-    return 1;
-
-  if(len > max_len) {
-    NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s exceed array size (%d > %d)\n", __FUNCTION__, len, max_len);
-    return 0;
-  }
-
-  if((end - (*in)) >= sizeof(uint8_t) * len) {
-    memcpy(out, (*in), len);
-    (*in)+=len;
-    return sizeof(uint8_t) * len;
-  } else {
-    NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__);
-    return 0;
-  }
-}
-
-uint32_t pusharray8(uint8_t in[], uint32_t max_len, uint32_t len, uint8_t **out, uint8_t *end) {
-  if(len == 0)
-    return 1;
-
-  if(len > max_len) {
-    NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s exceed array size (%d > %d)\n", __FUNCTION__, len, max_len);
-    return 0;
-  }
-
-  if((end - (*out)) >= sizeof(uint8_t) * len) {
-    memcpy((*out), in, len);
-    (*out)+=len;
-    return sizeof(uint8_t) * len;
-  } else {
-    NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__);
-    return 0;
-  }
-}
-
-uint8_t packarray(void *array, uint16_t array_element_size, uint16_t max_count, uint16_t count, uint8_t **ppwritepackedmsg, uint8_t *end, pack_array_elem_fn fn) {
-  if(count > max_count) {
-    NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s exceed array size (%d > %d)\n", __FUNCTION__, count, max_count);
-    return 0;
-  }
-
-  uint16_t i = 0;
-
-  for(i = 0; i < count; ++i) {
-    if((fn)(array, ppwritepackedmsg, end) == 0)
-      return 0;
-
-    array += array_element_size;
-  }
-
-  return 1;
-}
-
-uint8_t unpackarray(uint8_t **ppReadPackedMsg, void *array, uint16_t array_element_size, uint16_t max_count, uint16_t count, uint8_t *end, unpack_array_elem_fn fn) {
-  if(count > max_count) {
-    NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s exceed array size (%d > %d)\n", __FUNCTION__, count, max_count);
-    return 0;
-  }
-
-  uint16_t i = 0;
-
-  for(i = 0; i < count; ++i) {
-    if((fn)(array, ppReadPackedMsg, end) == 0)
-      return 0;
-
-    array += array_element_size;
-  }
-
-  return 1;
-}
-
-
-uint32_t pack_vendor_extension_tlv(nfapi_tl_t *ve, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t *config) {
-  if(ve != 0 && config != 0) {
-    if(config->pack_vendor_extension_tlv) {
-      uint8_t *pStartOfTlv = *ppWritePackedMsg;
-
-      if(pack_tl(ve, ppWritePackedMsg, end) == 0)
-        return 0;
-
-      uint8_t *pStartOfValue = *ppWritePackedMsg;
-
-      if((config->pack_vendor_extension_tlv)(ve, ppWritePackedMsg, end, config) == 0)
-        return 0;
-
-      ve->length = (*ppWritePackedMsg) - pStartOfValue;
-      pack_tl(ve, &pStartOfTlv, end);
-      return 1;
-    }
-  }
-
-  return 1;
-}
-
-uint32_t unpack_vendor_extension_tlv(nfapi_tl_t *tl, uint8_t **ppReadPackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t *config, nfapi_tl_t **ve_tlv) {
-  if(ve_tlv != 0 && config != 0) {
-    if(config->unpack_vendor_extension_tlv) {
-      return (config->unpack_vendor_extension_tlv)(tl, ppReadPackedMsg, end, (void **)ve_tlv, config);
-    }
-  }
-
-  return 1;
-}
-
-uint32_t pack_p7_vendor_extension_tlv(nfapi_tl_t *ve, uint8_t **ppWritePackedMsg, uint8_t *end,nfapi_p7_codec_config_t *config) {
-  if(ve != 0 && config != 0) {
-    if(config->pack_vendor_extension_tlv) {
-      uint8_t *pStartOfTlv = *ppWritePackedMsg;
-
-      if(pack_tl(ve, ppWritePackedMsg, end) == 0)
-        return 0;
-
-      uint8_t *pStartOfValue = *ppWritePackedMsg;
-
-      if((config->pack_vendor_extension_tlv)(ve, ppWritePackedMsg, end, config) == 0)
-        return 0;
-
-      ve->length = (*ppWritePackedMsg) - pStartOfValue;
-      pack_tl(ve, &pStartOfTlv, end);
-      return 1;
-    }
-  }
-
-  return 1;
-}
-
-int unpack_p7_vendor_extension_tlv(nfapi_tl_t *tl, uint8_t **ppReadPackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config, nfapi_tl_t **ve_tlv) {
-  if(ve_tlv != 0 && config != 0) {
-    if(config->unpack_vendor_extension_tlv) {
-      return (config->unpack_vendor_extension_tlv)(tl, ppReadPackedMsg, end, (void **)ve_tlv, config);
-    }
-  }
-
-  return 1;
-}
-
-
-uint8_t pack_tl(nfapi_tl_t *tl, uint8_t **ppWritePackedMsg, uint8_t *end) {
-  return (push16(tl->tag, ppWritePackedMsg, end) &&
-          push16(tl->length, ppWritePackedMsg, end));
-}
-
-uint8_t unpack_tl(uint8_t **ppReadPackedMsg, nfapi_tl_t *tl, uint8_t *end) {
-  return (pull16(ppReadPackedMsg, &tl->tag, end) &&
-          pull16(ppReadPackedMsg, &tl->length, end));
-}
-
-int unpack_tlv_list(unpack_tlv_t unpack_fns[], uint16_t size, uint8_t **ppReadPackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t *config, nfapi_tl_t **ve) {
-  nfapi_tl_t generic_tl;
-  uint8_t numBadTags = 0;
-  uint16_t idx = 0;
-
-  while ((uint8_t *)(*ppReadPackedMsg) < end) {
-    // unpack the tl and process the values accordingly
-    if(unpack_tl(ppReadPackedMsg, &generic_tl, end) == 0)
-      return 0;
-
-    uint8_t tagMatch = 0;
-    uint8_t *pStartOfValue = *ppReadPackedMsg;
-
-    for(idx = 0; idx < size; ++idx) {
-      if(unpack_fns[idx].tag == generic_tl.tag) { // match the extracted tag value with all the tags in unpack_fn list
-        tagMatch = 1;
-        nfapi_tl_t *tl = (nfapi_tl_t *)(unpack_fns[idx].tlv);
-        tl->tag = generic_tl.tag;
-        tl->length = generic_tl.length;
-        int result = (*unpack_fns[idx].unpack_func)(tl, ppReadPackedMsg, end);
-
-        if(result == 0) {
-          return 0;
-        }
-
-        // check if the length was right;
-        if(tl->length != (*ppReadPackedMsg - pStartOfValue)) {
-          NFAPI_TRACE(NFAPI_TRACE_ERROR, "Warning tlv tag 0x%x length %d not equal to unpack %ld\n", tl->tag, tl->length, (*ppReadPackedMsg - pStartOfValue));
-        }
-      }
-    }
-
-    if(tagMatch == 0) {
-      if(generic_tl.tag >= NFAPI_VENDOR_EXTENSION_MIN_TAG_VALUE &&
-          generic_tl.tag <= NFAPI_VENDOR_EXTENSION_MAX_TAG_VALUE) {
-        int result = unpack_vendor_extension_tlv(&generic_tl, ppReadPackedMsg, end, config, ve);
-
-        if(result == 0) {
-          // got tot the end.
-          return 0;
-        } else if(result < 0) {
-          NFAPI_TRACE(NFAPI_TRACE_ERROR, "Unknown VE TAG value: 0x%04x\n", generic_tl.tag);
-
-          if (++numBadTags > MAX_BAD_TAG) {
-            NFAPI_TRACE(NFAPI_TRACE_ERROR, "Supplied message has had too many bad tags\n");
-            return 0;
-          }
-
-          if((end - *ppReadPackedMsg) >= generic_tl.length) {
-            // Advance past the unknown TLV
-            (*ppReadPackedMsg) += generic_tl.length;
-          } else {
-            // go to the end
-            return 0;
-          }
-        }
-      } else {
-        NFAPI_TRACE(NFAPI_TRACE_ERROR, "Unknown TAG value: 0x%04x\n", generic_tl.tag);
-
-        if (++numBadTags > MAX_BAD_TAG) {
-          NFAPI_TRACE(NFAPI_TRACE_ERROR, "Supplied message has had too many bad tags\n");
-          return 0;
-        }
-
-        if((end - *ppReadPackedMsg) >= generic_tl.length) {
-          // Advance past the unknown TLV
-          (*ppReadPackedMsg) += generic_tl.length;
-        } else {
-          // go to the end
-          return 0;
-        }
-      }
-    }
-  }
-
-  return 1;
-}
-int unpack_p7_tlv_list(unpack_p7_tlv_t unpack_fns[], uint16_t size, uint8_t **ppReadPackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config, nfapi_tl_t **ve) {
-  nfapi_tl_t generic_tl;
-  uint8_t numBadTags = 0;
-  uint16_t idx = 0;
-
-  while ((uint8_t *)(*ppReadPackedMsg) < end) {
-    // unpack the tl and process the values accordingly
-    if(unpack_tl(ppReadPackedMsg, &generic_tl, end) == 0)
-      return 0;
-
-    uint8_t tagMatch = 0;
-    uint8_t *pStartOfValue = *ppReadPackedMsg;
-
-    for(idx = 0; idx < size; ++idx) {
-      if(unpack_fns[idx].tag == generic_tl.tag) {
-        tagMatch = 1;
-        nfapi_tl_t *tl = (nfapi_tl_t *)(unpack_fns[idx].tlv);
-        tl->tag = generic_tl.tag;
-        tl->length = generic_tl.length;
-        int result = (*unpack_fns[idx].unpack_func)(tl, ppReadPackedMsg, end, config);
-
-        if(result == 0) {
-          return  0;
-        }
-
-        // check if the length was right;
-        if(tl->length != (*ppReadPackedMsg - pStartOfValue)) {
-          NFAPI_TRACE(NFAPI_TRACE_ERROR, "Warning tlv tag 0x%x length %d not equal to unpack %ld\n", tl->tag, tl->length, (*ppReadPackedMsg - pStartOfValue));
-        }
-      }
-    }
-
-    if(tagMatch == 0) {
-      if(generic_tl.tag >= NFAPI_VENDOR_EXTENSION_MIN_TAG_VALUE &&
-          generic_tl.tag <= NFAPI_VENDOR_EXTENSION_MAX_TAG_VALUE) {
-        int result = unpack_p7_vendor_extension_tlv(&generic_tl, ppReadPackedMsg, end, config, ve);
-
-        if(result == 0) {
-          // got to end
-          return 0;
-        } else if(result < 0) {
-          NFAPI_TRACE(NFAPI_TRACE_ERROR, "Unknown TAG value: 0x%04x\n", generic_tl.tag);
-
-          if (++numBadTags > MAX_BAD_TAG) {
-            NFAPI_TRACE(NFAPI_TRACE_ERROR, "Supplied message has had too many bad tags\n");
-            return -1;
-          }
-
-          if((end - *ppReadPackedMsg) >= generic_tl.length) {
-            // Advance past the unknown TLV
-            (*ppReadPackedMsg) += generic_tl.length;
-          } else {
-            // got ot the dn
-            return 0;
-          }
-        }
-      } else {
-        NFAPI_TRACE(NFAPI_TRACE_ERROR, "Unknown TAG value: 0x%04x\n", generic_tl.tag);
-
-        if (++numBadTags > MAX_BAD_TAG) {
-          NFAPI_TRACE(NFAPI_TRACE_ERROR, "Supplied message has had too many bad tags\n");
-          return -1;
-        }
-
-        if((end - *ppReadPackedMsg) >= generic_tl.length) {
-          // Advance past the unknown TLV
-          (*ppReadPackedMsg) += generic_tl.length;
-        } else {
-          // got ot the dn
-          return 0;
-        }
-      }
-    }
-  }
-
-  return 1;
-}
-
-// This intermediate function deals with calculating the length of the value
-// and writing into the tlv header.
-uint8_t pack_tlv(uint16_t tag, void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end, pack_tlv_fn fn) {
-  nfapi_tl_t *tl = (nfapi_tl_t *)tlv;
-
-  // If the tag is defined
-  if(tl->tag == tag) {
-    uint8_t *pStartOfTlv = *ppWritePackedMsg;
-
-    // write a dumy tlv header
-    if(pack_tl(tl, ppWritePackedMsg, end) == 0)
-      return 0;
-
-    // Record the start of the value
-    uint8_t *pStartOfValue = *ppWritePackedMsg;
-
-    // pack the tlv value
-    if(fn(tlv, ppWritePackedMsg, end) == 0)
-      return 0;
-
-    // calculate the length of the value and rewrite the tl header
-    tl->length = (*ppWritePackedMsg) - pStartOfValue;
-    // rewrite the header with the correct length
-    pack_tl(tl, &pStartOfTlv, end);
-  } else {
-    if(tl->tag != 0) {
-      NFAPI_TRACE(NFAPI_TRACE_WARN, "Warning pack_tlv tag 0x%x does not match expected 0x%x\n", tl->tag, tag);
-    } else {
-      //NFAPI_TRACE(NFAPI_TRACE_ERROR, "Warning pack_tlv tag 0x%x ZERO does not match expected 0x%x\n", tl->tag, tag);
-    }
-  }
-
-  return 1;
-}
-
-const char *nfapi_error_code_to_str(nfapi_error_code_e value) {
-  switch(value) {
-    case NFAPI_MSG_OK:
-      return "NFAPI_MSG_OK";
-
-    case NFAPI_MSG_INVALID_STATE:
-      return "NFAPI_MSG_INVALID_STATE";
-
-    case NFAPI_MSG_INVALID_CONFIG:
-      return "NFAPI_MSG_INVALID_CONFIG";
-
-    case NFAPI_SFN_OUT_OF_SYNC:
-      return "NFAPI_SFN_OUT_OF_SYNC";
-
-    case NFAPI_MSG_SUBFRAME_ERR:
-      return "NFAPI_MSG_SUBFRAME_ERR";
-
-    case NFAPI_MSG_BCH_MISSING:
-      return "NFAPI_MSG_BCH_MISSING";
-
-    case NFAPI_MSG_INVALID_SFN:
-      return "NFAPI_MSG_INVALID_SFN";
-
-    case NFAPI_MSG_HI_ERR:
-      return "NFAPI_MSG_HI_ERR";
-
-    case NFAPI_MSG_TX_ERR:
-      return "NFAPI_MSG_TX_ERR";
-
-    default:
-      return "UNKNOWN";
-  }
-}
+/*
+ * Copyright (c) 2001-2016, Cisco Systems, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ *
+ * Neither the name of the Cisco Systems, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <signal.h>
+#include <sys/time.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <sched.h>
+#include <time.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+#include <pthread.h>
+#include <execinfo.h>
+
+#include <nfapi_interface.h>
+#include <nfapi.h>
+#include <debug.h>
+
+// What to do when an error happens (e.g., a push or pull fails)
+static inline void on_error()
+{
+    // show the call stack
+    int fd = STDERR_FILENO;
+    static const char msg[] = "---stack trace---\n";
+    __attribute__((unused)) int r =
+        write(fd, msg, sizeof(msg) - 1);
+    void *buffer[100];
+    int nptrs = backtrace(buffer, sizeof(buffer) / sizeof(buffer[0]));
+    backtrace_symbols_fd(buffer, nptrs, fd);
+
+    //abort();
+}
+
+// Fundamental routines
+
+uint8_t push8(uint8_t in, uint8_t **out, uint8_t *end) {
+  uint8_t *pOut = *out;
+
+  if((end - pOut) >= 1) {
+    pOut[0] = in;
+    (*out)+=1;
+    return 1;
+  } else {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__);
+    on_error();
+    return 0;
+  }
+}
+
+uint8_t pushs8(int8_t in, uint8_t **out, uint8_t *end) {
+  uint8_t *pOut = *out;
+
+  if((end - pOut) >= 1) {
+    pOut[0] = in;
+    (*out)+=1;
+    return 1;
+  } else {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__);
+    on_error();
+    return 0;
+  }
+}
+
+uint8_t push16(uint16_t in, uint8_t **out, uint8_t *end) {
+  uint8_t *pOut = *out;
+
+  if((end - pOut) >= 2) {
+    pOut[0] = (in & 0xFF00) >> 8;
+    pOut[1] = (in & 0xFF);
+    (*out)+=2;
+    return 2;
+  } else {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__);
+    on_error();
+    return 0;
+  }
+}
+
+uint8_t pushs16(int16_t in, uint8_t **out, uint8_t *end) {
+  uint8_t *pOut = *out;
+
+  if((end - pOut) >= 2) {
+    pOut[0] = (in & 0xFF00) >> 8;
+    pOut[1] = (in & 0xFF);
+    (*out)+=2;
+    return 2;
+  } else {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__);
+    on_error();
+    return 0;
+  }
+}
+
+uint8_t push32(uint32_t in, uint8_t **out, uint8_t *end) {
+  uint8_t *pOut = *out;
+
+  if((end - pOut) >= 4) {
+    pOut[0] = (in & 0xFF000000) >> 24;
+    pOut[1] = (in & 0xFF0000) >> 16;
+    pOut[2] = (in & 0xFF00) >> 8;
+    pOut[3] = (in & 0xFF);
+    (*out)+=4;
+    return 4;
+  } else {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__);
+    on_error();
+    return 0;
+  }
+}
+
+uint8_t pushs32(int32_t in, uint8_t **out, uint8_t *end) {
+  uint8_t *pOut = *out;
+
+  if((end - pOut) >= 4) {
+    pOut[0] = (in & 0xFF000000) >> 24;
+    pOut[1] = (in & 0xFF0000) >> 16;
+    pOut[2] = (in & 0xFF00) >> 8;
+    pOut[3] = (in & 0xFF);
+    (*out)+=4;
+    return 4;
+  } else {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__);
+    on_error();
+    return 0;
+  }
+}
+
+uint8_t pull8(uint8_t **in, uint8_t *out, uint8_t *end) {
+  uint8_t *pIn = *in;
+
+  if((end - pIn) >= 1 ) {
+    *out = *pIn;
+    (*in)+=1;
+    return 1;
+  } else {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__);
+    on_error();
+    return 0;
+  }
+}
+
+uint8_t pulls8(uint8_t **in, int8_t *out, uint8_t *end) {
+  uint8_t *pIn = *in;
+
+  if((end - pIn) >= 1 ) {
+    *out = *pIn;
+    (*in)+=1;
+    return 1;
+  } else {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__);
+    on_error();
+    return 0;
+  }
+}
+
+uint8_t pull16(uint8_t **in, uint16_t *out, uint8_t *end) {
+  uint8_t *pIn = *in;
+
+  if((end - pIn) >=2 ) {
+    *out = ((pIn[0]) << 8) | pIn[1];
+    (*in)+=2;
+    return 2;
+  } else {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__);
+    on_error();
+    return 0;
+  }
+}
+
+uint8_t pulls16(uint8_t **in, int16_t *out, uint8_t *end) {
+  uint8_t *pIn = *in;
+
+  if((end - pIn) >=2 ) {
+    *out = ((pIn[0]) << 8) | pIn[1];
+    (*in)+=2;
+    return 2;
+  } else {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__);
+    on_error();
+    return 0;
+  }
+}
+
+uint8_t pull32(uint8_t **in, uint32_t *out, uint8_t *end) {
+  uint8_t *pIn = *in;
+
+  if((end - pIn) >=4 ) {
+    *out = (pIn[0] << 24) | (pIn[1] << 16) | (pIn[2] << 8) | pIn[3];
+    (*in)+=4;
+    return 4;
+  } else {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n",  __FUNCTION__);
+    on_error();
+    return 0;
+  }
+}
+
+uint8_t pulls32(uint8_t **in, int32_t *out, uint8_t *end) {
+  uint8_t *pIn = *in;
+
+  if((end - pIn) >=4 ) {
+    *out = (pIn[0] << 24) | (pIn[1] << 16) | (pIn[2] << 8) | pIn[3];
+    (*in)+=4;
+    return 4;
+  } else {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__);
+    on_error();
+    return 0;
+  }
+}
+
+/*
+inline void pusharray16(uint8_t **, uint16_t, uint32_t len)
+{
+}
+*/
+
+uint32_t pullarray16(uint8_t **in, uint16_t out[], uint32_t max_len, uint32_t len, uint8_t *end) {
+  if(len == 0)
+    return 1;
+
+  if(len > max_len) {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s exceed array size (%d > %d)\n", __FUNCTION__, len, max_len);
+    on_error();
+    return 0;
+  }
+
+  if((end - (*in)) >= sizeof(uint16_t) * len) {
+    uint32_t idx;
+
+    for(idx = 0; idx < len; ++idx) {
+      if(!pull16(in, &out[idx], end))
+        return 0;
+    }
+
+    return sizeof(uint16_t) * len;
+  } else {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__);
+    on_error();
+    return 0;
+  }
+}
+
+uint32_t pullarrays16(uint8_t **in, int16_t out[], uint32_t max_len, uint32_t len, uint8_t *end) {
+  if(len == 0)
+    return 1;
+
+  if(len > max_len) {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s exceed array size (%d > %d)\n", __FUNCTION__, len, max_len);
+    on_error();
+    return 0;
+  }
+
+  if((end - (*in)) >= sizeof(uint16_t) * len) {
+    uint32_t idx;
+
+    for(idx = 0; idx < len; ++idx) {
+      if(!pulls16(in, &out[idx], end))
+        return 0;
+    }
+
+    return sizeof(uint16_t) * len;
+  } else {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__);
+    on_error();
+    return 0;
+  }
+}
+uint32_t pusharray16(uint16_t in[], uint32_t max_len, uint32_t len, uint8_t **out, uint8_t *end) {
+  if(len == 0)
+    return 1;
+
+  if(len > max_len) {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s exceed array size (%d > %d)\n", __FUNCTION__, len, max_len);
+    on_error();
+    return 0;
+  }
+
+  if((end - (*out)) >= sizeof(uint16_t) * len) {
+    uint32_t idx;
+
+    for(idx = 0; idx < len; ++idx) {
+      if(!push16(in[idx], out, end))
+        return 0;
+    }
+
+    return sizeof(uint16_t) * len;
+  } else {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__);
+    on_error();
+    return 0;
+  }
+}
+uint32_t pusharrays16(int16_t in[], uint32_t max_len, uint32_t len, uint8_t **out, uint8_t *end) {
+  if(len == 0)
+    return 1;
+
+  if(len > max_len) {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s exceed array size (%d > %d)\n", __FUNCTION__, len, max_len);
+    on_error();
+    return 0;
+  }
+
+  if((end - (*out)) >= sizeof(uint16_t) * len) {
+    uint32_t idx;
+
+    for(idx = 0; idx < len; ++idx) {
+      if (!pushs16(in[idx], out, end))
+        return 0;
+    }
+
+    return sizeof(uint16_t) * len;
+  } else {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__);
+    on_error();
+    return 0;
+  }
+}
+uint32_t pullarray32(uint8_t **values_to_pull,
+                     uint32_t out[],
+                     uint32_t max_num_values_to_pull,
+                     uint32_t num_values_to_pull,
+                     uint8_t *out_end) {
+  if (num_values_to_pull == 0)
+
+    return 1;
+
+  if (num_values_to_pull > max_num_values_to_pull) {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s exceed array size (%d > %d)\n",
+                __FUNCTION__, num_values_to_pull, max_num_values_to_pull);
+    on_error();
+    return 0;
+  }
+
+  if ((out_end - (*values_to_pull)) >= sizeof(uint32_t) * num_values_to_pull) {
+    uint32_t idx;
+
+    for (idx = 0; idx < num_values_to_pull; ++idx) {
+      if (!pull32(values_to_pull, &out[idx], out_end))
+        return 0;
+    }
+
+    return sizeof(uint32_t) * num_values_to_pull;
+  } else {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__);
+    on_error();
+    return 0;
+  }
+}
+
+uint32_t pullarrays32(uint8_t **in, int32_t out[], uint32_t max_len, uint32_t len, uint8_t *end) {
+  if(len == 0)
+    return 1;
+
+  if(len > max_len) {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s exceed array size (%d > %d)\n", __FUNCTION__, len, max_len);
+    on_error();
+    return 0;
+  }
+
+  if((end - (*in)) >= sizeof(uint32_t) * len) {
+    uint32_t idx;
+
+    for(idx = 0; idx < len; ++idx) {
+      if(!pulls32(in, &out[idx], end))
+        return 0;
+    }
+
+    return sizeof(uint32_t) * len;
+  } else {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__);
+    on_error();
+    return 0;
+  }
+}
+uint32_t pusharray32(const uint32_t *values_to_push,
+                     uint32_t max_num_values_to_push,
+                     uint32_t num_values_to_push,
+                     uint8_t **out,
+                     uint8_t *out_end) {
+  if (num_values_to_push == 0)
+    return 1;
+
+  if (num_values_to_push > max_num_values_to_push) {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s exceed array size (%d > %d)\n",
+                __FUNCTION__, num_values_to_push, max_num_values_to_push);
+    on_error();
+    return 0;
+  }
+
+  if ((out_end - (*out)) >= sizeof(uint32_t) * num_values_to_push) {
+    uint32_t idx;
+
+    for (idx = 0; idx < num_values_to_push; ++idx) {
+      if (!push32(values_to_push[idx], out, out_end))
+        return 0;
+    }
+
+    return sizeof(uint32_t) * num_values_to_push;
+  } else {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__);
+    on_error();
+    return 0;
+  }
+}
+uint32_t pusharrays32(int32_t in[], uint32_t max_len, uint32_t len, uint8_t **out, uint8_t *end) {
+  if(len == 0)
+    return 1;
+
+  if(len > max_len) {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s exceed array size (%d > %d)\n", __FUNCTION__, len, max_len);
+    on_error();
+    return 0;
+  }
+
+  if((end - (*out)) >= sizeof(uint32_t) * len) {
+    uint32_t idx;
+
+    for(idx = 0; idx < len; ++idx) {
+      if (!pushs32(in[idx], out, end))
+        return 0;
+    }
+
+    return sizeof(uint32_t) * len;
+  } else {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__);
+    on_error();
+    return 0;
+  }
+}
+uint32_t pullarray8(uint8_t **in, uint8_t out[], uint32_t max_len, uint32_t len, uint8_t *end) {
+  if(len == 0)
+    return 1;
+
+  if(len > max_len) {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s exceed array size (%d > %d)\n", __FUNCTION__, len, max_len);
+    on_error();
+    return 0;
+  }
+
+  if((end - (*in)) >= sizeof(uint8_t) * len) {
+    memcpy(out, (*in), len);
+    (*in)+=len;
+    return sizeof(uint8_t) * len;
+  } else {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__);
+    on_error();
+    return 0;
+  }
+}
+
+uint32_t pusharray8(uint8_t in[], uint32_t max_len, uint32_t len, uint8_t **out, uint8_t *end) {
+  if(len == 0)
+    return 1;
+
+  if(len > max_len) {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s exceed array size (%d > %d)\n", __FUNCTION__, len, max_len);
+    on_error();
+    return 0;
+  }
+
+  if((end - (*out)) >= sizeof(uint8_t) * len) {
+    memcpy((*out), in, len);
+    (*out)+=len;
+    return sizeof(uint8_t) * len;
+  } else {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__);
+    on_error();
+    return 0;
+  }
+}
+
+uint8_t packarray(void *array, uint16_t array_element_size, uint16_t max_count, uint16_t count, uint8_t **ppwritepackedmsg, uint8_t *end, pack_array_elem_fn fn) {
+  if(count > max_count) {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s exceed array size (%d > %d)\n", __FUNCTION__, count, max_count);
+    on_error();
+    return 0;
+  }
+
+  uint16_t i = 0;
+
+  for(i = 0; i < count; ++i) {
+    if((fn)(array, ppwritepackedmsg, end) == 0)
+      return 0;
+
+    array += array_element_size;
+  }
+
+  return 1;
+}
+
+uint8_t unpackarray(uint8_t **ppReadPackedMsg, void *array, uint16_t array_element_size, uint16_t max_count, uint16_t count, uint8_t *end, unpack_array_elem_fn fn) {
+  if(count > max_count) {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s exceed array size (%d > %d)\n", __FUNCTION__, count, max_count);
+    on_error();
+    return 0;
+  }
+
+  uint16_t i = 0;
+
+  for(i = 0; i < count; ++i) {
+    if((fn)(array, ppReadPackedMsg, end) == 0)
+      return 0;
+
+    array += array_element_size;
+  }
+
+  return 1;
+}
+
+
+uint32_t pack_vendor_extension_tlv(nfapi_tl_t *ve, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t *config) {
+  if(ve != 0 && config != 0) {
+    if(config->pack_vendor_extension_tlv) {
+      uint8_t *pStartOfTlv = *ppWritePackedMsg;
+
+      if(pack_tl(ve, ppWritePackedMsg, end) == 0)
+        return 0;
+
+      uint8_t *pStartOfValue = *ppWritePackedMsg;
+
+      if((config->pack_vendor_extension_tlv)(ve, ppWritePackedMsg, end, config) == 0)
+        return 0;
+
+      ve->length = (*ppWritePackedMsg) - pStartOfValue;
+      pack_tl(ve, &pStartOfTlv, end);
+      return 1;
+    }
+  }
+
+  return 1;
+}
+
+uint32_t unpack_vendor_extension_tlv(nfapi_tl_t *tl, uint8_t **ppReadPackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t *config, nfapi_tl_t **ve_tlv) {
+  if(ve_tlv != 0 && config != 0) {
+    if(config->unpack_vendor_extension_tlv) {
+      return (config->unpack_vendor_extension_tlv)(tl, ppReadPackedMsg, end, (void **)ve_tlv, config);
+    }
+  }
+
+  return 1;
+}
+
+uint32_t pack_p7_vendor_extension_tlv(nfapi_tl_t *ve, uint8_t **ppWritePackedMsg, uint8_t *end,nfapi_p7_codec_config_t *config) {
+  if(ve != 0 && config != 0) {
+    if(config->pack_vendor_extension_tlv) {
+      uint8_t *pStartOfTlv = *ppWritePackedMsg;
+
+      if(pack_tl(ve, ppWritePackedMsg, end) == 0)
+        return 0;
+
+      uint8_t *pStartOfValue = *ppWritePackedMsg;
+
+      if((config->pack_vendor_extension_tlv)(ve, ppWritePackedMsg, end, config) == 0)
+        return 0;
+
+      ve->length = (*ppWritePackedMsg) - pStartOfValue;
+      pack_tl(ve, &pStartOfTlv, end);
+      return 1;
+    }
+  }
+
+  return 1;
+}
+
+int unpack_p7_vendor_extension_tlv(nfapi_tl_t *tl, uint8_t **ppReadPackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config, nfapi_tl_t **ve_tlv) {
+  if(ve_tlv != 0 && config != 0) {
+    if(config->unpack_vendor_extension_tlv) {
+      return (config->unpack_vendor_extension_tlv)(tl, ppReadPackedMsg, end, (void **)ve_tlv, config);
+    }
+  }
+
+  return 1;
+}
+
+
+uint8_t pack_tl(nfapi_tl_t *tl, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  return (push16(tl->tag, ppWritePackedMsg, end) &&
+          push16(tl->length, ppWritePackedMsg, end));
+}
+
+uint8_t unpack_tl(uint8_t **ppReadPackedMsg, nfapi_tl_t *tl, uint8_t *end) {
+  return (pull16(ppReadPackedMsg, &tl->tag, end) &&
+          pull16(ppReadPackedMsg, &tl->length, end));
+}
+
+int unpack_tlv_list(unpack_tlv_t unpack_fns[], uint16_t size, uint8_t **ppReadPackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t *config, nfapi_tl_t **ve) {
+  nfapi_tl_t generic_tl;
+  uint8_t numBadTags = 0;
+  uint16_t idx = 0;
+
+  while ((uint8_t *)(*ppReadPackedMsg) < end) {
+    // unpack the tl and process the values accordingly
+    if(unpack_tl(ppReadPackedMsg, &generic_tl, end) == 0)
+      return 0;
+
+    uint8_t tagMatch = 0;
+    uint8_t *pStartOfValue = *ppReadPackedMsg;
+
+    for(idx = 0; idx < size; ++idx) {
+      if(unpack_fns[idx].tag == generic_tl.tag) { // match the extracted tag value with all the tags in unpack_fn list
+        tagMatch = 1;
+        nfapi_tl_t *tl = (nfapi_tl_t *)(unpack_fns[idx].tlv);
+        tl->tag = generic_tl.tag;
+        tl->length = generic_tl.length;
+        int result = (*unpack_fns[idx].unpack_func)(tl, ppReadPackedMsg, end);
+
+        if(result == 0) {
+          return 0;
+        }
+
+        // check if the length was right;
+        if(tl->length != (*ppReadPackedMsg - pStartOfValue)) {
+          NFAPI_TRACE(NFAPI_TRACE_ERROR, "Warning tlv tag 0x%x length %d not equal to unpack %ld\n", tl->tag, tl->length, (*ppReadPackedMsg - pStartOfValue));
+          on_error();
+        }
+      }
+    }
+
+    if(tagMatch == 0) {
+      if(generic_tl.tag >= NFAPI_VENDOR_EXTENSION_MIN_TAG_VALUE &&
+          generic_tl.tag <= NFAPI_VENDOR_EXTENSION_MAX_TAG_VALUE) {
+        int result = unpack_vendor_extension_tlv(&generic_tl, ppReadPackedMsg, end, config, ve);
+
+        if(result == 0) {
+          // got tot the end.
+          return 0;
+        } else if(result < 0) {
+          NFAPI_TRACE(NFAPI_TRACE_ERROR, "Unknown VE TAG value: 0x%04x\n", generic_tl.tag);
+          on_error();
+
+          if (++numBadTags > MAX_BAD_TAG) {
+            NFAPI_TRACE(NFAPI_TRACE_ERROR, "Supplied message has had too many bad tags\n");
+            on_error();
+            return 0;
+          }
+
+          if((end - *ppReadPackedMsg) >= generic_tl.length) {
+            // Advance past the unknown TLV
+            (*ppReadPackedMsg) += generic_tl.length;
+          } else {
+            // go to the end
+            return 0;
+          }
+        }
+      } else {
+        NFAPI_TRACE(NFAPI_TRACE_ERROR, "Unknown TAG value: 0x%04x\n", generic_tl.tag);
+        on_error();
+
+        if (++numBadTags > MAX_BAD_TAG) {
+          NFAPI_TRACE(NFAPI_TRACE_ERROR, "Supplied message has had too many bad tags\n");
+          on_error();
+          return 0;
+        }
+
+        if((end - *ppReadPackedMsg) >= generic_tl.length) {
+          // Advance past the unknown TLV
+          (*ppReadPackedMsg) += generic_tl.length;
+        } else {
+          // go to the end
+          return 0;
+        }
+      }
+    }
+  }
+
+  return 1;
+}
+int unpack_p7_tlv_list(unpack_p7_tlv_t unpack_fns[], uint16_t size, uint8_t **ppReadPackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config, nfapi_tl_t **ve) {
+  nfapi_tl_t generic_tl;
+  uint8_t numBadTags = 0;
+  uint16_t idx = 0;
+
+  while ((uint8_t *)(*ppReadPackedMsg) < end) {
+    // unpack the tl and process the values accordingly
+    if(unpack_tl(ppReadPackedMsg, &generic_tl, end) == 0)
+      return 0;
+
+    uint8_t tagMatch = 0;
+    uint8_t *pStartOfValue = *ppReadPackedMsg;
+
+    for(idx = 0; idx < size; ++idx) {
+      if(unpack_fns[idx].tag == generic_tl.tag) {
+        tagMatch = 1;
+        nfapi_tl_t *tl = (nfapi_tl_t *)(unpack_fns[idx].tlv);
+        tl->tag = generic_tl.tag;
+        tl->length = generic_tl.length;
+        int result = (*unpack_fns[idx].unpack_func)(tl, ppReadPackedMsg, end, config);
+
+        if(result == 0) {
+          return  0;
+        }
+
+        // check if the length was right;
+        if(tl->length != (*ppReadPackedMsg - pStartOfValue)) {
+          NFAPI_TRACE(NFAPI_TRACE_ERROR, "Warning tlv tag 0x%x length %d not equal to unpack %ld\n", tl->tag, tl->length, (*ppReadPackedMsg - pStartOfValue));
+          on_error();
+        }
+      }
+    }
+
+    if(tagMatch == 0) {
+      if(generic_tl.tag >= NFAPI_VENDOR_EXTENSION_MIN_TAG_VALUE &&
+          generic_tl.tag <= NFAPI_VENDOR_EXTENSION_MAX_TAG_VALUE) {
+        int result = unpack_p7_vendor_extension_tlv(&generic_tl, ppReadPackedMsg, end, config, ve);
+
+        if(result == 0) {
+          // got to end
+          return 0;
+        } else if(result < 0) {
+          NFAPI_TRACE(NFAPI_TRACE_ERROR, "Unknown TAG value: 0x%04x\n", generic_tl.tag);
+          on_error();
+
+          if (++numBadTags > MAX_BAD_TAG) {
+            NFAPI_TRACE(NFAPI_TRACE_ERROR, "Supplied message has had too many bad tags\n");
+            on_error();
+            return -1;
+          }
+
+          if((end - *ppReadPackedMsg) >= generic_tl.length) {
+            // Advance past the unknown TLV
+            (*ppReadPackedMsg) += generic_tl.length;
+          } else {
+            // got ot the dn
+            return 0;
+          }
+        }
+      } else {
+        NFAPI_TRACE(NFAPI_TRACE_ERROR, "Unknown TAG value: 0x%04x\n", generic_tl.tag);
+        on_error();
+
+        if (++numBadTags > MAX_BAD_TAG) {
+          NFAPI_TRACE(NFAPI_TRACE_ERROR, "Supplied message has had too many bad tags\n");
+          on_error();
+          return -1;
+        }
+
+        if((end - *ppReadPackedMsg) >= generic_tl.length) {
+          // Advance past the unknown TLV
+          (*ppReadPackedMsg) += generic_tl.length;
+        } else {
+          // got ot the dn
+          return 0;
+        }
+      }
+    }
+  }
+
+  return 1;
+}
+
+// This intermediate function deals with calculating the length of the value
+// and writing into the tlv header.
+uint8_t pack_tlv(uint16_t tag, void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end, pack_tlv_fn fn) {
+  nfapi_tl_t *tl = (nfapi_tl_t *)tlv;
+
+  // If the tag is defined
+  if(tl->tag == tag) {
+    uint8_t *pStartOfTlv = *ppWritePackedMsg;
+
+    // write a dumy tlv header
+    if(pack_tl(tl, ppWritePackedMsg, end) == 0)
+      return 0;
+
+    // Record the start of the value
+    uint8_t *pStartOfValue = *ppWritePackedMsg;
+
+    // pack the tlv value
+    if(fn(tlv, ppWritePackedMsg, end) == 0)
+      return 0;
+
+    // calculate the length of the value and rewrite the tl header
+    tl->length = (*ppWritePackedMsg) - pStartOfValue;
+    // rewrite the header with the correct length
+    pack_tl(tl, &pStartOfTlv, end);
+  } else {
+    if(tl->tag != 0) {
+      NFAPI_TRACE(NFAPI_TRACE_WARN, "Warning pack_tlv tag 0x%x does not match expected 0x%x\n", tl->tag, tag);
+    } else {
+      //NFAPI_TRACE(NFAPI_TRACE_ERROR, "Warning pack_tlv tag 0x%x ZERO does not match expected 0x%x\n", tl->tag, tag);
+    }
+  }
+
+  return 1;
+}
+
+const char *nfapi_error_code_to_str(nfapi_error_code_e value) {
+  switch(value) {
+    case NFAPI_MSG_OK:
+      return "NFAPI_MSG_OK";
+
+    case NFAPI_MSG_INVALID_STATE:
+      return "NFAPI_MSG_INVALID_STATE";
+
+    case NFAPI_MSG_INVALID_CONFIG:
+      return "NFAPI_MSG_INVALID_CONFIG";
+
+    case NFAPI_SFN_OUT_OF_SYNC:
+      return "NFAPI_SFN_OUT_OF_SYNC";
+
+    case NFAPI_MSG_SUBFRAME_ERR:
+      return "NFAPI_MSG_SUBFRAME_ERR";
+
+    case NFAPI_MSG_BCH_MISSING:
+      return "NFAPI_MSG_BCH_MISSING";
+
+    case NFAPI_MSG_INVALID_SFN:
+      return "NFAPI_MSG_INVALID_SFN";
+
+    case NFAPI_MSG_HI_ERR:
+      return "NFAPI_MSG_HI_ERR";
+
+    case NFAPI_MSG_TX_ERR:
+      return "NFAPI_MSG_TX_ERR";
+
+    default:
+      return "UNKNOWN";
+  }
+}
diff --git a/nfapi/open-nFAPI/nfapi/src/nfapi_p7.c b/nfapi/open-nFAPI/nfapi/src/nfapi_p7.c
index 0e43c803e75a26f31632e8c605f346c3d4775f82..3adde23e7dab995bb0cd19c97f26a6087e67ef67 100644
--- a/nfapi/open-nFAPI/nfapi/src/nfapi_p7.c
+++ b/nfapi/open-nFAPI/nfapi/src/nfapi_p7.c
@@ -1048,7 +1048,7 @@ static uint8_t pack_ul_tti_request_srs_pdu(nfapi_nr_srs_pdu_t *srs_pdu, uint8_t
           push8(srs_pdu->comb_offset, ppWritePackedMsg, end) &&
           push8(srs_pdu->cyclic_shift, ppWritePackedMsg, end) &&
           push8(srs_pdu->frequency_position, ppWritePackedMsg, end) &&
-          push8(srs_pdu->frequency_shift, ppWritePackedMsg, end) &&
+          push16(srs_pdu->frequency_shift, ppWritePackedMsg, end) &&
           push8(srs_pdu->frequency_hopping, ppWritePackedMsg, end) &&
           push8(srs_pdu->group_or_sequence_hopping, ppWritePackedMsg, end) &&
           push8(srs_pdu->resource_type, ppWritePackedMsg, end) &&
@@ -1583,13 +1583,19 @@ static uint8_t pack_ul_config_request_body_value(void *tlv, uint8_t **ppWritePac
 static uint8_t pack_ul_tti_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config) {
   nfapi_nr_ul_tti_request_t *pNfapiMsg = (nfapi_nr_ul_tti_request_t *)msg;
 
-  if (!(push16(pNfapiMsg->SFN, ppWritePackedMsg, end) &&
-        push16(pNfapiMsg->Slot, ppWritePackedMsg, end) &&
-        push8(pNfapiMsg->n_pdus, ppWritePackedMsg, end) &&
-        push8(pNfapiMsg->rach_present, ppWritePackedMsg, end) &&
-        push8(pNfapiMsg->n_ulsch, ppWritePackedMsg, end) &&
-        push8(pNfapiMsg->n_ulcch, ppWritePackedMsg, end) &&
-        push8(pNfapiMsg->n_group, ppWritePackedMsg, end) ))
+  if (!push16(pNfapiMsg->SFN, ppWritePackedMsg, end))
+    return 0;
+  if (!push16(pNfapiMsg->Slot, ppWritePackedMsg, end))
+    return 0;
+  if (!push8(pNfapiMsg->n_pdus, ppWritePackedMsg, end))
+    return 0;
+  if (!push8(pNfapiMsg->n_group, ppWritePackedMsg, end))
+    return 0;
+  if (!push8(pNfapiMsg->rach_present, ppWritePackedMsg, end))
+    return 0;
+  if (!push8(pNfapiMsg->n_ulsch, ppWritePackedMsg, end))
+    return 0;
+  if (!push8(pNfapiMsg->n_ulcch, ppWritePackedMsg, end))
     return 0;
 
   for(int i=0; i<pNfapiMsg->n_pdus; i++) {
@@ -1893,15 +1899,23 @@ static uint8_t pack_tx_data_pdu_list_value(void *tlv, uint8_t **ppWritePackedMsg
 
     switch(value->TLVs[i].tag) {
       case 0: {
-        if(!pusharray32(value->TLVs[i].value.direct, 16384, value->TLVs[i].length, ppWritePackedMsg, end))
+        if (!pusharray32(value->TLVs[i].value.direct, sizeof(value->TLVs[i].value.direct) / sizeof(uint32_t),
+                        value->TLVs[i].length / sizeof(uint32_t), ppWritePackedMsg, end)) {
+          NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s():%d. value->TLVs[i].length %d \n",
+                      __FUNCTION__, __LINE__, value->TLVs[i].length);
           return 0;
+        }
 
         break;
       }
 
       case 1: {
-        if(!pusharray32(value->TLVs[i].value.ptr, value->TLVs[i].length, value->TLVs[i].length, ppWritePackedMsg, end))
+        if (!pusharray32(value->TLVs[i].value.ptr, value->TLVs[i].length / sizeof(uint32_t),
+                         value->TLVs[i].length / sizeof(uint32_t), ppWritePackedMsg, end)) {
+          NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s():%d. value->TLVs[i].length %d \n",
+                      __FUNCTION__, __LINE__, value->TLVs[i].length);
           return 0;
+        }
 
         break;
       }
@@ -3008,10 +3022,8 @@ return 1;
 
 //RX DATA INDICATION
 
-static uint8_t pack_nr_rx_data_indication_body(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
+static uint8_t pack_nr_rx_data_indication_body(nfapi_nr_rx_data_pdu_t *value, uint8_t **ppWritePackedMsg, uint8_t *end)
 {
-	nfapi_nr_rx_data_pdu_t* value = (nfapi_nr_rx_data_pdu_t*)tlv;
-
 	if(!(push32(value->handle, ppWritePackedMsg, end) &&
 	 	 push16(value->rnti, ppWritePackedMsg, end) &&
 		 push8(value->harq_id, ppWritePackedMsg, end) &&
@@ -3041,7 +3053,7 @@ static uint8_t pack_nr_rx_data_indication(void *msg, uint8_t **ppWritePackedMsg,
 
 	for (int i = 0; i < pNfapiMsg->number_of_pdus; i++)
 	{
-		if(!pack_nr_rx_data_indication_body(&(pNfapiMsg->pdu_list[i]), ppWritePackedMsg, end))
+		if(!pack_nr_rx_data_indication_body(&(pNfapiMsg->pdu_list[i]), ppWritePackedMsg, end))	
 		        return 0;
 	}
 
@@ -3089,10 +3101,8 @@ return 1;
 
 //SRS INDICATION
 
-static uint8_t pack_nr_srs_indication_body(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
+static uint8_t pack_nr_srs_indication_body(nfapi_nr_srs_indication_pdu_t *value, uint8_t **ppWritePackedMsg, uint8_t *end)
 {
-	nfapi_nr_srs_indication_pdu_t* value = (nfapi_nr_srs_indication_pdu_t*)tlv;
-
 	if(!(push32(value->handle, ppWritePackedMsg, end) &&
 	 	 push16(value->rnti, ppWritePackedMsg, end) &&
 		 push16(value->timing_advance, ppWritePackedMsg, end) &&
@@ -3104,8 +3114,7 @@ static uint8_t pack_nr_srs_indication_body(void* tlv, uint8_t **ppWritePackedMsg
 		  return 0;
 	for(int i = 0; i < value->reported_symbol_list->num_rbs; i++)
 	{
-		if(!(push8(value->reported_symbol_list->rb_list->rb_snr, ppWritePackedMsg, end)
-			))
+		if (!push8(value->reported_symbol_list->rb_list[i].rb_snr, ppWritePackedMsg, end))
 			return 0;
 	}
 	return 1;
@@ -3181,32 +3190,36 @@ return 1;
 static uint8_t pack_nr_uci_pucch_0_1(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
 	nfapi_nr_uci_pucch_pdu_format_0_1_t* value = (nfapi_nr_uci_pucch_pdu_format_0_1_t*)tlv;
 
-	if(!(push8(value->pduBitmap, ppWritePackedMsg, end) &&
-	 	 push32(value->handle, ppWritePackedMsg, end) &&
-		 push16(value->rnti, ppWritePackedMsg, end) &&
-		 push8(value->pucch_format, ppWritePackedMsg, end) &&
-		 push8(value->ul_cqi, ppWritePackedMsg, end) &&
-		 push16(value->timing_advance, ppWritePackedMsg, end) &&
-		 push16(value->rssi, ppWritePackedMsg, end)
-		 ))
-		  return 0;
+	if (!push8(value->pduBitmap, ppWritePackedMsg, end))
+		return 0;
+	if (!push32(value->handle, ppWritePackedMsg, end))
+		return 0;
+	if (!push16(value->rnti, ppWritePackedMsg, end))
+		return 0;
+	if (!push8(value->pucch_format, ppWritePackedMsg, end))
+		return 0;
+	if (!push8(value->ul_cqi, ppWritePackedMsg, end))
+		return 0;
+	if (!push16(value->timing_advance, ppWritePackedMsg, end))
+		return 0;
+	if (!push16(value->rssi, ppWritePackedMsg, end))
+		return 0;
 	if (value->pduBitmap & 0x01) { //SR
-		if (!(push8(value->sr->sr_indication, ppWritePackedMsg, end) &&
-		 push8(value->sr->sr_confidence_level, ppWritePackedMsg, end)
-		 ))
-		  return 0;
+		if (!push8(value->sr->sr_indication, ppWritePackedMsg, end))
+			return 0;
+		if (!push8(value->sr->sr_confidence_level, ppWritePackedMsg, end))
+			return 0;
 	}
 
 	if (((value->pduBitmap >> 1) & 0x01)) { //HARQ
-		if (!(push8(value->harq->num_harq, ppWritePackedMsg, end) &&
-		 push8(value->harq->harq_confidence_level, ppWritePackedMsg, end)
-		 ))
+		if (!push8(value->harq->num_harq, ppWritePackedMsg, end))
+			return 0;
+		if (!push8(value->harq->harq_confidence_level, ppWritePackedMsg, end))
 			return 0;
 		for (int i = 0; i < value->harq->num_harq; i++)
 		{
-			if (!(push8(value->harq->harq_list[i].harq_value, ppWritePackedMsg, end)
-			))
-			        return 0;
+			if (!push8(value->harq->harq_list[i].harq_value, ppWritePackedMsg, end))
+				return 0;
 		}
 	}
 
@@ -3216,57 +3229,79 @@ static uint8_t pack_nr_uci_pucch_0_1(void* tlv, uint8_t **ppWritePackedMsg, uint
 static uint8_t pack_nr_uci_pucch_2_3_4(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
 	nfapi_nr_uci_pucch_pdu_format_2_3_4_t* value = (nfapi_nr_uci_pucch_pdu_format_2_3_4_t*) tlv;
 
-	if(!(push8(value->pduBitmap, ppWritePackedMsg, end) &&
-	 	 push32(value->handle, ppWritePackedMsg, end) &&
-		 push16(value->rnti, ppWritePackedMsg, end) &&
-		 push8(value->pucch_format, ppWritePackedMsg, end) &&
-		 push8(value->ul_cqi, ppWritePackedMsg, end) &&
-		 push16(value->timing_advance, ppWritePackedMsg, end) &&
-		 push16(value->rssi, ppWritePackedMsg, end)
-		 ))
-		  return 0;
+	if (!push8(value->pduBitmap, ppWritePackedMsg, end))
+		return 0;
+	if (!push32(value->handle, ppWritePackedMsg, end))
+		return 0;
+	if (!push16(value->rnti, ppWritePackedMsg, end))
+		return 0;
+	if (!push8(value->pucch_format, ppWritePackedMsg, end))
+		return 0;
+	if (!push8(value->ul_cqi, ppWritePackedMsg, end))
+		return 0;
+	if (!push16(value->timing_advance, ppWritePackedMsg, end))
+		return 0;
+	if (!push16(value->rssi, ppWritePackedMsg, end))
+		return 0;
 
 	if (value->pduBitmap & 0x01) { //SR
-		if(!(push8(value->sr.sr_bit_len, ppWritePackedMsg, end) &&
-	 	 pusharray8(value->sr.sr_payload, (int)(value->sr.sr_bit_len / 8) + 1, (int)(value->sr.sr_bit_len / 8) + 1, ppWritePackedMsg, end)
-		 ))
-		  return 0;
+		if (!push16(value->sr.sr_bit_len, ppWritePackedMsg, end))
+			return 0;
+		if (!pusharray8(value->sr.sr_payload,
+                               (int)((value->sr.sr_bit_len / 8) + 1),
+                               (int)((value->sr.sr_bit_len / 8) + 1),
+                               ppWritePackedMsg,
+                               end))
+			return 0;
 	}
 
-	if (((value->pduBitmap >> 1) & 0x01)) { //HARQ
-		if(!(push8(value->harq.harq_crc, ppWritePackedMsg, end) &&
-			push8(value->harq.harq_bit_len, ppWritePackedMsg, end) &&
-	 	 	pusharray8(value->harq.harq_payload, (int)(value->harq.harq_bit_len / 8) + 1, (int)(value->harq.harq_bit_len / 8) + 1, ppWritePackedMsg, end)
-			))
+	if ((value->pduBitmap >> 1) & 0x01) { //HARQ
+		if (!push8(value->harq.harq_crc, ppWritePackedMsg, end))
+			return 0;
+		if (!push16(value->harq.harq_bit_len, ppWritePackedMsg, end))
+			return 0;
+		if (!pusharray8(value->harq.harq_payload,
+                                (int)((value->harq.harq_bit_len / 8) + 1),
+                                (int)((value->harq.harq_bit_len / 8) + 1),
+                                ppWritePackedMsg,
+                                end))
 			return 0;
 	}
 
-	if (((value->pduBitmap >> 2) & 0x01)) { //CSI-1
-		if(!(push8(value->csi_part1.csi_part1_crc, ppWritePackedMsg, end) &&
-			push8(value->csi_part1.csi_part1_bit_len, ppWritePackedMsg, end) &&
-	 	 	pusharray8(value->csi_part1.csi_part1_payload, (int)(value->csi_part1.csi_part1_bit_len / 8) + 1, (int)(value->csi_part1.csi_part1_bit_len / 8) + 1, ppWritePackedMsg, end)
-			))
+	if ((value->pduBitmap >> 2) & 0x01) { //CSI-1
+		if (!push8(value->csi_part1.csi_part1_crc, ppWritePackedMsg, end))
+			return 0;
+		if (!push16(value->csi_part1.csi_part1_bit_len, ppWritePackedMsg, end))
+			return 0;
+		if (!pusharray8(value->csi_part1.csi_part1_payload,
+                                (int)((value->csi_part1.csi_part1_bit_len / 8) + 1),
+                                (int)((value->csi_part1.csi_part1_bit_len / 8) + 1),
+                                ppWritePackedMsg,
+                                end))
 			return 0;
 	}
 
-	if (((value->pduBitmap >> 3) & 0x01)) { //CSI-2
-		if(!(push8(value->csi_part2.csi_part2_crc, ppWritePackedMsg, end) &&
-			push8(value->csi_part2.csi_part2_bit_len, ppWritePackedMsg, end) &&
-	 	 	pusharray8(value->csi_part2.csi_part2_payload, (int)(value->csi_part2.csi_part2_bit_len / 8) + 1, (int)(value->csi_part2.csi_part2_bit_len / 8) + 1, ppWritePackedMsg, end)
-			))
+	if ((value->pduBitmap >> 3) & 0x01) { //CSI-2
+		if (!push8(value->csi_part2.csi_part2_crc, ppWritePackedMsg, end))
+			return 0;
+		if (!push16(value->csi_part2.csi_part2_bit_len, ppWritePackedMsg, end))
+			return 0;
+		if (!pusharray8(value->csi_part2.csi_part2_payload,
+                                (int)((value->csi_part2.csi_part2_bit_len / 8) + 1),
+                                (int)((value->csi_part2.csi_part2_bit_len / 8) + 1),
+                                ppWritePackedMsg,
+                                end))
 			return 0;
 	}
 
 	return 1;
 }
 
-static uint8_t pack_nr_uci_indication_body(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
+static uint8_t pack_nr_uci_indication_body(nfapi_nr_uci_t* value, uint8_t **ppWritePackedMsg, uint8_t *end)
 {
-	nfapi_nr_uci_t* value = (nfapi_nr_uci_t*)tlv;
-
-	if(!(push16(value->pdu_type, ppWritePackedMsg, end) &&
-		push16(value->pdu_size, ppWritePackedMsg, end)
-		))
+	if (!push16(value->pdu_type, ppWritePackedMsg, end))
+		return 0;
+	if (!push16(value->pdu_size, ppWritePackedMsg, end))
 		return 0;
 
 	switch (value->pdu_type) {
@@ -3290,13 +3325,14 @@ static uint8_t pack_nr_uci_indication(void *msg, uint8_t **ppWritePackedMsg, uin
 {
 	nfapi_nr_uci_indication_t *pNfapiMsg = (nfapi_nr_uci_indication_t*)msg;
 
-	if (!(push16(pNfapiMsg->sfn , ppWritePackedMsg, end) &&
-		push16(pNfapiMsg->slot , ppWritePackedMsg, end) &&
-		push16(pNfapiMsg->num_ucis, ppWritePackedMsg, end)
-		))
+	if (!push16(pNfapiMsg->sfn , ppWritePackedMsg, end))
+			return 0;
+	if (!push16(pNfapiMsg->slot , ppWritePackedMsg, end))
+			return 0;
+	if (!push16(pNfapiMsg->num_ucis, ppWritePackedMsg, end))
 			return 0;
 
-	for(int i=0; i<pNfapiMsg->num_ucis;i++)
+	for (int i = 0; i < pNfapiMsg->num_ucis; i++)
 	{
 		if (!pack_nr_uci_indication_body(&pNfapiMsg->uci_list[i], ppWritePackedMsg, end))
 		        return 0;
@@ -4620,14 +4656,19 @@ static uint8_t unpack_ul_tti_groups_list_value(uint8_t **ppReadPackedMsg, uint8_
 static uint8_t unpack_ul_tti_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t *config) {
   nfapi_nr_ul_tti_request_t *pNfapiMsg = (nfapi_nr_ul_tti_request_t *)msg;
 
-  if (!(
-        pull16(ppReadPackedMsg, &pNfapiMsg->SFN, end) &&
-        pull16(ppReadPackedMsg, &pNfapiMsg->Slot, end) &&
-        pull8(ppReadPackedMsg, &pNfapiMsg->n_pdus, end) &&
-        pull8(ppReadPackedMsg, &pNfapiMsg->n_group, end) &&
-        pull8(ppReadPackedMsg, &pNfapiMsg->rach_present, end) &&
-        pull8(ppReadPackedMsg, &pNfapiMsg->n_ulcch, end) &&
-        pull8(ppReadPackedMsg, &pNfapiMsg->n_ulsch, end) ))
+  if (!pull16(ppReadPackedMsg, &pNfapiMsg->SFN, end))
+    return 0;
+  if (!pull16(ppReadPackedMsg, &pNfapiMsg->Slot, end))
+    return 0;
+  if (!pull8(ppReadPackedMsg, &pNfapiMsg->n_pdus, end))
+    return 0;
+  if (!pull8(ppReadPackedMsg, &pNfapiMsg->n_group, end))
+    return 0;
+  if (!pull8(ppReadPackedMsg, &pNfapiMsg->rach_present, end))
+    return 0;
+  if (!pull8(ppReadPackedMsg, &pNfapiMsg->n_ulcch, end))
+    return 0;
+  if (!pull8(ppReadPackedMsg, &pNfapiMsg->n_ulsch, end))
     return 0;
 
   for(int i=0; i< pNfapiMsg->n_pdus; i++) {
@@ -5510,14 +5551,18 @@ static uint8_t unpack_tx_data_pdu_list_value(uint8_t **ppReadPackedMsg, uint8_t
 
     switch(pNfapiMsg->TLVs[i].tag) {
       case 0: {
-        if(!pullarray32(ppReadPackedMsg, pNfapiMsg->TLVs[i].value.direct, 16384, pNfapiMsg->TLVs[i].length, end))
+        if (!pullarray32(ppReadPackedMsg, pNfapiMsg->TLVs[i].value.direct,
+                        sizeof(pNfapiMsg->TLVs[i].value.direct) / sizeof(uint32_t),
+                        pNfapiMsg->TLVs[i].length / sizeof(uint32_t), end))
           return 0;
 
         break;
       }
 
       case 1: {
-        if(!pullarray32(ppReadPackedMsg, pNfapiMsg->TLVs[i].value.ptr, pNfapiMsg->TLVs[i].length, pNfapiMsg->TLVs[i].length, end))
+        if (!pullarray32(ppReadPackedMsg,pNfapiMsg->TLVs[i].value.ptr,
+                        pNfapiMsg->TLVs[i].length / sizeof(uint32_t),
+                        pNfapiMsg->TLVs[i].length / sizeof(uint32_t), end))
           return 0;
 
         break;
@@ -5671,7 +5716,7 @@ static uint8_t unpack_nr_rx_data_indication_body(nfapi_nr_rx_data_pdu_t* value,
 		return 0;
 
         uint16_t length = value->pdu_length;
-        value->pdu = nfapi_p7_allocate(length, config);
+        value->pdu = nfapi_p7_allocate(sizeof(*value->pdu) * length, config);
 
         if (pullarray8(ppReadPackedMsg, value->pdu, length, length, end) == 0)
         {
@@ -5752,10 +5797,8 @@ return 1;
 
 //SRS INDICATION
 
-static uint8_t unpack_nr_srs_indication_body(void* tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
+static uint8_t unpack_nr_srs_indication_body(nfapi_nr_srs_indication_pdu_t* value, uint8_t **ppReadPackedMsg, uint8_t *end)
 {
-	nfapi_nr_srs_indication_pdu_t* value = (nfapi_nr_srs_indication_pdu_t*)tlv;
-
 	if(!(pull32(ppReadPackedMsg, &value->handle, end) &&
 	 	 pull16(ppReadPackedMsg, &value->rnti, end) &&
 		 pull16(ppReadPackedMsg, &value->timing_advance, end) &&
@@ -5767,17 +5810,14 @@ static uint8_t unpack_nr_srs_indication_body(void* tlv, uint8_t **ppReadPackedMs
 		  return 0;
 	for(int i = 0; i < value->reported_symbol_list->num_rbs; i++)
 	{
-		if(!(pull8(ppReadPackedMsg, &value->reported_symbol_list->rb_list->rb_snr, end)
-			))
+		if (!pull8(ppReadPackedMsg, &value->reported_symbol_list->rb_list[i].rb_snr, end))
 			return 0;
 	}
 	return 1;
 }
 
-static uint8_t unpack_nr_srs_indication(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t* config)
+static uint8_t unpack_nr_srs_indication(uint8_t **ppReadPackedMsg, uint8_t *end, nfapi_nr_srs_indication_t *pNfapiMsg, nfapi_p7_codec_config_t* config)
 {
-	nfapi_nr_srs_indication_t *pNfapiMsg = (nfapi_nr_srs_indication_t*)msg;
-
 	if (!(pull16(ppReadPackedMsg,&pNfapiMsg->sfn , end) &&
 		pull16(ppReadPackedMsg,&pNfapiMsg->slot , end) &&
 		pull8(ppReadPackedMsg,&pNfapiMsg->number_of_pdus, end)
@@ -5786,7 +5826,7 @@ static uint8_t unpack_nr_srs_indication(uint8_t **ppReadPackedMsg, uint8_t *end,
 
 	for(int i=0; i<pNfapiMsg->number_of_pdus;i++)
 	{
-		if(!unpack_nr_srs_indication_body(&pNfapiMsg->pdu_list,ppReadPackedMsg,end))
+		if (!unpack_nr_srs_indication_body(&pNfapiMsg->pdu_list[i], ppReadPackedMsg, end))
 		return 0;
 	}
 
@@ -5907,58 +5947,111 @@ static uint8_t unpack_nr_uci_pucch_0_1(nfapi_nr_uci_pucch_pdu_format_0_1_t *valu
 }
 
 
-static uint8_t unpack_nr_uci_pucch_2_3_4(nfapi_nr_uci_pucch_pdu_format_2_3_4_t* tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
-	nfapi_nr_uci_pucch_pdu_format_2_3_4_t* value = (nfapi_nr_uci_pucch_pdu_format_2_3_4_t*) tlv;
+static uint8_t unpack_nr_uci_pucch_2_3_4(nfapi_nr_uci_pucch_pdu_format_2_3_4_t* value,
+                                         uint8_t **ppReadPackedMsg,
+                                         uint8_t *end,
+                                         nfapi_p7_codec_config_t *config) {
+
+	if (!pull8(ppReadPackedMsg, &value->pduBitmap, end))
+		return 0;
+	if (!pull32(ppReadPackedMsg, &value->handle, end))
+                return 0;
+	if (!pull16(ppReadPackedMsg, &value->rnti, end))
+                return 0;
+	if (!pull8(ppReadPackedMsg, &value->pucch_format, end))
+                return 0;
+	if (!pull8(ppReadPackedMsg, &value->ul_cqi, end))
+                return 0;
+	if (!pull16(ppReadPackedMsg, &value->timing_advance, end))
+                return 0;
+	if (!pull16(ppReadPackedMsg, &value->rssi, end))
+                return 0;
 
-	if(!(pull8(ppReadPackedMsg, &value->pduBitmap, end) &&
-	 	 pull32(ppReadPackedMsg, &value->handle, end) &&
-		 pull16(ppReadPackedMsg, &value->rnti, end) &&
-		 pull8(ppReadPackedMsg, &value->pucch_format, end) &&
-		 pull8(ppReadPackedMsg, &value->ul_cqi, end) &&
-		 pull16(ppReadPackedMsg, &value->timing_advance, end) &&
-		 pull16(ppReadPackedMsg, &value->rssi, end)
-		 ))
-		  return 0;
 	if (value->pduBitmap & 0x01) { //SR
-		if(!(pull16(ppReadPackedMsg, &value->sr.sr_bit_len, end)))
+		if (!pull16(ppReadPackedMsg, &value->sr.sr_bit_len, end))
 			return 0;
 
-		value->sr.sr_payload = (uint8_t*) malloc(sizeof(uint8_t) * ((value->sr.sr_bit_len/8)));
+		value->sr.sr_payload = nfapi_p7_allocate(sizeof(*value->sr.sr_payload) *
+                                                         (int)((value->sr.sr_bit_len / 8) + 1),
+                                                         config);
+		if (value->sr.sr_payload == NULL)
+		{
+			NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s failed to allocate value->sr.sr_payload\n", __FUNCTION__);
+			return 0;
+		}
 
-	 	if(!(pullarray8(ppReadPackedMsg, &value->sr.sr_payload[0], (int)(value->sr.sr_bit_len / 8), (int)(value->sr.sr_bit_len / 8), end)))
-		  	return 0;
+		if (!pullarray8(ppReadPackedMsg, value->sr.sr_payload,
+				(int)((value->sr.sr_bit_len / 8) + 1),
+				(int)((value->sr.sr_bit_len / 8) + 1),
+                                end))
+			return 0;
 	}
 
-	if (((value->pduBitmap >> 1) & 0x01)) { //HARQ
-		if(!(pull8(ppReadPackedMsg, &value->harq.harq_crc, end)) &&
-			(pull16(ppReadPackedMsg, &value->harq.harq_bit_len, end)))
+	if ((value->pduBitmap >> 1) & 0x01) { //HARQ
+		if (!pull8(ppReadPackedMsg, &value->harq.harq_crc, end))
+			return 0;
+		if (!pull16(ppReadPackedMsg, &value->harq.harq_bit_len, end))
 			return 0;
 
-		value->harq.harq_payload = (uint8_t*) malloc(sizeof(uint8_t) * ((value->harq.harq_bit_len/8 )));
+		value->harq.harq_payload = nfapi_p7_allocate(sizeof(*value->harq.harq_payload) *
+                                                             (int)((value->harq.harq_bit_len / 8) + 1),
+                                                             config);
+		if (value->harq.harq_payload == NULL)
+		{
+			NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s failed to allocate value->harq.harq_payload\n", __FUNCTION__);
+			return 0;
+		}
 
-	 	if(!(pullarray8(ppReadPackedMsg, value->harq.harq_payload, (int)(value->harq.harq_bit_len / 8), (int)(value->harq.harq_bit_len / 8), end)))
+		if (!pullarray8(ppReadPackedMsg, value->harq.harq_payload,
+				(int)((value->harq.harq_bit_len / 8) + 1),
+				(int)((value->harq.harq_bit_len / 8) + 1),
+                                end))
 			return 0;
 	}
 
-	if (((value->pduBitmap >> 2) & 0x01)) { //CSI-1
-		if(!(pull8(ppReadPackedMsg, &value->csi_part1.csi_part1_crc, end)) &&
-			(pull16(ppReadPackedMsg, &value->csi_part1.csi_part1_bit_len, end)))
+	if ((value->pduBitmap >> 2) & 0x01) { //CSI-1
+		if (!pull8(ppReadPackedMsg, &value->csi_part1.csi_part1_crc, end))
+			return 0;
+		if (!pull16(ppReadPackedMsg, &value->csi_part1.csi_part1_bit_len, end))
 			return 0;
 
-		value->csi_part1.csi_part1_payload = (uint8_t*) malloc(sizeof(uint8_t) * ((value->csi_part1.csi_part1_bit_len/8)));
+		value->csi_part1.csi_part1_payload = nfapi_p7_allocate(sizeof(*value->csi_part1.csi_part1_payload) *
+                                                                       (int)((value->csi_part1.csi_part1_bit_len / 8) + 1),
+                                                                       config);
+		if (value->csi_part1.csi_part1_payload == NULL)
+		{
+			NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s failed to allocate value->csi_part1.csi_part1_payload\n",
+				    __FUNCTION__);
+			return 0;
+		}
 
-//		if(!(pullarray8(ppReadPackedMsg, value->csi_part1.csi_part1_payload, (int)(value->csi_part1.csi_part1_bit_len / 8), (int)(value->csi_part1.csi_part1_bit_len / 8), end)))
-//			return 0;
+		if (!pullarray8(ppReadPackedMsg, value->csi_part1.csi_part1_payload,
+                                (int)((value->csi_part1.csi_part1_bit_len / 8) + 1),
+                                (int)((value->csi_part1.csi_part1_bit_len / 8) + 1),
+                                end))
+			return 0;
 	}
 
-	if (((value->pduBitmap >> 3) & 0x01)) { //CSI-2
-		if(!(pull8(ppReadPackedMsg, &value->csi_part2.csi_part2_crc, end)) &&
-			(pull16(ppReadPackedMsg, &value->csi_part2.csi_part2_bit_len, end)))
+	if ((value->pduBitmap >> 3) & 0x01) { //CSI-2
+		if (!pull8(ppReadPackedMsg, &value->csi_part2.csi_part2_crc, end))
+			return 0;
+		if (!pull16(ppReadPackedMsg, &value->csi_part2.csi_part2_bit_len, end))
 			return 0;
 
-		value->csi_part2.csi_part2_payload = (uint8_t*) malloc(sizeof(uint8_t) * ((value->csi_part2.csi_part2_bit_len/8 )));
+		value->csi_part2.csi_part2_payload = nfapi_p7_allocate(sizeof(*value->csi_part2.csi_part2_payload) *
+                                                                       (int)((value->csi_part2.csi_part2_bit_len / 8) + 1),
+                                                                       config);
+		if (value->csi_part2.csi_part2_payload == NULL)
+		{
+			NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s failed to allocate value->csi_part2.csi_part2_payload\n",
+			            __FUNCTION__);
+			return 0;
+		}
 
-		if(!(pullarray8(ppReadPackedMsg, value->csi_part2.csi_part2_payload, (int)(value->csi_part2.csi_part2_bit_len / 8) , (int)(value->csi_part2.csi_part2_bit_len / 8) , end)))
+		if (!pullarray8(ppReadPackedMsg, value->csi_part2.csi_part2_payload,
+                                (int)((value->csi_part2.csi_part2_bit_len / 8) + 1),
+                                (int)((value->csi_part2.csi_part2_bit_len / 8) + 1),
+                                end))
 			return 0;
 	}
 
@@ -5970,9 +6063,9 @@ static uint8_t unpack_nr_uci_indication_body(nfapi_nr_uci_t *value,
                                              uint8_t *end,
                                              nfapi_p7_codec_config_t *config)
 {
-	if(!(pull16(ppReadPackedMsg, &value->pdu_type, end) &&
-		pull16(ppReadPackedMsg, &value->pdu_size, end)
-		))
+	if (!pull16(ppReadPackedMsg, &value->pdu_type, end))
+		return 0;
+	if (!pull16(ppReadPackedMsg, &value->pdu_size, end))
 		return 0;
 
 	switch (value->pdu_type) {
@@ -5988,7 +6081,7 @@ static uint8_t unpack_nr_uci_indication_body(nfapi_nr_uci_t *value,
                 }
                 case NFAPI_NR_UCI_FORMAT_2_3_4_PDU_TYPE: {
                         nfapi_nr_uci_pucch_pdu_format_2_3_4_t *uci_pdu = &value->pucch_pdu_format_2_3_4;
-                        if (!unpack_nr_uci_pucch_2_3_4(uci_pdu, ppReadPackedMsg, end))
+                        if (!unpack_nr_uci_pucch_2_3_4(uci_pdu, ppReadPackedMsg, end, config))
                                 return 0;
                         break;
                 }
@@ -6004,17 +6097,18 @@ static uint8_t unpack_nr_uci_indication(uint8_t **ppReadPackedMsg, uint8_t *end,
 {
 	nfapi_nr_uci_indication_t *pNfapiMsg = (nfapi_nr_uci_indication_t*)msg;
 
-	if (!(pull16(ppReadPackedMsg, &pNfapiMsg->sfn , end) &&
-		pull16(ppReadPackedMsg, &pNfapiMsg->slot , end) &&
-		pull16(ppReadPackedMsg, &pNfapiMsg->num_ucis, end)
-		))
-			return 0;
+	if (!pull16(ppReadPackedMsg, &pNfapiMsg->sfn , end))
+		return 0;
+	if (!pull16(ppReadPackedMsg, &pNfapiMsg->slot , end))
+		return 0;
+	if (!pull16(ppReadPackedMsg, &pNfapiMsg->num_ucis, end))
+		return 0;
 
 	pNfapiMsg->uci_list = nfapi_p7_allocate(sizeof(*pNfapiMsg->uci_list) * pNfapiMsg->num_ucis, config);
 	for (int i = 0; i < pNfapiMsg->num_ucis; i++)
 	{
-		if(!unpack_nr_uci_indication_body(&pNfapiMsg->uci_list[i], ppReadPackedMsg, end, config))
-		        return 0;
+		if (!unpack_nr_uci_indication_body(&pNfapiMsg->uci_list[i], ppReadPackedMsg, end, config))
+			return 0;
 	}
 
         return 1;
diff --git a/nfapi/open-nFAPI/vnf/src/vnf_p7.c b/nfapi/open-nFAPI/vnf/src/vnf_p7.c
index 2ac59dd7be91f24ca40d6eb1cb8ac87d1393fb84..e4b4bef848eb452b69a44b6413bad1aa2912e565 100644
--- a/nfapi/open-nFAPI/vnf/src/vnf_p7.c
+++ b/nfapi/open-nFAPI/vnf/src/vnf_p7.c
@@ -1473,7 +1473,7 @@ void vnf_handle_nr_slot_indication(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf
 		}
 		else
 		{
-			NFAPI_TRACE(NFAPI_TRACE_INFO, "%s: Handling NR SLOT Indication\n", __FUNCTION__);
+			NFAPI_TRACE(NFAPI_TRACE_DEBUG, "%s: Handling NR SLOT Indication\n", __FUNCTION__);
                         if(vnf_p7->_public.nr_slot_indication)
 			{
 				(vnf_p7->_public.nr_slot_indication)(&ind);
@@ -2574,32 +2574,28 @@ int vnf_p7_read_dispatch_message(vnf_p7_t* vnf_p7)
 			// resize the buffer if we have a large segment
 			if(header.message_length > vnf_p7->rx_message_buffer_size)
 			{
-				NFAPI_TRACE(NFAPI_TRACE_NOTE, "reallocing rx buffer %d\n", header.message_length); 
+				NFAPI_TRACE(NFAPI_TRACE_NOTE, "reallocing rx buffer %d\n", header.message_length);
 				vnf_p7->rx_message_buffer = realloc(vnf_p7->rx_message_buffer, header.message_length);
 				vnf_p7->rx_message_buffer_size = header.message_length;
 			}
 
 			// read the segment
-			recvfrom_result = recvfrom(vnf_p7->socket, vnf_p7->rx_message_buffer, header.message_length, MSG_WAITALL, (struct sockaddr*)&remote_addr, &remote_addr_size);
+			recvfrom_result = recvfrom(vnf_p7->socket, vnf_p7->rx_message_buffer, header.message_length, MSG_WAITALL | MSG_TRUNC, (struct sockaddr*)&remote_addr, &remote_addr_size);
+			NFAPI_TRACE(NFAPI_TRACE_INFO, "recvfrom_result = %d from %s():%d\n", recvfrom_result, __FUNCTION__, __LINE__);
 
 			// todo : how to handle incomplete readfroms, need some sort of buffer/select
 
-			if(recvfrom_result == 0)
-			{
-				NFAPI_TRACE(NFAPI_TRACE_ERROR, "recvfrom returned 0\n");
-			}
-			else if(recvfrom_result != -1 && recvfrom_result != header.message_length)
-			{
-				NFAPI_TRACE(NFAPI_TRACE_ERROR, "Received unexpected number of bytes %d %d\n", recvfrom_result, header.message_length);
-				
-				recvfrom_result += recvfrom(vnf_p7->socket, &vnf_p7->rx_message_buffer[recvfrom_result], header.message_length - recvfrom_result, MSG_WAITALL, (struct sockaddr*)&remote_addr, &remote_addr_size);
-	
-			}
-			
-			
-			if(recvfrom_result > 0)
+			if (recvfrom_result > 0)
 			{
+				if (recvfrom_result != header.message_length)
+				{
+					NFAPI_TRACE(NFAPI_TRACE_ERROR, "(%d) Received unexpected number of bytes. %d != %d",
+						    __LINE__, recvfrom_result, header.message_length);
+					break;
+				}
+				NFAPI_TRACE(NFAPI_TRACE_INFO, "Calling vnf_nr_handle_p7_message from %d\n", __LINE__);
 				vnf_handle_p7_message(vnf_p7->rx_message_buffer, recvfrom_result, vnf_p7);
+				return 0;
 			}
 			else
 			{
diff --git a/oaienv b/oaienv
index f8ef707c12fe09a1aa2da5f86a59548fc0134b8e..bb24469703c54628a13d7fbfb2ad29faf09d2fcc 100644
--- a/oaienv
+++ b/oaienv
@@ -1,6 +1,7 @@
 
 export OPENAIR_HOME=$(pwd)
 export OPENAIR_DIR=$(pwd)
+export AWGN_RESULTS_DIR=$OPENAIR_DIR/openair1/SIMULATION/NR_PHY/BLER_SIMULATIONS/AWGN/AWGN_results
 export OPENAIR1_DIR=$OPENAIR_HOME/openair1
 export OPENAIR2_DIR=$OPENAIR_HOME/openair2
 export OPENAIR3_DIR=$OPENAIR_HOME/openair3
diff --git a/openair1/PHY/CODING/TESTBENCH/ldpctest.c b/openair1/PHY/CODING/TESTBENCH/ldpctest.c
index 41b2d4fe84c2b3a3b330edc6a262986d501a38a5..841a31fd850713839941888f9c4351b7980d7d9d 100644
--- a/openair1/PHY/CODING/TESTBENCH/ldpctest.c
+++ b/openair1/PHY/CODING/TESTBENCH/ldpctest.c
@@ -31,6 +31,7 @@
 #include "openair1/PHY/CODING/nrLDPC_decoder_LYC/nrLDPC_decoder_LYC.h"
 #include "openair1/PHY/defs_nr_common.h"
 #include "coding_unitary_defs.h"
+#include "common/utils/LOG/log.h"
 
 #define MAX_BLOCK_LENGTH 8448
 
@@ -79,16 +80,19 @@ char quantize8bit(double D,double x)
 }
 
 typedef struct {
-  double n_iter_mean;
-  double n_iter_std;
-  int n_iter_max;
+  double n_iter_mean[400];
+  double n_iter_std[400];
+  int n_iter_max[400];
+  double snr[400];
+  double ber[400];
+  double bler[400];
 } n_iter_stats_t;
 
 nrLDPC_encoderfunc_t encoder_orig;
 
 short lift_size[51]= {2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,18,20,22,24,26,28,30,32,36,40,44,48,52,56,60,64,72,80,88,96,104,112,120,128,144,160,176,192,208,224,240,256,288,320,352,384};
 
-int test_ldpc(short No_iteration,
+int test_ldpc(short max_iterations,
               int nom_rate,
               int denom_rate,
               double SNR,
@@ -102,8 +106,8 @@ int test_ldpc(short No_iteration,
               unsigned int *crc_misses,
               time_stats_t *time_optim,
               time_stats_t *time_decoder,
-              n_iter_stats_t *dec_iter
-              )
+              n_iter_stats_t *dec_iter,
+              int nsnr)
 {
   //clock initiate
   //time_stats_t time,time_optim,tinput,tprep,tparity,toutput, time_decoder;
@@ -126,7 +130,6 @@ int test_ldpc(short No_iteration,
   //double channel_output[68 * 384];
   double modulated_input[MAX_NUM_DLSCH_SEGMENTS][68 * 384] = { 0 };
   char channel_output_fixed[MAX_NUM_DLSCH_SEGMENTS][68  * 384] = { 0 };
-  unsigned int i,j,trial=0;
   short BG=0,nrows=0;//,ncols;
   int no_punctured_columns,removed_bit;
   int i1,Zc,Kb=0;
@@ -137,12 +140,9 @@ int test_ldpc(short No_iteration,
   int code_rate_vec[8] = {15, 13, 25, 12, 23, 34, 56, 89};
   //double code_rate_actual_vec[8] = {0.2, 0.33333, 0.4, 0.5, 0.66667, 0.73333, 0.81481, 0.88};
 
-  t_nrLDPC_dec_params decParams;
-  t_nrLDPC_procBuf nrLDPC_procBuf;
-  t_nrLDPC_procBuf* p_nrLDPC_procBuf = &nrLDPC_procBuf;
-    
+  t_nrLDPC_dec_params decParams[MAX_NUM_DLSCH_SEGMENTS]={0};
+
   t_nrLDPC_time_stats decoder_profiler = {0};
-  t_nrLDPC_time_stats* p_decoder_profiler =&decoder_profiler ;
 
   int32_t n_iter = 0;
 
@@ -152,7 +152,7 @@ int test_ldpc(short No_iteration,
   *crc_misses=0;
 
   // generate input block
-  for(j=0;j<MAX_NUM_DLSCH_SEGMENTS;j++) {
+  for(int j=0;j<MAX_NUM_DLSCH_SEGMENTS;j++) {
     test_input[j]=(unsigned char *)malloc16(sizeof(unsigned char) * block_length/8);
     memset(test_input[j], 0, sizeof(unsigned char) * block_length / 8);
     channel_input[j] = (unsigned char *)malloc16(sizeof(unsigned char) * 68*384);
@@ -181,11 +181,8 @@ int test_ldpc(short No_iteration,
   reset_meas(&decoder_profiler.llr2bit);
   //reset_meas(&decoder_profiler.total);
 
-  // Allocate LDPC decoder buffers
-  p_nrLDPC_procBuf = nrLDPC_init_mem();
-
-  for (j=0;j<MAX_NUM_DLSCH_SEGMENTS;j++) {
-    for (i=0; i<block_length/8; i++) {
+  for (int j=0;j<MAX_NUM_DLSCH_SEGMENTS;j++) {
+    for (int i=0; i<block_length/8; i++) {
       test_input[j][i]=(unsigned char) rand();
       //test_input[j][i]=j%256;
       //test_input[j][i]=252;
@@ -272,17 +269,17 @@ int test_ldpc(short No_iteration,
   //  printf("puncture:%d\n",no_punctured_columns);
   removed_bit=(nrows-no_punctured_columns-2) * Zc+block_length-(int)(block_length/((float)nom_rate/(float)denom_rate));
   encoder_implemparams_t impp=INIT0_LDPCIMPLEMPARAMS;
- 
+
   impp.gen_code=1;
   if (ntrials==0)
     encoder_orig(test_input,channel_input, Zc, BG, block_length, BG, &impp);
   impp.gen_code=0;
-  for (trial=0; trial < ntrials; trial++)
+  for (int trial=0; trial < ntrials; trial++)
   {
 	segment_bler = 0;
     //// encoder
     start_meas(&time);
-    for(j=0;j<n_segments;j++) {
+    for(int j=0;j<n_segments;j++) {
       encoder_orig(&(test_input[j]), &(channel_input[j]),Zc,Kb,block_length,BG,&impp);
     }
     stop_meas(&time);
@@ -294,7 +291,7 @@ int test_ldpc(short No_iteration,
       }
     stop_meas(time_optim);*/
     impp.n_segments=n_segments;
-    for(j=0;j<(n_segments/8+1);j++) {
+    for(int j=0;j<(n_segments/8+1);j++) {
     	start_meas(time_optim);
     	impp.macro_num=j;
     	nrLDPC_encoder(test_input,channel_input_optim,Zc,Kb,block_length, BG, &impp);
@@ -302,8 +299,8 @@ int test_ldpc(short No_iteration,
     }
     
     if (ntrials==1)    
-      for (j=0;j<n_segments;j++)
-        for (i = 0; i < block_length+(nrows-no_punctured_columns) * Zc - removed_bit; i++)
+      for (int j=0;j<n_segments;j++)
+        for (int i = 0; i < block_length+(nrows-no_punctured_columns) * Zc - removed_bit; i++)
           if (channel_input[j][i]!=channel_input_optim[j][i]) {
             printf("differ in seg %u pos %u (%u,%u)\n", j, i, channel_input[j][i], channel_input_optim[j][i]);
             return (-1);
@@ -319,92 +316,60 @@ int test_ldpc(short No_iteration,
       printf("number of undecoded bits: %d\n", (Kb+nrows-no_punctured_columns-2) * Zc-removed_bit);
     }
 
-    //print_meas_now(&time, "", stdout);
-
-    // for (i=0;i<6400;i++)
-    //printf("channel_input[%d]=%d\n",i,channel_input[i]);
-    //printf("%d ",channel_input[i]);
-
-    //if ((BG==2) && (Zc==128||Zc==256))
     if (1) { // Transmitting one segment 
-      for(j=0;j<n_segments;j++) {
-	for (i = 2*Zc; i < (Kb+nrows-no_punctured_columns) * Zc-removed_bit; i++) {
+      for(int j=0;j<n_segments;j++) {
+        for (int i = 2*Zc; i < (Kb+nrows-no_punctured_columns) * Zc-removed_bit; i++) {
 #ifdef DEBUG_CODER
-        if ((i&0xf)==0)
-          printf("\ne %u..%u:    ",i,i+15);
+          if ((i&0xf)==0)
+            printf("\ne %u..%u:    ",i,i+15);
 #endif
 
-        if (channel_input_optim[j][i-2*Zc]==0)
-          modulated_input[j][i]=1.0;///sqrt(2);  //QPSK
-        else
-          modulated_input[j][i]=-1.0;///sqrt(2);
-
-        ///channel_output[i] = modulated_input[i] + gaussdouble(0.0,1.0) * 1/sqrt(2*SNR);
-        //channel_output_fixed[i] = (char) ((channel_output[i]*128)<0?(channel_output[i]*128-0.5):(channel_output[i]*128+0.5)); //fixed point 9-7
-        //printf("llr[%d]=%d\n",i,channel_output_fixed[i]);
-
-        //channel_output_fixed[i] = (char)quantize(sigma/4.0,(2.0*modulated_input[i]) - 1.0 + sigma*gaussdouble(0.0,1.0),qbits);
-        channel_output_fixed[j][i] = (char)quantize(sigma/4.0/4.0,modulated_input[j][i] + sigma*gaussdouble(0.0,1.0),qbits);
-        //channel_output_fixed[i] = (char)quantize8bit(sigma/4.0,(2.0*modulated_input[i]) - 1.0 + sigma*gaussdouble(0.0,1.0));
-        //printf("llr[%d]=%d\n",i,channel_output_fixed[i]);
-        //printf("channel_output_fixed[%d]: %d\n",i,channel_output_fixed[i]);
+          if (channel_input_optim[j][i-2*Zc]==0)
+            modulated_input[j][i]=1.0;///sqrt(2);  //QPSK
+          else
+            modulated_input[j][i]=-1.0;///sqrt(2);
 
+          ///channel_output[i] = modulated_input[i] + gaussdouble(0.0,1.0) * 1/sqrt(2*SNR);
+          //channel_output_fixed[i] = (char) ((channel_output[i]*128)<0?(channel_output[i]*128-0.5):(channel_output[i]*128+0.5)); //fixed point 9-7
+          //printf("llr[%d]=%d\n",i,channel_output_fixed[i]);
 
-        //channel_output_fixed[i] = (char)quantize(1,channel_output_fixed[i],qbits);
+          //channel_output_fixed[i] = (char)quantize(sigma/4.0,(2.0*modulated_input[i]) - 1.0 + sigma*gaussdouble(0.0,1.0),qbits);
+          channel_output_fixed[j][i] = (char)quantize(sigma/4.0/4.0,modulated_input[j][i] + sigma*gaussdouble(0.0,1.0),qbits);
+          //channel_output_fixed[i] = (char)quantize8bit(sigma/4.0,(2.0*modulated_input[i]) - 1.0 + sigma*gaussdouble(0.0,1.0));
+          //printf("llr[%d]=%d\n",i,channel_output_fixed[i]);
+          //printf("channel_output_fixed[%d]: %d\n",i,channel_output_fixed[i]);
 
-        //Uncoded BER
-        unsigned char channel_output_uncoded = channel_output_fixed[j][i]<0 ? 1 /* QPSK demod */ : 0;
 
-        if (channel_output_uncoded != channel_input_optim[j][i-2*Zc])
-	  *errors_bit_uncoded = (*errors_bit_uncoded) + 1;
+          //Uncoded BER
+          unsigned char channel_output_uncoded = channel_output_fixed[j][i]<0 ? 1 /* QPSK demod */ : 0;
 
-	}
-      } // End segments
+          if (channel_output_uncoded != channel_input_optim[j][i-2*Zc])
+      *errors_bit_uncoded = (*errors_bit_uncoded) + 1;
 
-      //for (i=(Kb+nrows) * Zc-5;i<(Kb+nrows) * Zc;i++)
-      //{
-      //  printf("channel_input[%d]=%d\n",i,channel_input[i]);
-      //printf("%lf %d\n",channel_output[i], channel_output_fixed[i]);
-      //printf("v[%d]=%lf\n",i,modulated_input[i]);}
+        }
+     
 #ifdef DEBUG_CODER
-      printf("\n");
-      exit(-1);
+        printf("\n");
+        exit(-1);
 #endif
 
-      decParams.BG=BG;
-      decParams.Z=Zc;
-      decParams.R=code_rate_vec[R_ind];//13;
-      decParams.numMaxIter=No_iteration;
-      decParams.outMode = nrLDPC_outMode_BIT;
-      decParams.block_length=block_length;
-      //decParams.outMode =nrLDPC_outMode_LLRINT8;
-	  nrLDPC_initcall(&decParams, (int8_t*)channel_output_fixed[j], (int8_t*)estimated_output[j]);
-	  for(j=0;j<n_segments;j++) {
-    	  start_meas(time_decoder);
-          n_iter = nrLDPC_decoder(&decParams, (int8_t*)channel_output_fixed[j], (int8_t*)estimated_output[j], p_nrLDPC_procBuf, p_decoder_profiler);
-	      stop_meas(time_decoder);
+        decParams[j].BG=BG;
+        decParams[j].Z=Zc;
+        decParams[j].R=code_rate_vec[R_ind];//13;
+        decParams[j].numMaxIter=max_iterations;
+        decParams[j].outMode = nrLDPC_outMode_BIT;
+        decParams[j].block_length=block_length;
+        nrLDPC_initcall(&decParams[j], (int8_t*)channel_output_fixed[j], (int8_t*)estimated_output[j]);
       }
-
-      //for (i=(Kb+nrows) * Zc-5;i<(Kb+nrows) * Zc;i++)
-      //  printf("esimated_output[%d]=%d\n",i,esimated_output[i]);
-
-      //count errors
-      for(j=0;j<n_segments;j++) {
-      for (i=0; i<block_length>>3; i++)
-      {
-          //printf("block_length>>3: %d \n",block_length>>3);
-         /// printf("i: %d \n",i);
-          ///printf("estimated_output[%d]: %d \n",i,estimated_output[i]);
-          ///printf("test_input[0][%d]: %d \n",i,test_input[0][i]);
-        if (estimated_output[j][i] != test_input[j][i])
-        {
-      //////printf("error pos %d (%d, %d)\n\n",i,estimated_output[i],test_input[0][i]);
-          segment_bler = segment_bler + 1;
-          break;
+      for(int j=0;j<n_segments;j++) {
+        start_meas(time_decoder);
+        n_iter = nrLDPC_decoder(&decParams[j], (int8_t*)channel_output_fixed[j], (int8_t*)estimated_output[j], &decoder_profiler);
+        stop_meas(time_decoder);
+        //count errors
+        if ( memcmp(estimated_output[j], test_input[j], block_length/8 ) != 0 ) {
+          segment_bler++;
         }
-      }
-
-      for (i=0; i<block_length; i++)
+        for (int i=0; i<block_length; i++)
         {
           unsigned char estoutputbit = (estimated_output[j][i/8]&(1<<(i&7)))>>(i&7);
           unsigned char inputbit = (test_input[j][i/8]&(1<<(i&7)))>>(i&7); // Further correct for multiple segments
@@ -412,40 +377,33 @@ int test_ldpc(short No_iteration,
             *errors_bit = (*errors_bit) + 1;
         }
 
-      //if (*errors == 1000)
-    	  //break;
-
-      n_iter_mean =  n_iter_mean + n_iter;
-      n_iter_std = n_iter_std + pow(n_iter-1,2);
+        n_iter_mean += n_iter;
+        n_iter_std +=  pow(n_iter-1,2);
 
-      if ( n_iter > n_iter_max )
-        n_iter_max = n_iter;
+        if ( n_iter > n_iter_max )
+          n_iter_max = n_iter;
 
-    } // end segments
+      } // end segments
 
       if (segment_bler != 0)
-		*errors = (*errors) + 1;
+        *errors = (*errors) + 1;
 
     }
-    /*else if (trial==0)
-      printf("decoder is not supported\n");*/
   }
 
 
-  dec_iter->n_iter_mean = n_iter_mean/(double)ntrials/(double)n_segments - 1;
-  dec_iter->n_iter_std = sqrt(n_iter_std/(double)ntrials/(double)n_segments - pow(n_iter_mean/(double)ntrials/(double)n_segments - 1,2));
-  dec_iter->n_iter_max = n_iter_max -1;
+  dec_iter->n_iter_mean[nsnr] = n_iter_mean/(double)ntrials/(double)n_segments - 1;
+  dec_iter->n_iter_std[nsnr] = sqrt(n_iter_std/(double)ntrials/(double)n_segments - pow(n_iter_mean/(double)ntrials/(double)n_segments - 1,2));
+  dec_iter->n_iter_max[nsnr] = n_iter_max -1;
 
   *errors_bit_uncoded = *errors_bit_uncoded / (double)((Kb+nrows-no_punctured_columns-2) * Zc-removed_bit);
 
-  for(j=0;j<MAX_NUM_DLSCH_SEGMENTS;j++) {
+  for(int j=0;j<MAX_NUM_DLSCH_SEGMENTS;j++) {
     free(test_input[j]);
     free(channel_input[j]);
     free(channel_input_optim[j]);
   }
 
-  nrLDPC_free_mem(p_nrLDPC_procBuf);
-
   print_meas(&time,"ldpc_encoder",NULL,NULL);
   print_meas(time_optim,"ldpc_encoder_optim",NULL,NULL);
   print_meas(&tinput,"ldpc_encoder_optim(input)",NULL,NULL);
@@ -476,7 +434,7 @@ int main(int argc, char *argv[])
   double errors_bit_uncoded;
   short block_length=8448; // decoder supports length: 1201 -> 1280, 2401 -> 2560
   char *ldpc_version=NULL; /* version of the ldpc decoder library to use (XXX suffix to use when loading libldpc_XXX.so */
-  short No_iteration=5;
+  short max_iterations=5;
   int n_segments=1;
   //double rate=0.333;
   
@@ -486,7 +444,7 @@ int main(int argc, char *argv[])
   unsigned char qbits=8;
   unsigned int decoded_errors[10000]; // initiate the size of matrix equivalent to size of SNR
   int c,i=0, i1 = 0;
-  int loglvl=OAILOG_WARNING;
+
   int n_trials = 1;
   double SNR_step = 0.1;
 
@@ -494,14 +452,11 @@ int main(int argc, char *argv[])
   int test_uncoded= 0;
 
   time_stats_t time_optim[10], time_decoder[10];
-  n_iter_stats_t dec_iter[3];
+  n_iter_stats_t dec_iter;
 
   short BG=0,Zc,Kb=0;
-  if ( load_configmodule(argc,argv,CONFIG_ENABLECMDLINEONLY) == 0) {
-    exit_fun(" Error, configuration module init failed\n");
-  } // must be done before specific options parsing to prevent errasing them
-  
-  while ((c = getopt (argc, argv, "q:r:s:S:l:L:G:n:d:i:t:u:hv:")) != -1)
+
+  while ((c = getopt (argc, argv, "q:r:s:S:l:G:n:d:i:t:u:hv:")) != -1)
     switch (c)
     {
       case 'q':
@@ -519,10 +474,6 @@ int main(int argc, char *argv[])
       case 'l':
         block_length = atoi(optarg);
         break;
-
-      case 'L':
-        loglvl = atoi(optarg);
-        break;
 		
       case 'G':
         ldpc_version="_cuda";
@@ -545,7 +496,7 @@ int main(int argc, char *argv[])
         break;
 
       case 'i':
-        No_iteration = atoi(optarg);
+        max_iterations = atoi(optarg);
         break;
 
       case 'u':
@@ -560,11 +511,10 @@ int main(int argc, char *argv[])
               printf("BG1 (blocklength > 3840): 1/3, 2/3, 22/25 (8/9) \n");
               printf("BG2 (blocklength <= 3840): 1/5, 1/3, 2/3 \n\n");
               printf("-h This message\n");
-              printf("-L <log level, 0(errors), 1(warning), 2(info) 3(debug) 4 (trace)>\n");              
               printf("-q Quantization bits, Default: 8\n");
               printf("-r Nominator rate, (1, 2, 22), Default: 1\n");
               printf("-d Denominator rate, (3, 5, 25), Default: 1\n");
-              printf("-l Block length (l > 3840 -> BG1, rest BG2 ), Default: 8448\n");              
+              printf("-l Block length (l > 3840 -> BG1, rest BG2 ), Default: 8448\n");
 			  printf("-G give 1 to run cuda for LDPC, Default: 0\n");
               printf("-n Number of simulation trials, Default: 1\n");
               //printf("-M MCS2 for TB 2\n");
@@ -583,8 +533,6 @@ int main(int argc, char *argv[])
   printf("n_trials %d: \n", n_trials);
   printf("SNR0 %f: \n", SNR0);
 
-  logInit();
-  set_glog(loglvl);
 
   if (ldpc_version != NULL)
     load_nrLDPClib(ldpc_version);
@@ -632,7 +580,7 @@ int main(int argc, char *argv[])
   }
 
   char fname[200];
-  sprintf(fname,"ldpctest_BG_%d_Zc_%d_rate_%d-%d_block_length_%d_maxit_%d.txt",BG,Zc,nom_rate,denom_rate,block_length, No_iteration);
+  sprintf(fname,"ldpctest_BG_%d_Zc_%d_rate_%d-%d_block_length_%d_maxit_%d.txt",BG,Zc,nom_rate,denom_rate,block_length, max_iterations);
   FILE *fd=fopen(fname,"w");
   AssertFatal(fd!=NULL,"cannot open %s\n",fname);
 
@@ -647,7 +595,7 @@ int main(int argc, char *argv[])
     else
     	SNR_lin = pow(10,SNR/10.0)*nom_rate/denom_rate;
     printf("Linear SNR: %f\n", SNR_lin);
-    decoded_errors[i]=test_ldpc(No_iteration,
+    decoded_errors[i]=test_ldpc(max_iterations,
                                 nom_rate,
                                 denom_rate,
                                 SNR_lin,   // noise standard deviation
@@ -661,14 +609,18 @@ int main(int argc, char *argv[])
                                 &crc_misses,
                                 time_optim,
                                 time_decoder,
-                                dec_iter);
-
-    printf("SNR %f, BLER %f (%u/%d)\n", SNR, (float)decoded_errors[i]/(float)n_trials, decoded_errors[i], n_trials);
-    printf("SNR %f, BER %f (%u/%d)\n", SNR, (float)errors_bit/(float)n_trials/(float)block_length/(double)n_segments, decoded_errors[i], n_trials);
+                                &dec_iter,
+                                i);
+
+    dec_iter.snr[i] = SNR;
+    dec_iter.ber[i] = (float)errors_bit/(float)n_trials/(float)block_length/(double)n_segments;
+    dec_iter.bler[i] = (float)decoded_errors[i]/(float)n_trials;
+    printf("SNR %f, BLER %f (%u/%d)\n", SNR, dec_iter.bler[i], decoded_errors[i], n_trials);
+    printf("SNR %f, BER %f (%u/%d)\n", SNR, dec_iter.ber[i], decoded_errors[i], n_trials);
     printf("SNR %f, Uncoded BER %f (%u/%d)\n",SNR, errors_bit_uncoded/(float)n_trials/(double)n_segments, decoded_errors[i], n_trials);
-    printf("SNR %f, Mean iterations: %f\n",SNR, dec_iter->n_iter_mean);
-    printf("SNR %f, Std iterations: %f\n",SNR, dec_iter->n_iter_std);
-    printf("SNR %f, Max iterations: %d\n",SNR, dec_iter->n_iter_max);
+    printf("SNR %f, Mean iterations: %f\n",SNR, dec_iter.n_iter_mean[i]);
+    printf("SNR %f, Std iterations: %f\n",SNR, dec_iter.n_iter_std[i]);
+    printf("SNR %f, Max iterations: %d\n",SNR, dec_iter.n_iter_max[i]);
     printf("\n");
     printf("Encoding time mean: %15.3f us\n",(double)time_optim->diff/time_optim->trials/1000.0/get_cpu_freq_GHz());
     printf("Encoding time std: %15.3f us\n",sqrt((double)time_optim->diff_square/time_optim->trials/pow(1000,2)/pow(get_cpu_freq_GHz(),2)-pow((double)time_optim->diff/time_optim->trials/1000.0/get_cpu_freq_GHz(),2)));
@@ -689,16 +641,20 @@ int main(int argc, char *argv[])
     		(double)time_decoder->diff/time_decoder->trials/1000.0/get_cpu_freq_GHz(),
     		sqrt((double)time_decoder->diff_square/time_decoder->trials/pow(1000,2)/pow(get_cpu_freq_GHz(),2)-pow((double)time_decoder->diff/time_decoder->trials/1000.0/get_cpu_freq_GHz(),2)),
     		(double)time_decoder->max/1000.0/get_cpu_freq_GHz(),
-    		dec_iter->n_iter_mean,
-    		dec_iter->n_iter_std,
-    		dec_iter->n_iter_max
+    		dec_iter.n_iter_mean[i],
+    		dec_iter.n_iter_std[i],
+    		dec_iter.n_iter_max[i]
     		);
 
-    if (decoded_errors[i] == 0) break;
-
     i=i+1;
+    if (decoded_errors[i-1] == 0) break;
+
   }
   fclose(fd);
+  LOG_M("ldpctestStats.m","SNR",&dec_iter.snr[0],i,1,7);
+  LOG_MM("ldpctestStats.m","BLER",&dec_iter.bler[0],i,1,7);
+  LOG_MM("ldpctestStats.m","BER",&dec_iter.ber[0],i,1,7);
+  LOG_MM("ldpctestStats.m","meanIter",&dec_iter.n_iter_mean[0],i,1,7);
 
   loader_reset();
   logTerm();
diff --git a/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_bnProc.h b/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_bnProc.h
index 878150a9a8c20405142e72548baa2ab07c10530a..91f552f935c02d41543c94826dcbf74dfdea01f4 100644
--- a/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_bnProc.h
+++ b/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_bnProc.h
@@ -37,17 +37,12 @@
    \param p_lut Pointer to decoder LUTs
    \param Z Lifting size
 */
-static inline void nrLDPC_bnProcPc(t_nrLDPC_lut* p_lut, t_nrLDPC_procBuf* p_procBuf, uint16_t Z)
+static inline void nrLDPC_bnProcPc(t_nrLDPC_lut* p_lut, int8_t* bnProcBuf, int8_t* bnProcBufRes, int8_t* llrProcBuf, int8_t* llrRes, uint16_t Z)
 {
     const uint8_t*  lut_numBnInBnGroups = p_lut->numBnInBnGroups;
     const uint32_t* lut_startAddrBnGroups = p_lut->startAddrBnGroups;
     const uint16_t* lut_startAddrBnGroupsLlr = p_lut->startAddrBnGroupsLlr;
 
-    int8_t* bnProcBuf    = p_procBuf->bnProcBuf;
-    int8_t* bnProcBufRes = p_procBuf->bnProcBufRes;
-    int8_t* llrRes       = p_procBuf->llrRes;
-    int8_t* llrProcBuf   = p_procBuf->llrProcBuf;
-
     __m128i* p_bnProcBuf;
     __m256i* p_bnProcBufRes;
     __m128i* p_llrProcBuf;
@@ -1681,7 +1676,7 @@ static inline void nrLDPC_bnProcPc(t_nrLDPC_lut* p_lut, t_nrLDPC_procBuf* p_proc
    \param p_lut Pointer to decoder LUTs
    \param Z Lifting size
 */
-static inline void nrLDPC_bnProc(t_nrLDPC_lut* p_lut, t_nrLDPC_procBuf* p_procBuf, uint16_t Z)
+static inline void nrLDPC_bnProc(t_nrLDPC_lut* p_lut, int8_t* bnProcBuf, int8_t* bnProcBufRes, int8_t* llrRes, uint16_t Z)
 {
     // BN Processing calculating the values to send back to the CNs for next iteration
     // bnProcBufRes contains the sum of all edges to each BN at the start of each group
@@ -1690,10 +1685,6 @@ static inline void nrLDPC_bnProc(t_nrLDPC_lut* p_lut, t_nrLDPC_procBuf* p_procBu
     const uint32_t* lut_startAddrBnGroups = p_lut->startAddrBnGroups;
     const uint16_t* lut_startAddrBnGroupsLlr = p_lut->startAddrBnGroupsLlr;
 
-    int8_t* bnProcBuf    = p_procBuf->bnProcBuf;
-    int8_t* bnProcBufRes = p_procBuf->bnProcBufRes;
-    int8_t* llrRes       = p_procBuf->llrRes;
-
     __m256i* p_bnProcBuf;
     __m256i* p_bnProcBufRes;
     __m256i* p_llrRes;
diff --git a/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_cnProc.h b/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_cnProc.h
index db9d6e4119c8d6f79faabc2e4daa8787bd1e7855..6d82fe5f11f86ebc924e3a163a56cb1adbd7e36f 100644
--- a/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_cnProc.h
+++ b/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_cnProc.h
@@ -37,14 +37,11 @@
    \param p_procBuf Pointer to processing buffers
    \param Z Lifting size
 */
-static inline void nrLDPC_cnProc_BG2(t_nrLDPC_lut* p_lut, t_nrLDPC_procBuf* p_procBuf, uint16_t Z)
+static inline void nrLDPC_cnProc_BG2(t_nrLDPC_lut* p_lut, int8_t* cnProcBuf, int8_t* cnProcBufRes, uint16_t Z)
 {
     const uint8_t*  lut_numCnInCnGroups   = p_lut->numCnInCnGroups;
     const uint32_t* lut_startAddrCnGroups = p_lut->startAddrCnGroups;
 
-    int8_t* cnProcBuf    = p_procBuf->cnProcBuf;
-    int8_t* cnProcBufRes = p_procBuf->cnProcBufRes;
-    
     __m256i* p_cnProcBuf;
     __m256i* p_cnProcBufRes;
 
@@ -372,14 +369,11 @@ static inline void nrLDPC_cnProc_BG2(t_nrLDPC_lut* p_lut, t_nrLDPC_procBuf* p_pr
    \param p_lut Pointer to decoder LUTs
    \param Z Lifting size
 */
-static inline void nrLDPC_cnProc_BG1(t_nrLDPC_lut* p_lut, t_nrLDPC_procBuf* p_procBuf, uint16_t Z)
+static inline void nrLDPC_cnProc_BG1(t_nrLDPC_lut* p_lut, int8_t* cnProcBuf, int8_t* cnProcBufRes, uint16_t Z)
 {
     const uint8_t*  lut_numCnInCnGroups   = p_lut->numCnInCnGroups;
     const uint32_t* lut_startAddrCnGroups = p_lut->startAddrCnGroups;
 
-    int8_t* cnProcBuf    = p_procBuf->cnProcBuf;
-    int8_t* cnProcBufRes = p_procBuf->cnProcBufRes;
-    
     __m256i* p_cnProcBuf;
     __m256i* p_cnProcBufRes;
 
@@ -871,14 +865,11 @@ static inline void nrLDPC_cnProc_BG1(t_nrLDPC_lut* p_lut, t_nrLDPC_procBuf* p_pr
    \param Z Lifting size
    \return 32-bit parity check indicator
 */
-static inline uint32_t nrLDPC_cnProcPc_BG1(t_nrLDPC_lut* p_lut, t_nrLDPC_procBuf* p_procBuf, uint16_t Z)
+static inline uint32_t nrLDPC_cnProcPc_BG1(t_nrLDPC_lut* p_lut, int8_t* cnProcBuf, int8_t* cnProcBufRes, uint16_t Z)
 {
     const uint8_t*  lut_numCnInCnGroups   = p_lut->numCnInCnGroups;
     const uint32_t* lut_startAddrCnGroups = p_lut->startAddrCnGroups;
 
-    int8_t* cnProcBuf    = p_procBuf->cnProcBuf;
-    int8_t* cnProcBufRes = p_procBuf->cnProcBufRes;
-    
     __m256i* p_cnProcBuf;
     __m256i* p_cnProcBufRes;
 
@@ -1506,14 +1497,11 @@ static inline uint32_t nrLDPC_cnProcPc_BG1(t_nrLDPC_lut* p_lut, t_nrLDPC_procBuf
    \param Z Lifting size
    \return 32-bit parity check indicator
 */
-static inline uint32_t nrLDPC_cnProcPc_BG2(t_nrLDPC_lut* p_lut, t_nrLDPC_procBuf* p_procBuf, uint16_t Z)
+static inline uint32_t nrLDPC_cnProcPc_BG2(t_nrLDPC_lut* p_lut, int8_t* cnProcBuf, int8_t* cnProcBufRes, uint16_t Z)
 {
     const uint8_t*  lut_numCnInCnGroups   = p_lut->numCnInCnGroups;
     const uint32_t* lut_startAddrCnGroups = p_lut->startAddrCnGroups;
 
-    int8_t* cnProcBuf    = p_procBuf->cnProcBuf;
-    int8_t* cnProcBufRes = p_procBuf->cnProcBufRes;
-    
     __m256i* p_cnProcBuf;
     __m256i* p_cnProcBufRes;
 
diff --git a/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_decoder.c b/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_decoder.c
index 166cd9a5a333b45f5ccdcbfc53ec042b1baead6c..bf0f401e9746d7d48bf571dc2066cb68288d0689 100644
--- a/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_decoder.c
+++ b/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_decoder.c
@@ -45,22 +45,22 @@
 #include "nrLDPC_tools/nrLDPC_debug.h"
 #endif
 
-static inline uint32_t nrLDPC_decoder_core(int8_t* p_llr, int8_t* p_out, t_nrLDPC_procBuf* p_procBuf, uint32_t numLLR, t_nrLDPC_lut* p_lut, t_nrLDPC_dec_params* p_decParams, t_nrLDPC_time_stats* p_profiler);
+static inline uint32_t nrLDPC_decoder_core(int8_t* p_llr, int8_t* p_out, uint32_t numLLR, t_nrLDPC_lut* p_lut, t_nrLDPC_dec_params* p_decParams, t_nrLDPC_time_stats* p_profiler);
+int check_crc(uint8_t* decoded_bytes, uint32_t n, uint32_t F, uint8_t crc_type);
 void nrLDPC_initcall(t_nrLDPC_dec_params* p_decParams, int8_t* p_llr, int8_t* p_out) {
 }
-int32_t nrLDPC_decod(t_nrLDPC_dec_params* p_decParams, int8_t* p_llr, int8_t* p_out, t_nrLDPC_procBuf* p_procBuf, t_nrLDPC_time_stats* p_profiler)
+int32_t nrLDPC_decod(t_nrLDPC_dec_params* p_decParams, int8_t* p_llr, int8_t* p_out, t_nrLDPC_time_stats* p_profiler)
 {
     uint32_t numLLR;
     uint32_t numIter = 0;
     t_nrLDPC_lut lut;
     t_nrLDPC_lut* p_lut = &lut;
 
-    //printf("p_procBuf->cnProcBuf = %p\n", p_procBuf->cnProcBuf);
     // Initialize decoder core(s) with correct LUTs
     numLLR = nrLDPC_init(p_decParams, p_lut);
 
     // Launch LDPC decoder core for one segment
-    numIter = nrLDPC_decoder_core(p_llr, p_out, p_procBuf, numLLR, p_lut, p_decParams, p_profiler);
+    numIter = nrLDPC_decoder_core(p_llr, p_out, numLLR, p_lut, p_decParams, p_profiler);
 
     return numIter;
 }
@@ -74,13 +74,20 @@ int32_t nrLDPC_decod(t_nrLDPC_dec_params* p_decParams, int8_t* p_llr, int8_t* p_
    \param p_decParams LDPC decoder parameters
    \param p_profiler LDPC profiler statistics
 */
-static inline uint32_t nrLDPC_decoder_core(int8_t* p_llr, int8_t* p_out, t_nrLDPC_procBuf* p_procBuf, uint32_t numLLR, t_nrLDPC_lut* p_lut, t_nrLDPC_dec_params* p_decParams, t_nrLDPC_time_stats* p_profiler)
+static inline uint32_t nrLDPC_decoder_core(int8_t* p_llr, int8_t* p_out, uint32_t numLLR, t_nrLDPC_lut* p_lut, t_nrLDPC_dec_params* p_decParams, t_nrLDPC_time_stats* p_profiler)
 {
     uint16_t Z          = p_decParams->Z;
     uint8_t  BG         = p_decParams->BG;
     uint8_t  numMaxIter = p_decParams->numMaxIter;
     e_nrLDPC_outMode outMode = p_decParams->outMode;
 
+    int8_t cnProcBuf[NR_LDPC_SIZE_CN_PROC_BUF]    __attribute__ ((aligned(32))) = {0};
+    int8_t cnProcBufRes[NR_LDPC_SIZE_CN_PROC_BUF] __attribute__ ((aligned(32))) = {0};
+    int8_t bnProcBuf[NR_LDPC_SIZE_BN_PROC_BUF]    __attribute__ ((aligned(32))) = {0};
+    int8_t bnProcBufRes[NR_LDPC_SIZE_BN_PROC_BUF] __attribute__ ((aligned(32))) = {0};
+    int8_t llrRes[NR_LDPC_MAX_NUM_LLR]            __attribute__ ((aligned(32))) = {0};
+    int8_t llrProcBuf[NR_LDPC_MAX_NUM_LLR]        __attribute__ ((aligned(32))) = {0};
+    int8_t llrOut[NR_LDPC_MAX_NUM_LLR]            __attribute__ ((aligned(32))) = {0};
     // Minimum number of iterations is 1
     // 0 iterations means hard-decision on input LLRs
     uint32_t i = 1;
@@ -95,9 +102,7 @@ static inline uint32_t nrLDPC_decoder_core(int8_t* p_llr, int8_t* p_out, t_nrLDP
     else
     {
         // Use LLR processing buffer as temporary output buffer
-        p_llrOut = p_procBuf->llrProcBuf;
-        // Clear llrProcBuf
-        memset(p_llrOut,0, NR_LDPC_MAX_NUM_LLR*sizeof(int8_t));
+        p_llrOut = llrOut;
     }
 
 
@@ -105,14 +110,14 @@ static inline uint32_t nrLDPC_decoder_core(int8_t* p_llr, int8_t* p_out, t_nrLDP
 #ifdef NR_LDPC_PROFILER_DETAIL
     start_meas(&p_profiler->llr2llrProcBuf);
 #endif
-    nrLDPC_llr2llrProcBuf(p_lut, p_llr, p_procBuf, Z, BG);
+    nrLDPC_llr2llrProcBuf(p_lut, p_llr, llrProcBuf, Z, BG);
 #ifdef NR_LDPC_PROFILER_DETAIL
     stop_meas(&p_profiler->llr2llrProcBuf);
 #endif
 
 #ifdef NR_LDPC_DEBUG_MODE
     nrLDPC_debug_initBuffer2File(nrLDPC_buffers_LLR_PROC);
-    nrLDPC_debug_writeBuffer2File(nrLDPC_buffers_LLR_PROC, p_procBuf);
+    nrLDPC_debug_writeBuffer2File(nrLDPC_buffers_LLR_PROC, llrProcBuf);
 #endif
 
 #ifdef NR_LDPC_PROFILER_DETAIL
@@ -120,11 +125,11 @@ static inline uint32_t nrLDPC_decoder_core(int8_t* p_llr, int8_t* p_out, t_nrLDP
 #endif
     if (BG == 1)
     {
-        nrLDPC_llr2CnProcBuf_BG1(p_lut, p_llr, p_procBuf, Z);
+        nrLDPC_llr2CnProcBuf_BG1(p_lut, p_llr, cnProcBuf, Z);
     }
     else
     {
-        nrLDPC_llr2CnProcBuf_BG2(p_lut, p_llr, p_procBuf, Z);
+        nrLDPC_llr2CnProcBuf_BG2(p_lut, p_llr, cnProcBuf, Z);
     }
 #ifdef NR_LDPC_PROFILER_DETAIL
     stop_meas(&p_profiler->llr2CnProcBuf);
@@ -132,7 +137,7 @@ static inline uint32_t nrLDPC_decoder_core(int8_t* p_llr, int8_t* p_out, t_nrLDP
 
 #ifdef NR_LDPC_DEBUG_MODE
     nrLDPC_debug_initBuffer2File(nrLDPC_buffers_CN_PROC);
-    nrLDPC_debug_writeBuffer2File(nrLDPC_buffers_CN_PROC, p_procBuf);
+    nrLDPC_debug_writeBuffer2File(nrLDPC_buffers_CN_PROC, cnProcBuf);
 #endif
 
     // First iteration
@@ -143,11 +148,11 @@ static inline uint32_t nrLDPC_decoder_core(int8_t* p_llr, int8_t* p_out, t_nrLDP
 #endif
     if (BG == 1)
     {
-        nrLDPC_cnProc_BG1(p_lut, p_procBuf, Z);
+        nrLDPC_cnProc_BG1(p_lut, cnProcBuf, cnProcBufRes, Z);
     }
     else
     {
-        nrLDPC_cnProc_BG2(p_lut, p_procBuf, Z);
+        nrLDPC_cnProc_BG2(p_lut, cnProcBuf, cnProcBufRes, Z);
     }
 #ifdef NR_LDPC_PROFILER_DETAIL
     stop_meas(&p_profiler->cnProc);
@@ -155,7 +160,7 @@ static inline uint32_t nrLDPC_decoder_core(int8_t* p_llr, int8_t* p_out, t_nrLDP
 
 #ifdef NR_LDPC_DEBUG_MODE
     nrLDPC_debug_initBuffer2File(nrLDPC_buffers_CN_PROC_RES);
-    nrLDPC_debug_writeBuffer2File(nrLDPC_buffers_CN_PROC_RES, p_procBuf);
+    nrLDPC_debug_writeBuffer2File(nrLDPC_buffers_CN_PROC_RES, cnProcBufRes);
 #endif
 
 #ifdef NR_LDPC_PROFILER_DETAIL
@@ -163,11 +168,11 @@ static inline uint32_t nrLDPC_decoder_core(int8_t* p_llr, int8_t* p_out, t_nrLDP
 #endif
     if (BG == 1)
     {
-        nrLDPC_cn2bnProcBuf_BG1(p_lut, p_procBuf, Z);
+        nrLDPC_cn2bnProcBuf_BG1(p_lut, cnProcBufRes, bnProcBuf, Z);
     }
     else
     {
-        nrLDPC_cn2bnProcBuf_BG2(p_lut, p_procBuf, Z);
+        nrLDPC_cn2bnProcBuf_BG2(p_lut, cnProcBufRes, bnProcBuf, Z);
     }
 #ifdef NR_LDPC_PROFILER_DETAIL
     stop_meas(&p_profiler->cn2bnProcBuf);
@@ -175,34 +180,34 @@ static inline uint32_t nrLDPC_decoder_core(int8_t* p_llr, int8_t* p_out, t_nrLDP
 
 #ifdef NR_LDPC_DEBUG_MODE
     nrLDPC_debug_initBuffer2File(nrLDPC_buffers_BN_PROC);
-    nrLDPC_debug_writeBuffer2File(nrLDPC_buffers_BN_PROC, p_procBuf);
+    nrLDPC_debug_writeBuffer2File(nrLDPC_buffers_BN_PROC, bnProcBuf);
 #endif
 
     // BN processing
 #ifdef NR_LDPC_PROFILER_DETAIL
     start_meas(&p_profiler->bnProcPc);
 #endif
-    nrLDPC_bnProcPc(p_lut, p_procBuf, Z);
+    nrLDPC_bnProcPc(p_lut, bnProcBuf, bnProcBufRes, llrProcBuf, llrRes, Z);
 #ifdef NR_LDPC_PROFILER_DETAIL
     stop_meas(&p_profiler->bnProcPc);
 #endif
 
 #ifdef NR_LDPC_DEBUG_MODE
     nrLDPC_debug_initBuffer2File(nrLDPC_buffers_LLR_RES);
-    nrLDPC_debug_writeBuffer2File(nrLDPC_buffers_LLR_RES, p_procBuf);
+    nrLDPC_debug_writeBuffer2File(nrLDPC_buffers_LLR_RES, llrRes);
 #endif
 
 #ifdef NR_LDPC_PROFILER_DETAIL
     start_meas(&p_profiler->bnProc);
 #endif
-    nrLDPC_bnProc(p_lut, p_procBuf, Z);
+    nrLDPC_bnProc(p_lut, bnProcBuf, bnProcBufRes, llrRes, Z);
 #ifdef NR_LDPC_PROFILER_DETAIL
     stop_meas(&p_profiler->bnProc);
 #endif
 
 #ifdef NR_LDPC_DEBUG_MODE
     nrLDPC_debug_initBuffer2File(nrLDPC_buffers_BN_PROC_RES);
-    nrLDPC_debug_writeBuffer2File(nrLDPC_buffers_BN_PROC_RES, p_procBuf);
+    nrLDPC_debug_writeBuffer2File(nrLDPC_buffers_BN_PROC_RES, bnProcBufRes);
 #endif
 
     // BN results to CN processing buffer
@@ -211,18 +216,18 @@ static inline uint32_t nrLDPC_decoder_core(int8_t* p_llr, int8_t* p_out, t_nrLDP
 #endif
     if (BG == 1)
     {
-        nrLDPC_bn2cnProcBuf_BG1(p_lut, p_procBuf, Z);
+        nrLDPC_bn2cnProcBuf_BG1(p_lut, bnProcBufRes, cnProcBuf, Z);
     }
     else
     {
-        nrLDPC_bn2cnProcBuf_BG2(p_lut, p_procBuf, Z);
+        nrLDPC_bn2cnProcBuf_BG2(p_lut, bnProcBufRes, cnProcBuf, Z);
     }
 #ifdef NR_LDPC_PROFILER_DETAIL
     stop_meas(&p_profiler->bn2cnProcBuf);
 #endif
 
 #ifdef NR_LDPC_DEBUG_MODE
-    nrLDPC_debug_writeBuffer2File(nrLDPC_buffers_CN_PROC, p_procBuf);
+    nrLDPC_debug_writeBuffer2File(nrLDPC_buffers_CN_PROC, cnProcBuf);
 #endif
 
     // Parity Check not necessary here since it will fail
@@ -242,18 +247,18 @@ static inline uint32_t nrLDPC_decoder_core(int8_t* p_llr, int8_t* p_out, t_nrLDP
 #endif
         if (BG == 1)
         {
-            nrLDPC_cnProc_BG1(p_lut, p_procBuf, Z);
+            nrLDPC_cnProc_BG1(p_lut, cnProcBuf, cnProcBufRes, Z);
         }
         else
         {
-            nrLDPC_cnProc_BG2(p_lut, p_procBuf, Z);
+            nrLDPC_cnProc_BG2(p_lut, cnProcBuf, cnProcBufRes, Z);
         }
 #ifdef NR_LDPC_PROFILER_DETAIL
         stop_meas(&p_profiler->cnProc);
 #endif
 
 #ifdef NR_LDPC_DEBUG_MODE
-        nrLDPC_debug_writeBuffer2File(nrLDPC_buffers_CN_PROC_RES, p_procBuf);
+        nrLDPC_debug_writeBuffer2File(nrLDPC_buffers_CN_PROC_RES, cnProcBufRes);
 #endif
 
         // Send CN results back to BNs
@@ -262,43 +267,43 @@ static inline uint32_t nrLDPC_decoder_core(int8_t* p_llr, int8_t* p_out, t_nrLDP
 #endif
         if (BG == 1)
         {
-            nrLDPC_cn2bnProcBuf_BG1(p_lut, p_procBuf, Z);
+            nrLDPC_cn2bnProcBuf_BG1(p_lut, cnProcBufRes, bnProcBuf, Z);
         }
         else
         {
-            nrLDPC_cn2bnProcBuf_BG2(p_lut, p_procBuf, Z);
+            nrLDPC_cn2bnProcBuf_BG2(p_lut, cnProcBufRes, bnProcBuf, Z);
         }
 #ifdef NR_LDPC_PROFILER_DETAIL
         stop_meas(&p_profiler->cn2bnProcBuf);
 #endif
 
 #ifdef NR_LDPC_DEBUG_MODE
-        nrLDPC_debug_writeBuffer2File(nrLDPC_buffers_BN_PROC, p_procBuf);
+        nrLDPC_debug_writeBuffer2File(nrLDPC_buffers_BN_PROC, bnProcBuf);
 #endif
 
         // BN Processing
 #ifdef NR_LDPC_PROFILER_DETAIL
         start_meas(&p_profiler->bnProcPc);
 #endif
-        nrLDPC_bnProcPc(p_lut, p_procBuf, Z);
+        nrLDPC_bnProcPc(p_lut, bnProcBuf, bnProcBufRes, llrProcBuf, llrRes, Z);
 #ifdef NR_LDPC_PROFILER_DETAIL
         stop_meas(&p_profiler->bnProcPc);
 #endif
 
 #ifdef NR_LDPC_DEBUG_MODE
-        nrLDPC_debug_writeBuffer2File(nrLDPC_buffers_LLR_RES, p_procBuf);
+        nrLDPC_debug_writeBuffer2File(nrLDPC_buffers_LLR_RES, llrRes);
 #endif
 
 #ifdef NR_LDPC_PROFILER_DETAIL
         start_meas(&p_profiler->bnProc);
 #endif
-        nrLDPC_bnProc(p_lut, p_procBuf, Z);
+        nrLDPC_bnProc(p_lut, bnProcBuf, bnProcBufRes, llrRes, Z);
 #ifdef NR_LDPC_PROFILER_DETAIL
         stop_meas(&p_profiler->bnProc);
 #endif
 
 #ifdef NR_LDPC_DEBUG_MODE
-        nrLDPC_debug_writeBuffer2File(nrLDPC_buffers_BN_PROC_RES, p_procBuf);
+        nrLDPC_debug_writeBuffer2File(nrLDPC_buffers_BN_PROC_RES, bnProcBufRes);
 #endif
 
         // BN results to CN processing buffer
@@ -307,18 +312,18 @@ static inline uint32_t nrLDPC_decoder_core(int8_t* p_llr, int8_t* p_out, t_nrLDP
 #endif
         if (BG == 1)
         {
-            nrLDPC_bn2cnProcBuf_BG1(p_lut, p_procBuf, Z);
+            nrLDPC_bn2cnProcBuf_BG1(p_lut, bnProcBufRes, cnProcBuf, Z);
         }
         else
         {
-            nrLDPC_bn2cnProcBuf_BG2(p_lut, p_procBuf, Z);
+            nrLDPC_bn2cnProcBuf_BG2(p_lut, bnProcBufRes, cnProcBuf, Z);
         }
 #ifdef NR_LDPC_PROFILER_DETAIL
         stop_meas(&p_profiler->bn2cnProcBuf);
 #endif
 
 #ifdef NR_LDPC_DEBUG_MODE
-        nrLDPC_debug_writeBuffer2File(nrLDPC_buffers_CN_PROC, p_procBuf);
+        nrLDPC_debug_writeBuffer2File(nrLDPC_buffers_CN_PROC, cnProcBuf);
 #endif
 
         // Parity Check
@@ -328,123 +333,11 @@ static inline uint32_t nrLDPC_decoder_core(int8_t* p_llr, int8_t* p_out, t_nrLDP
 #endif
         if (BG == 1)
         {
-            pcRes = nrLDPC_cnProcPc_BG1(p_lut, p_procBuf, Z);
+            pcRes = nrLDPC_cnProcPc_BG1(p_lut, cnProcBuf, cnProcBufRes, Z);
         }
         else
         {
-            pcRes = nrLDPC_cnProcPc_BG2(p_lut, p_procBuf, Z);
-        }
-#ifdef NR_LDPC_PROFILER_DETAIL
-        stop_meas(&p_profiler->cnProcPc);
-#endif
-#endif
-    }
-
-    // Last iteration
-    if ( (i < numMaxIter) && (pcRes != 0) )
-    {
-        // Increase iteration counter
-        i++;
-
-        // CN processing
-#ifdef NR_LDPC_PROFILER_DETAIL
-        start_meas(&p_profiler->cnProc);
-#endif
-        if (BG == 1)
-        {
-            nrLDPC_cnProc_BG1(p_lut, p_procBuf, Z);
-        }
-        else
-        {
-            nrLDPC_cnProc_BG2(p_lut, p_procBuf, Z);
-        }
-#ifdef NR_LDPC_PROFILER_DETAIL
-        stop_meas(&p_profiler->cnProc);
-#endif
-
-#ifdef NR_LDPC_DEBUG_MODE
-        nrLDPC_debug_writeBuffer2File(nrLDPC_buffers_CN_PROC_RES, p_procBuf);
-#endif
-
-        // Send CN results back to BNs
-#ifdef NR_LDPC_PROFILER_DETAIL
-        start_meas(&p_profiler->cn2bnProcBuf);
-#endif
-        if (BG == 1)
-        {
-            nrLDPC_cn2bnProcBuf_BG1(p_lut, p_procBuf, Z);
-        }
-        else
-        {
-            nrLDPC_cn2bnProcBuf_BG2(p_lut, p_procBuf, Z);
-        }
-#ifdef NR_LDPC_PROFILER_DETAIL
-        stop_meas(&p_profiler->cn2bnProcBuf);
-#endif
-
-#ifdef NR_LDPC_DEBUG_MODE
-        nrLDPC_debug_writeBuffer2File(nrLDPC_buffers_BN_PROC, p_procBuf);
-#endif
-
-        // BN Processing
-#ifdef NR_LDPC_PROFILER_DETAIL
-        start_meas(&p_profiler->bnProcPc);
-#endif
-        nrLDPC_bnProcPc(p_lut, p_procBuf, Z);
-#ifdef NR_LDPC_PROFILER_DETAIL
-        stop_meas(&p_profiler->bnProcPc);
-#endif
-
-#ifdef NR_LDPC_DEBUG_MODE
-        nrLDPC_debug_writeBuffer2File(nrLDPC_buffers_LLR_RES, p_procBuf);
-#endif
-
-        // If parity check not enabled, no need to send the BN proc results
-        // back to CNs
-#ifdef NR_LDPC_ENABLE_PARITY_CHECK
-#ifdef NR_LDPC_PROFILER_DETAIL
-        start_meas(&p_profiler->bnProc);
-#endif
-        nrLDPC_bnProc(p_lut, p_procBuf, Z);
-#ifdef NR_LDPC_PROFILER_DETAIL
-        stop_meas(&p_profiler->bnProc);
-#endif
-
-#ifdef NR_LDPC_DEBUG_MODE
-        nrLDPC_debug_writeBuffer2File(nrLDPC_buffers_BN_PROC_RES, p_procBuf);
-#endif
-
-        // BN results to CN processing buffer
-#ifdef NR_LDPC_PROFILER_DETAIL
-        start_meas(&p_profiler->bn2cnProcBuf);
-#endif
-        if (BG == 1)
-        {
-            nrLDPC_bn2cnProcBuf_BG1(p_lut, p_procBuf, Z);
-        }
-        else
-        {
-            nrLDPC_bn2cnProcBuf_BG2(p_lut, p_procBuf, Z);
-        }
-#ifdef NR_LDPC_PROFILER_DETAIL
-        stop_meas(&p_profiler->bn2cnProcBuf);
-#endif
-
-#ifdef NR_LDPC_DEBUG_MODE
-        nrLDPC_debug_writeBuffer2File(nrLDPC_buffers_CN_PROC, p_procBuf);
-#endif
-
-        // Parity Check
-#ifdef NR_LDPC_PROFILER_DETAIL
-        start_meas(&p_profiler->cnProcPc);
-#endif
-        if (BG == 1)
-        {
-            pcRes = nrLDPC_cnProcPc_BG1(p_lut, p_procBuf, Z);
-        }
-        else
-        {
-            pcRes = nrLDPC_cnProcPc_BG2(p_lut, p_procBuf, Z);
+            pcRes = nrLDPC_cnProcPc_BG2(p_lut, cnProcBuf, cnProcBufRes, Z);
         }
 #ifdef NR_LDPC_PROFILER_DETAIL
         stop_meas(&p_profiler->cnProcPc);
@@ -466,7 +359,7 @@ static inline uint32_t nrLDPC_decoder_core(int8_t* p_llr, int8_t* p_out, t_nrLDP
 #ifdef NR_LDPC_PROFILER_DETAIL
     start_meas(&p_profiler->llrRes2llrOut);
 #endif
-    nrLDPC_llrRes2llrOut(p_lut, p_llrOut, p_procBuf, Z, BG);
+    nrLDPC_llrRes2llrOut(p_lut, p_llrOut, llrRes, Z, BG);
 #ifdef NR_LDPC_PROFILER_DETAIL
     stop_meas(&p_profiler->llrRes2llrOut);
 #endif
diff --git a/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_init_mem.h b/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_init_mem.h
deleted file mode 100644
index f08549130ee08db0296b623482cf8411ef71b257..0000000000000000000000000000000000000000
--- a/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_init_mem.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * 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 nrLDPC_init_mem.h
- * \brief Defines the function to initialize the LDPC decoder and sets correct LUTs.
- * \author Sebastian Wagner (TCL Communications) Email: <mailto:sebastian.wagner@tcl.com>
- * \date 07-12-2018
- * \version 1.0
- * \note
- * \warning
- */
-
-#ifndef __NR_LDPC_INIT_MEM__H__
-#define __NR_LDPC_INIT_MEM__H__
-
-#include <stdlib.h>
-#include "nrLDPC_types.h"
-
-/**
-   \brief Allocates 32 byte aligned memory and initializes to zero
-   \param size Input size in bytes
-   \return Pointer to memory
-*/
-static inline void* malloc32_clear(size_t size)
-{
-    void* ptr = (void*) memalign(32, size+32);
-    memset(ptr, 0, size);
-    return ptr;
-}
-
-/**
-   \brief Allocates and initializes the internal decoder processing buffers
-   \param p_decParams Pointer to decoder parameters
-   \param p_lut Pointer to decoder LUTs
-   \return Number of LLR values
-*/
-static inline t_nrLDPC_procBuf* nrLDPC_init_mem(void)
-{
-    t_nrLDPC_procBuf* p_procBuf = (t_nrLDPC_procBuf*) malloc32_clear(sizeof(t_nrLDPC_procBuf));
-
-    if (p_procBuf)
-    {
-        p_procBuf->cnProcBuf    = (int8_t*) malloc32_clear(NR_LDPC_SIZE_CN_PROC_BUF*sizeof(int8_t));
-        p_procBuf->cnProcBufRes = (int8_t*) malloc32_clear(NR_LDPC_SIZE_CN_PROC_BUF*sizeof(int8_t));
-        p_procBuf->bnProcBuf    = (int8_t*) malloc32_clear(NR_LDPC_SIZE_BN_PROC_BUF*sizeof(int8_t));
-        p_procBuf->bnProcBufRes = (int8_t*) malloc32_clear(NR_LDPC_SIZE_BN_PROC_BUF*sizeof(int8_t));
-        p_procBuf->llrRes       = (int8_t*) malloc32_clear(NR_LDPC_MAX_NUM_LLR     *sizeof(int8_t));
-        p_procBuf->llrProcBuf   = (int8_t*) malloc32_clear(NR_LDPC_MAX_NUM_LLR     *sizeof(int8_t));
-    }
-
-    return(p_procBuf);
-}
-
-static inline void nrLDPC_free_mem(t_nrLDPC_procBuf* p_procBuf)
-{
-    free(p_procBuf->cnProcBuf);
-    free(p_procBuf->cnProcBufRes);
-    free(p_procBuf->bnProcBuf);
-    free(p_procBuf->bnProcBufRes);
-    free(p_procBuf->llrRes);
-    free(p_procBuf->llrProcBuf);
-
-    free(p_procBuf);
-}
-#endif
diff --git a/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_mPass.h b/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_mPass.h
index b76750459d90830e3abd4ba103befb182e24376d..7f514d5cfa6ff2a457f79c2493ea314c3517cf24 100644
--- a/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_mPass.h
+++ b/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_mPass.h
@@ -97,7 +97,7 @@ static inline void *nrLDPC_circ_memcpy(int8_t *str1, const int8_t *str2, uint16_
    \param Z Lifting size
    \param BG Base graph
 */
-static inline void nrLDPC_llr2llrProcBuf(t_nrLDPC_lut* p_lut, int8_t* llr, t_nrLDPC_procBuf* p_procBuf, uint16_t Z, uint8_t BG)
+static inline void nrLDPC_llr2llrProcBuf(t_nrLDPC_lut* p_lut, int8_t* llr, int8_t* llrProcBuf, uint16_t Z, uint8_t BG)
 {
     uint32_t i;
     const uint8_t numBn2CnG1 = p_lut->numBnInBnGroups[0];
@@ -109,7 +109,6 @@ static inline void nrLDPC_llr2llrProcBuf(t_nrLDPC_lut* p_lut, int8_t* llr, t_nrL
     const uint8_t*  lut_llr2llrProcBufBnPos = p_lut->llr2llrProcBufBnPos;
 
     uint32_t idxBn;
-    int8_t* llrProcBuf = p_procBuf->llrProcBuf;
 
     // Copy LLRs connected to 1 CN
     if (numBn2CnG1 > 0)
@@ -133,7 +132,7 @@ static inline void nrLDPC_llr2llrProcBuf(t_nrLDPC_lut* p_lut, int8_t* llr, t_nrL
    \param p_procBuf Pointer to the processing buffers
    \param Z Lifting size
 */
-static inline void nrLDPC_llr2CnProcBuf_BG1(t_nrLDPC_lut* p_lut, int8_t* llr, t_nrLDPC_procBuf* p_procBuf, uint16_t Z)
+static inline void nrLDPC_llr2CnProcBuf_BG1(t_nrLDPC_lut* p_lut, int8_t* llr, int8_t* cnProcBuf, uint16_t Z)
 {
     const uint16_t (*lut_circShift_CNG3) [lut_numCnInCnGroups_BG1_R13[0]] = (const uint16_t(*)[lut_numCnInCnGroups_BG1_R13[0]]) p_lut->circShift[0];
     const uint16_t (*lut_circShift_CNG4) [lut_numCnInCnGroups_BG1_R13[1]] = (const uint16_t(*)[lut_numCnInCnGroups_BG1_R13[1]]) p_lut->circShift[1];
@@ -158,7 +157,6 @@ static inline void nrLDPC_llr2CnProcBuf_BG1(t_nrLDPC_lut* p_lut, int8_t* llr, t_
     const uint8_t*  lut_numCnInCnGroups = p_lut->numCnInCnGroups;
     const uint32_t* lut_startAddrCnGroups = p_lut->startAddrCnGroups;
 
-    int8_t* cnProcBuf = p_procBuf->cnProcBuf;
     uint32_t i;
     uint32_t j;
 
@@ -342,7 +340,7 @@ static inline void nrLDPC_llr2CnProcBuf_BG1(t_nrLDPC_lut* p_lut, int8_t* llr, t_
    \param p_procBuf Pointer to the processing buffers
    \param Z Lifting size
 */
-static inline void nrLDPC_llr2CnProcBuf_BG2(t_nrLDPC_lut* p_lut, int8_t* llr, t_nrLDPC_procBuf* p_procBuf, uint16_t Z)
+static inline void nrLDPC_llr2CnProcBuf_BG2(t_nrLDPC_lut* p_lut, int8_t* llr, int8_t* cnProcBuf, uint16_t Z)
 {
     const uint16_t (*lut_circShift_CNG3)  [lut_numCnInCnGroups_BG2_R15[0]] = (const uint16_t(*)[lut_numCnInCnGroups_BG2_R15[0]]) p_lut->circShift[0];
     const uint16_t (*lut_circShift_CNG4)  [lut_numCnInCnGroups_BG2_R15[1]] = (const uint16_t(*)[lut_numCnInCnGroups_BG2_R15[1]]) p_lut->circShift[1];
@@ -361,7 +359,6 @@ static inline void nrLDPC_llr2CnProcBuf_BG2(t_nrLDPC_lut* p_lut, int8_t* llr, t_
     const uint8_t*  lut_numCnInCnGroups = p_lut->numCnInCnGroups;
     const uint32_t* lut_startAddrCnGroups = p_lut->startAddrCnGroups;
 
-    int8_t* cnProcBuf = p_procBuf->cnProcBuf;
     uint32_t i;
     uint32_t j;
 
@@ -478,7 +475,7 @@ static inline void nrLDPC_llr2CnProcBuf_BG2(t_nrLDPC_lut* p_lut, int8_t* llr, t_
    \param p_procBuf Pointer to the processing buffers
    \param Z Lifting size
 */
-static inline void nrLDPC_cn2bnProcBuf_BG2(t_nrLDPC_lut* p_lut, t_nrLDPC_procBuf* p_procBuf, uint16_t Z)
+static inline void nrLDPC_cn2bnProcBuf_BG2(t_nrLDPC_lut* p_lut, int8_t* cnProcBufRes, int8_t* bnProcBuf, uint16_t Z)
 {
     const uint8_t*  lut_numCnInCnGroups = p_lut->numCnInCnGroups;
     const uint32_t* lut_startAddrCnGroups = p_lut->startAddrCnGroups;
@@ -504,9 +501,6 @@ static inline void nrLDPC_cn2bnProcBuf_BG2(t_nrLDPC_lut* p_lut, t_nrLDPC_procBuf
     const uint8_t (*lut_bnPosBnProcBuf_CNG8)  [lut_numCnInCnGroups[4]] = (const uint8_t(*)[lut_numCnInCnGroups[4]]) p_lut->bnPosBnProcBuf[4];
     const uint8_t (*lut_bnPosBnProcBuf_CNG10) [lut_numCnInCnGroups[5]] = (const uint8_t(*)[lut_numCnInCnGroups[5]]) p_lut->bnPosBnProcBuf[5];
 
-    int8_t* cnProcBufRes = p_procBuf->cnProcBufRes;
-    int8_t* bnProcBuf    = p_procBuf->bnProcBuf;
-
     int8_t* p_cnProcBufRes;
     uint32_t bitOffsetInGroup;
     uint32_t i;
@@ -621,7 +615,7 @@ static inline void nrLDPC_cn2bnProcBuf_BG2(t_nrLDPC_lut* p_lut, t_nrLDPC_procBuf
    \param p_procBuf Pointer to the processing buffers
    \param Z Lifting size
 */
-static inline void nrLDPC_cn2bnProcBuf_BG1(t_nrLDPC_lut* p_lut, t_nrLDPC_procBuf* p_procBuf, uint16_t Z)
+static inline void nrLDPC_cn2bnProcBuf_BG1(t_nrLDPC_lut* p_lut, int8_t* cnProcBufRes, int8_t* bnProcBuf, uint16_t Z)
 {
     const uint8_t*  lut_numCnInCnGroups = p_lut->numCnInCnGroups;
     const uint32_t* lut_startAddrCnGroups = p_lut->startAddrCnGroups;
@@ -655,9 +649,6 @@ static inline void nrLDPC_cn2bnProcBuf_BG1(t_nrLDPC_lut* p_lut, t_nrLDPC_procBuf
     const uint8_t (*lut_bnPosBnProcBuf_CNG10)[lut_numCnInCnGroups[7]] = (const uint8_t(*)[lut_numCnInCnGroups[7]]) p_lut->bnPosBnProcBuf[7];
     const uint8_t (*lut_bnPosBnProcBuf_CNG19)[lut_numCnInCnGroups[8]] = (const uint8_t(*)[lut_numCnInCnGroups[8]]) p_lut->bnPosBnProcBuf[8];
 
-    int8_t* cnProcBufRes = p_procBuf->cnProcBufRes;
-    int8_t* bnProcBuf    = p_procBuf->bnProcBuf;
-
     int8_t* p_cnProcBufRes;
     uint32_t bitOffsetInGroup;
     uint32_t i;
@@ -819,7 +810,7 @@ static inline void nrLDPC_cn2bnProcBuf_BG1(t_nrLDPC_lut* p_lut, t_nrLDPC_procBuf
    \param p_procBuf Pointer to the processing buffers
    \param Z Lifting size
 */
-static inline void nrLDPC_bn2cnProcBuf_BG2(t_nrLDPC_lut* p_lut, t_nrLDPC_procBuf* p_procBuf, uint16_t Z)
+static inline void nrLDPC_bn2cnProcBuf_BG2(t_nrLDPC_lut* p_lut, int8_t* bnProcBufRes, int8_t* cnProcBuf, uint16_t Z)
 {
     const uint8_t*  lut_numCnInCnGroups = p_lut->numCnInCnGroups;
     const uint32_t* lut_startAddrCnGroups = p_lut->startAddrCnGroups;
@@ -845,9 +836,6 @@ static inline void nrLDPC_bn2cnProcBuf_BG2(t_nrLDPC_lut* p_lut, t_nrLDPC_procBuf
     const uint8_t (*lut_bnPosBnProcBuf_CNG8)  [lut_numCnInCnGroups[4]] = (const uint8_t(*)[lut_numCnInCnGroups[4]]) p_lut->bnPosBnProcBuf[4];
     const uint8_t (*lut_bnPosBnProcBuf_CNG10) [lut_numCnInCnGroups[5]] = (const uint8_t(*)[lut_numCnInCnGroups[5]]) p_lut->bnPosBnProcBuf[5];
 
-    int8_t* cnProcBuf    = p_procBuf->cnProcBuf;
-    int8_t* bnProcBufRes = p_procBuf->bnProcBufRes;
-
     int8_t* p_cnProcBuf;
     uint32_t bitOffsetInGroup;
     uint32_t i;
@@ -961,7 +949,7 @@ static inline void nrLDPC_bn2cnProcBuf_BG2(t_nrLDPC_lut* p_lut, t_nrLDPC_procBuf
    \param p_procBuf Pointer to the processing buffers
    \param Z Lifting size
 */
-static inline void nrLDPC_bn2cnProcBuf_BG1(t_nrLDPC_lut* p_lut, t_nrLDPC_procBuf* p_procBuf, uint16_t Z)
+static inline void nrLDPC_bn2cnProcBuf_BG1(t_nrLDPC_lut* p_lut, int8_t* bnProcBufRes, int8_t* cnProcBuf, uint16_t Z)
 {
     const uint8_t*  lut_numCnInCnGroups = p_lut->numCnInCnGroups;
     const uint32_t* lut_startAddrCnGroups = p_lut->startAddrCnGroups;
@@ -995,9 +983,6 @@ static inline void nrLDPC_bn2cnProcBuf_BG1(t_nrLDPC_lut* p_lut, t_nrLDPC_procBuf
     const uint8_t (*lut_bnPosBnProcBuf_CNG10)[lut_numCnInCnGroups[7]] = (const uint8_t(*)[lut_numCnInCnGroups[7]]) p_lut->bnPosBnProcBuf[7];
     const uint8_t (*lut_bnPosBnProcBuf_CNG19)[lut_numCnInCnGroups[8]] = (const uint8_t(*)[lut_numCnInCnGroups[8]]) p_lut->bnPosBnProcBuf[8];
 
-    int8_t* cnProcBuf    = p_procBuf->cnProcBuf;
-    int8_t* bnProcBufRes = p_procBuf->bnProcBufRes;
-
     int8_t* p_cnProcBuf;
     uint32_t bitOffsetInGroup;
     uint32_t i;
@@ -1157,7 +1142,7 @@ static inline void nrLDPC_bn2cnProcBuf_BG1(t_nrLDPC_lut* p_lut, t_nrLDPC_procBuf
    \param Z Lifting size
    \param BG Base graph
 */
-static inline void nrLDPC_llrRes2llrOut(t_nrLDPC_lut* p_lut, int8_t* llrOut, t_nrLDPC_procBuf* p_procBuf, uint16_t Z, uint8_t BG)
+static inline void nrLDPC_llrRes2llrOut(t_nrLDPC_lut* p_lut, int8_t* llrOut, int8_t* llrRes, uint16_t Z, uint8_t BG)
 {
     uint32_t i;
     const uint8_t numBn2CnG1 = p_lut->numBnInBnGroups[0];
@@ -1168,7 +1153,6 @@ static inline void nrLDPC_llrRes2llrOut(t_nrLDPC_lut* p_lut, int8_t* llrOut, t_n
     const uint16_t* lut_llr2llrProcBufAddr = p_lut->llr2llrProcBufAddr;
     const uint8_t*  lut_llr2llrProcBufBnPos = p_lut->llr2llrProcBufBnPos;
 
-    int8_t* llrRes = p_procBuf->llrRes;
     int8_t* p_llrOut = &llrOut[0];
     uint32_t idxBn;
 
diff --git a/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_tools/nrLDPC_debug.h b/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_tools/nrLDPC_debug.h
index e4dcb56edd3ef02dfc86a3f427407b99ebd5c466..41c0a474a4457ad6ea975f3b15c5fa4ed50ceed9 100644
--- a/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_tools/nrLDPC_debug.h
+++ b/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_tools/nrLDPC_debug.h
@@ -87,38 +87,38 @@ static inline void nrLDPC_initFile(const char* fileName)
    \brief Writes data of predefined buffers to file
    \param buffer Enum of buffer name to write
 */
-static inline void nrLDPC_debug_writeBuffer2File(e_nrLDPC_buffers buffer, t_nrLDPC_procBuf* p_procBuf)
+static inline void nrLDPC_debug_writeBuffer2File(e_nrLDPC_buffers buffer, int8_t* p_buffer)
 {
     switch (buffer)
     {
     case nrLDPC_buffers_LLR_PROC:
     {
-        nrLDPC_writeFile("llrProcBuf.txt", p_procBuf->llrProcBuf, NR_LDPC_MAX_NUM_LLR);
+        nrLDPC_writeFile("llrProcBuf.txt", p_buffer, NR_LDPC_MAX_NUM_LLR);
         break;
     }
     case nrLDPC_buffers_CN_PROC:
     {
-        nrLDPC_writeFile("cnProcBuf.txt", p_procBuf->cnProcBuf, NR_LDPC_SIZE_CN_PROC_BUF);
+        nrLDPC_writeFile("cnProcBuf.txt", p_buffer, NR_LDPC_SIZE_CN_PROC_BUF);
         break;
     }
     case nrLDPC_buffers_CN_PROC_RES:
     {
-        nrLDPC_writeFile("cnProcBufRes.txt", p_procBuf->cnProcBufRes, NR_LDPC_SIZE_CN_PROC_BUF);
+        nrLDPC_writeFile("cnProcBufRes.txt", p_buffer, NR_LDPC_SIZE_CN_PROC_BUF);
         break;
     }
     case nrLDPC_buffers_BN_PROC:
     {
-        nrLDPC_writeFile("bnProcBuf.txt", p_procBuf->bnProcBuf, NR_LDPC_SIZE_BN_PROC_BUF);
+        nrLDPC_writeFile("bnProcBuf.txt", p_buffer, NR_LDPC_SIZE_BN_PROC_BUF);
         break;
     }
     case nrLDPC_buffers_BN_PROC_RES:
     {
-        nrLDPC_writeFile("bnProcBufRes.txt", p_procBuf->bnProcBufRes, NR_LDPC_SIZE_BN_PROC_BUF);
+        nrLDPC_writeFile("bnProcBufRes.txt", p_buffer, NR_LDPC_SIZE_BN_PROC_BUF);
         break;
     }
     case nrLDPC_buffers_LLR_RES:
     {
-        nrLDPC_writeFile("llrRes.txt", p_procBuf->llrRes, NR_LDPC_MAX_NUM_LLR);
+        nrLDPC_writeFile("llrRes.txt", p_buffer, NR_LDPC_MAX_NUM_LLR);
         break;
     }
     }
diff --git a/openair1/PHY/CODING/nrLDPC_defs.h b/openair1/PHY/CODING/nrLDPC_defs.h
index a6fb44cb0dd40bfd1b0995043ec6893e91317dff..0c9c78c3ac06ec9c5f56614a3291f83e104b7f4e 100644
--- a/openair1/PHY/CODING/nrLDPC_defs.h
+++ b/openair1/PHY/CODING/nrLDPC_defs.h
@@ -71,5 +71,5 @@ typedef int(*nrLDPC_encoderfunc_t)(unsigned char **,unsigned char **,int,int,sho
    \param p_llrOut Output vector
    \param p_profiler LDPC profiler statistics
 */
-typedef int32_t(*nrLDPC_decoderfunc_t)(t_nrLDPC_dec_params *, int8_t *, int8_t *, t_nrLDPC_procBuf *, t_nrLDPC_time_stats * );
+typedef int32_t(*nrLDPC_decoderfunc_t)(t_nrLDPC_dec_params* , int8_t*, int8_t* , t_nrLDPC_time_stats* );
 #endif
diff --git a/openair1/PHY/CODING/nrLDPC_extern.h b/openair1/PHY/CODING/nrLDPC_extern.h
index b75b38fc76e77ac3f2955f0b332b71eb33e567ba..b358119408b61bae73af411200f9a5cef9f139a9 100644
--- a/openair1/PHY/CODING/nrLDPC_extern.h
+++ b/openair1/PHY/CODING/nrLDPC_extern.h
@@ -34,5 +34,4 @@ extern nrLDPC_initcallfunc_t nrLDPC_initcall;
 extern nrLDPC_decoderfunc_t nrLDPC_decoder;
 extern nrLDPC_encoderfunc_t nrLDPC_encoder;
 // inline functions:
-#include "openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_init_mem.h"
 #endif
diff --git a/openair1/PHY/CODING/nr_rate_matching.c b/openair1/PHY/CODING/nr_rate_matching.c
index 29cba0a55729b2b7347a4a8b8324afeeb9a10f43..8c105c37e69cb0706006b83a789eba29c981fca2 100644
--- a/openair1/PHY/CODING/nr_rate_matching.c
+++ b/openair1/PHY/CODING/nr_rate_matching.c
@@ -307,62 +307,76 @@ void nr_interleaving_ldpc(uint32_t E, uint8_t Qm, uint8_t *e,uint8_t *f)
 
 
 void nr_deinterleaving_ldpc(uint32_t E, uint8_t Qm, int16_t *e,int16_t *f)
-{
+{ 
 
-  int16_t *e1,*e2,*e3,*e4,*e5,*e6,*e7;
+  
   switch(Qm) {
   case 2:
-    e1=e+(E/2);
-    for (int j = 0,j2=0; j< E/2; j+=2,j2+=4){
-      e[j]  = f[j2];
-      e1[j] = f[j2+1];
-      e[j+1]  = f[j2+2];
-      e1[j+1] = f[j2+3];
+    {
+      AssertFatal(E%2==0,"");
+      int16_t *e1=e+(E/2);
+      int16_t *end=f+E-1;
+      while( f<end ){
+        *e++  = *f++;
+        *e1++ = *f++;
+      }
     }
     break;
   case 4:
-    e1=e+(E/4);
-    e2=e1+(E/4);
-    e3=e2+(E/4);
-    for (int j = 0,j2=0; j< E/4; j++,j2+=4){
-      e[j]  = f[j2];
-      e1[j] = f[j2+1];
-      e2[j] = f[j2+2];
-      e3[j] = f[j2+3];
+    {
+      AssertFatal(E%4==0,"");
+      int16_t *e1=e+(E/4);
+      int16_t *e2=e1+(E/4);
+      int16_t *e3=e2+(E/4);
+      int16_t *end=f+E-3;
+      while( f<end ){ 
+        *e++  = *f++;
+        *e1++ = *f++;
+        *e2++ = *f++;
+        *e3++ = *f++;
+      }
     }
     break;
   case 6:
-    e1=e+(E/6);
-    e2=e1+(E/6);
-    e3=e2+(E/6);
-    e4=e3+(E/6);
-    e5=e4+(E/6);
-    for (int j = 0,j2=0; j< E/6; j++,j2+=6){
-      e[j]  = f[j2];
-      e1[j] = f[j2+1];
-      e2[j] = f[j2+2];
-      e3[j] = f[j2+3];
-      e4[j] = f[j2+4];
-      e5[j] = f[j2+5];
+    {
+      AssertFatal(E%6==0,"");
+      int16_t *e1=e+(E/6);
+      int16_t *e2=e1+(E/6);
+      int16_t *e3=e2+(E/6);
+      int16_t *e4=e3+(E/6);
+      int16_t *e5=e4+(E/6);
+      int16_t *end=f+E-5;
+     while( f<end ){ 
+        *e++  = *f++;
+        *e1++ = *f++;
+        *e2++ = *f++;
+        *e3++ = *f++;
+        *e4++ = *f++;
+        *e5++ = *f++;
+      }
     }
     break;
   case 8:
-    e1=e+(E/8);
-    e2=e1+(E/8);
-    e3=e2+(E/8);
-    e4=e3+(E/8);
-    e5=e4+(E/8);
-    e6=e5+(E/8);
-    e7=e6+(E/8);
-    for (int j = 0,j2=0; j< E/8; j++,j2+=8){
-      e[j]  = f[j2];
-      e1[j] = f[j2+1];
-      e2[j] = f[j2+2];
-      e3[j] = f[j2+3];
-      e4[j] = f[j2+4];
-      e5[j] = f[j2+5];
-      e6[j] = f[j2+6];
-      e7[j] = f[j2+7];
+    {
+      AssertFatal(E%8==0,"");
+      int16_t *e1=e+(E/8);
+      int16_t *e2=e1+(E/8);
+      int16_t *e3=e2+(E/8);
+      int16_t *e4=e3+(E/8);
+      int16_t *e5=e4+(E/8);
+      int16_t *e6=e5+(E/8);
+      int16_t *e7=e6+(E/8);
+      int16_t *end=f+E-7;
+      while( f<end ){
+        *e++  = *f++;
+        *e1++ = *f++;
+        *e2++ = *f++;
+        *e3++ = *f++;
+        *e4++ = *f++;
+        *e5++ = *f++;
+        *e6++ = *f++;
+        *e7++ = *f++;
+      }
     }
     break;
   default:
diff --git a/openair1/PHY/CODING/nr_segmentation.c b/openair1/PHY/CODING/nr_segmentation.c
index 281e61cda523fc3c9621f81c4d2f1ab183f0c5a5..f43813a6ca1f7b0f872308c6d8263dd91f4a1291 100644
--- a/openair1/PHY/CODING/nr_segmentation.c
+++ b/openair1/PHY/CODING/nr_segmentation.c
@@ -87,7 +87,7 @@ if ((Kprime%Kb) > 0)
 else
   Z = (Kprime/Kb);
 
- LOG_D(PHY,"nr segmetation B %u Bprime %u Kprime %u z %u \n", B, Bprime, Kprime, Z);
+ LOG_D(PHY,"nr segmentation B %u Bprime %u Kprime %u z %u \n", B, Bprime, Kprime, Z);
 	  
   if (Z <= 2) {
     *K = 2;
diff --git a/openair1/PHY/INIT/nr_init.c b/openair1/PHY/INIT/nr_init.c
index aeaccc2466946f2ad7a46dd9ee04f686a516523a..17e464c25ea4296df06b023f66574adced9cf684 100644
--- a/openair1/PHY/INIT/nr_init.c
+++ b/openair1/PHY/INIT/nr_init.c
@@ -536,6 +536,7 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB,
   }
 
   nr_generate_modulation_table();
+  gNB->pdcch_gold_init = cfg->cell_config.phy_cell_id.value;
   nr_init_pdcch_dmrs(gNB, cfg->cell_config.phy_cell_id.value);
   nr_init_pbch_interleaver(gNB->nr_pbch_interleaver);
 
@@ -549,28 +550,30 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB,
     pdsch_dmrs[slot] = (uint32_t ***)malloc16(fp->symbols_per_slot*sizeof(uint32_t **));
     AssertFatal(pdsch_dmrs[slot]!=NULL, "NR init: pdsch_dmrs for slot %d - malloc failed\n", slot);
 
-    int nb_codewords = NR_MAX_NB_LAYERS > 4 ? 2 : 1;
     for (int symb=0; symb<fp->symbols_per_slot; symb++) {
-      pdsch_dmrs[slot][symb] = (uint32_t **)malloc16(nb_codewords*sizeof(uint32_t *));
+      pdsch_dmrs[slot][symb] = (uint32_t **)malloc16(NR_NB_NSCID*sizeof(uint32_t *));
       AssertFatal(pdsch_dmrs[slot][symb]!=NULL, "NR init: pdsch_dmrs for slot %d symbol %d - malloc failed\n", slot, symb);
 
-      for (int q=0; q<nb_codewords; q++) {
+      for (int q=0; q<NR_NB_NSCID; q++) {
         pdsch_dmrs[slot][symb][q] = (uint32_t *)malloc16(pdsch_dmrs_init_length*sizeof(uint32_t));
-        AssertFatal(pdsch_dmrs[slot][symb][q]!=NULL, "NR init: pdsch_dmrs for slot %d symbol %d codeword %d - malloc failed\n", slot, symb, q);
+        AssertFatal(pdsch_dmrs[slot][symb][q]!=NULL, "NR init: pdsch_dmrs for slot %d symbol %d nscid %d - malloc failed\n", slot, symb, q);
       }
     }
   }
 
-  nr_init_pdsch_dmrs(gNB, cfg->cell_config.phy_cell_id.value);
+
+  for (int nscid = 0; nscid < NR_NB_NSCID; nscid++) {
+    gNB->pdsch_gold_init[nscid] = cfg->cell_config.phy_cell_id.value;
+    nr_init_pdsch_dmrs(gNB, nscid, cfg->cell_config.phy_cell_id.value);
+  }
 
   //PUSCH DMRS init
-  gNB->nr_gold_pusch_dmrs = (uint32_t ****)malloc16(2*sizeof(uint32_t ***));
+  gNB->nr_gold_pusch_dmrs = (uint32_t ****)malloc16(NR_NB_NSCID*sizeof(uint32_t ***));
 
   uint32_t ****pusch_dmrs = gNB->nr_gold_pusch_dmrs;
 
-  // ceil(((NB_RB*6(k)*2(QPSK)/32) // 3 RE *2(QPSK)
   int pusch_dmrs_init_length =  ((fp->N_RB_UL*12)>>5)+1;
-  for(int nscid=0; nscid<2; nscid++) {
+  for(int nscid=0; nscid<NR_NB_NSCID; nscid++) {
     pusch_dmrs[nscid] = (uint32_t ***)malloc16(fp->slots_per_frame*sizeof(uint32_t **));
     AssertFatal(pusch_dmrs[nscid]!=NULL, "NR init: pusch_dmrs for nscid %d - malloc failed\n", nscid);
 
@@ -585,9 +588,10 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB,
     }
   }
 
-  uint32_t Nid_pusch[2] = {cfg->cell_config.phy_cell_id.value,cfg->cell_config.phy_cell_id.value};
-  LOG_D(PHY,"Initializing PUSCH DMRS Gold sequence with (%x,%x)\n",Nid_pusch[0],Nid_pusch[1]);
-  nr_gold_pusch(gNB, &Nid_pusch[0]);
+  for (int nscid=0; nscid<NR_NB_NSCID; nscid++) {
+    gNB->pusch_gold_init[nscid] = cfg->cell_config.phy_cell_id.value;
+    nr_gold_pusch(gNB, nscid, gNB->pusch_gold_init[nscid]);
+  }
 
   //CSI RS init
   gNB->nr_gold_csi_rs = (uint32_t ***)malloc16(fp->slots_per_frame*sizeof(uint32_t **));
@@ -607,6 +611,7 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB,
     }
   }
 
+  gNB->csi_gold_init = cfg->cell_config.phy_cell_id.value;
   nr_init_csi_rs(gNB, cfg->cell_config.phy_cell_id.value);
 
   for (int id=0; id<NUMBER_OF_NR_SRS_MAX; id++) {
@@ -644,12 +649,12 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB,
   common_vars->beam_id = (uint8_t **)malloc16(Ptx*sizeof(uint8_t*));
 
   for (i=0;i<Ptx;i++){
-      common_vars->txdataF[i] = (int32_t*)malloc16_clear(fp->samples_per_frame_wCP*sizeof(int32_t)); // [hna] samples_per_frame without CP
-      LOG_D(PHY,"[INIT] common_vars->txdataF[%d] = %p (%lu bytes)\n",
-	    i,common_vars->txdataF[i],
-	    fp->samples_per_frame_wCP*sizeof(int32_t));
-      common_vars->beam_id[i] = (uint8_t*)malloc16_clear(fp->symbols_per_slot*fp->slots_per_frame*sizeof(uint8_t));
-      memset(common_vars->beam_id[i],255,fp->symbols_per_slot*fp->slots_per_frame);
+    common_vars->txdataF[i] = (int32_t*)malloc16_clear(fp->samples_per_frame_wCP*sizeof(int32_t)); // [hna] samples_per_frame without CP
+    LOG_D(PHY,"[INIT] common_vars->txdataF[%d] = %p (%lu bytes)\n",
+          i,common_vars->txdataF[i],
+          fp->samples_per_frame_wCP*sizeof(int32_t));
+    common_vars->beam_id[i] = (uint8_t*)malloc16_clear(fp->symbols_per_slot*fp->slots_per_frame*sizeof(uint8_t));
+    memset(common_vars->beam_id[i],255,fp->symbols_per_slot*fp->slots_per_frame);
   }
   for (i=0;i<Prx;i++){
     common_vars->rxdataF[i] = (int32_t*)malloc16_clear(fp->samples_per_frame_wCP*sizeof(int32_t));
@@ -740,10 +745,9 @@ void phy_free_nr_gNB(PHY_VARS_gNB *gNB)
   free_and_zero(pdcch_dmrs);
 
   uint32_t ****pdsch_dmrs = gNB->nr_gold_pdsch_dmrs;
-  int nb_codewords = NR_MAX_NB_LAYERS > 4 ? 2 : 1;
   for (int slot = 0; slot < fp->slots_per_frame; slot++) {
     for (int symb = 0; symb < fp->symbols_per_slot; symb++) {
-      for (int q = 0; q < nb_codewords; q++)
+      for (int q = 0; q < NR_NB_NSCID; q++)
         free_and_zero(pdsch_dmrs[slot][symb][q]);
       free_and_zero(pdsch_dmrs[slot][symb]);
     }
@@ -771,7 +775,7 @@ void phy_free_nr_gNB(PHY_VARS_gNB *gNB)
   free_and_zero(csi_rs);
 
   for (int id = 0; id < NUMBER_OF_NR_SRS_MAX; id++) {
-    for (int i = 0; i < Prx; i++){
+    for (int i = 0; i < Prx; i++) {
       free_and_zero(gNB->nr_srs_info[id]->srs_received_signal[i]);
       free_and_zero(gNB->nr_srs_info[id]->srs_ls_estimated_channel[i]);
       free_and_zero(gNB->nr_srs_info[id]->srs_estimated_channel_freq[i]);
diff --git a/openair1/PHY/INIT/nr_init_ue.c b/openair1/PHY/INIT/nr_init_ue.c
index 142ef9b1d970aacb9e2772c5255c6fdce83a55d0..9927085a921d8919d11049cd37a3874a375ad8de 100644
--- a/openair1/PHY/INIT/nr_init_ue.c
+++ b/openair1/PHY/INIT/nr_init_ue.c
@@ -159,7 +159,7 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB)
   NR_UE_COMMON *const common_vars        = &ue->common_vars;
   NR_UE_PBCH  **const pbch_vars          = ue->pbch_vars;
   NR_UE_PRACH **const prach_vars         = ue->prach_vars;
-  int i,j,slot,symb, gNB_id, th_id;
+  int i,slot,symb, gNB_id, th_id;
 
   NR_UE_SRS **const srs_vars             = ue->srs_vars;
 
@@ -210,18 +210,21 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB)
 
   // ceil(((NB_RB*6(k)*2(QPSK)/32) // 3 RE *2(QPSK)
   int pusch_dmrs_init_length =  ((fp->N_RB_UL*12)>>5)+1;
-
-  ue->nr_gold_pusch_dmrs = (uint32_t ***)malloc16(fp->slots_per_frame*sizeof(uint32_t **));
-  uint32_t ***pusch_dmrs = ue->nr_gold_pusch_dmrs;
+  ue->nr_gold_pusch_dmrs = (uint32_t ****)malloc16(fp->slots_per_frame*sizeof(uint32_t ***));
+  uint32_t ****pusch_dmrs = ue->nr_gold_pusch_dmrs;
 
   for (slot=0; slot<fp->slots_per_frame; slot++) {
-    pusch_dmrs[slot] = (uint32_t **)malloc16(fp->symbols_per_slot*sizeof(uint32_t *));
+    pusch_dmrs[slot] = (uint32_t ***)malloc16(fp->symbols_per_slot*sizeof(uint32_t **));
     AssertFatal(pusch_dmrs[slot]!=NULL, "init_nr_ue_signal: pusch_dmrs for slot %d - malloc failed\n", slot);
 
     for (symb=0; symb<fp->symbols_per_slot; symb++) {
-      pusch_dmrs[slot][symb] = (uint32_t *)malloc16(pusch_dmrs_init_length*sizeof(uint32_t));
+      pusch_dmrs[slot][symb] = (uint32_t **)malloc16(NR_NB_NSCID*sizeof(uint32_t *));
       AssertFatal(pusch_dmrs[slot][symb]!=NULL, "init_nr_ue_signal: pusch_dmrs for slot %d symbol %d - malloc failed\n", slot, symb);
 
+      for (int q=0; q<NR_NB_NSCID; q++) {
+        pusch_dmrs[slot][symb][q] = (uint32_t *)malloc16(pusch_dmrs_init_length*sizeof(uint32_t));
+        AssertFatal(pusch_dmrs[slot][symb][q]!=NULL, "init_nr_ue_signal: pusch_dmrs for slot %d symbol %d nscid %d - malloc failed\n", slot, symb, q);
+      }
     }
   }
 
@@ -298,24 +301,38 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB)
     pdsch_dmrs[slot] = (uint32_t ***)malloc16(fp->symbols_per_slot*sizeof(uint32_t **));
     AssertFatal(pdsch_dmrs[slot]!=NULL, "NR init: pdsch_dmrs for slot %d - malloc failed\n", slot);
 
-    int nb_codewords = NR_MAX_NB_LAYERS > 4 ? 2 : 1;
     for (int symb=0; symb<fp->symbols_per_slot; symb++) {
-      pdsch_dmrs[slot][symb] = (uint32_t **)malloc16(nb_codewords*sizeof(uint32_t *));
+      pdsch_dmrs[slot][symb] = (uint32_t **)malloc16(NR_NB_NSCID*sizeof(uint32_t *));
       AssertFatal(pdsch_dmrs[slot][symb]!=NULL, "NR init: pdsch_dmrs for slot %d symbol %d - malloc failed\n", slot, symb);
 
-      for (int q=0; q<nb_codewords; q++) {
+      for (int q=0; q<NR_NB_NSCID; q++) {
         pdsch_dmrs[slot][symb][q] = (uint32_t *)malloc16(pdsch_dmrs_init_length*sizeof(uint32_t));
-        AssertFatal(pdsch_dmrs[slot][symb][q]!=NULL, "NR init: pdsch_dmrs for slot %d symbol %d codeword %d - malloc failed\n", slot, symb, q);
+        AssertFatal(pdsch_dmrs[slot][symb][q]!=NULL, "NR init: pdsch_dmrs for slot %d symbol %d nscid %d - malloc failed\n", slot, symb, q);
       }
     }
   }
 
   // DLSCH
-  for (gNB_id = 0; gNB_id < ue->n_connected_gNB; gNB_id++) {
+  for (gNB_id = 0; gNB_id < ue->n_connected_gNB+1; gNB_id++) {
     for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) {
       ue->pdsch_vars[th_id][gNB_id] = (NR_UE_PDSCH *)malloc16_clear(sizeof(NR_UE_PDSCH));
     }
+    for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) {
+      phy_init_nr_ue_PDSCH( ue->pdsch_vars[th_id][gNB_id], fp );
+    }
 
+    int nb_codewords = NR_MAX_NB_LAYERS > 4 ? 2 : 1;
+    for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) {
+      for (i=0; i<nb_codewords; i++) {
+        ue->pdsch_vars[th_id][gNB_id]->llr[i] = (int16_t *)malloc16_clear( (8*(3*8*8448))*sizeof(int16_t) );//Q_m = 8 bits/Sym, Code_Rate=3, Number of Segments =8, Circular Buffer K_cb = 8448
+      }
+      for (i=0; i<NR_MAX_NB_LAYERS; i++) {
+        ue->pdsch_vars[th_id][gNB_id]->layer_llr[i] = (int16_t *)malloc16_clear( (8*(3*8*8448))*sizeof(int16_t) );//Q_m = 8 bits/Sym, Code_Rate=3, Number of Segments =8, Circular Buffer K_cb = 8448
+      }
+    }
+  }
+
+  for (gNB_id = 0; gNB_id < ue->n_connected_gNB; gNB_id++) {
     for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) {
       ue->pdcch_vars[th_id][gNB_id] = (NR_UE_PDCCH *)malloc16_clear(sizeof(NR_UE_PDCCH));
     }
@@ -343,50 +360,6 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB)
     }
 
 
-    for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) {
-      phy_init_nr_ue_PDSCH( ue->pdsch_vars[th_id][gNB_id], fp );
-    }
-
-    int nb_codewords = NR_MAX_NB_LAYERS > 4 ? 2 : 1;
-    for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) {
-      for (i=0; i<nb_codewords; i++) {
-        ue->pdsch_vars[th_id][gNB_id]->llr[i] = (int16_t *)malloc16_clear( (8*(3*8*8448))*sizeof(int16_t) );//Q_m = 8 bits/Sym, Code_Rate=3, Number of Segments =8, Circular Buffer K_cb = 8448
-      }
-      for (i=0; i<NR_MAX_NB_LAYERS; i++) {
-        ue->pdsch_vars[th_id][gNB_id]->layer_llr[i] = (int16_t *)malloc16_clear( (8*(3*8*8448))*sizeof(int16_t) );//Q_m = 8 bits/Sym, Code_Rate=3, Number of Segments =8, Circular Buffer K_cb = 8448
-      }
-    }
-
-    // 100 PRBs * 12 REs/PRB * 4 PDCCH SYMBOLS * 2 LLRs/RE
-    for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) {
-      ue->pdcch_vars[th_id][gNB_id]->llr                 = (int16_t *)malloc16_clear( 2*4*100*12*sizeof(uint16_t) );
-      ue->pdcch_vars[th_id][gNB_id]->llr16               = (int16_t *)malloc16_clear( 2*4*100*12*sizeof(uint16_t) );
-      ue->pdcch_vars[th_id][gNB_id]->wbar                = (int16_t *)malloc16_clear( 2*4*100*12*sizeof(uint16_t) );
-      ue->pdcch_vars[th_id][gNB_id]->e_rx                = (int16_t *)malloc16_clear( 4*2*100*12 );
-      ue->pdcch_vars[th_id][gNB_id]->rxdataF_comp        = (int32_t **)malloc16_clear( 4*fp->nb_antennas_rx*sizeof(int32_t *) );
-      ue->pdcch_vars[th_id][gNB_id]->rho                 = (int32_t **)malloc16( fp->nb_antennas_rx*sizeof(int32_t *) );
-      ue->pdcch_vars[th_id][gNB_id]->rxdataF_ext         = (int32_t **)malloc16_clear( 4*fp->nb_antennas_rx*sizeof(int32_t *) );
-      ue->pdcch_vars[th_id][gNB_id]->dl_ch_estimates_ext = (int32_t **)malloc16_clear( 4*fp->nb_antennas_rx*sizeof(int32_t *) );
-      // Channel estimates
-      ue->pdcch_vars[th_id][gNB_id]->dl_ch_estimates      = (int32_t **)malloc16_clear(4*fp->nb_antennas_rx*sizeof(int32_t *));
-      ue->pdcch_vars[th_id][gNB_id]->dl_ch_estimates_time = (int32_t **)malloc16_clear(4*fp->nb_antennas_rx*sizeof(int32_t *));
-
-      for (i=0; i<fp->nb_antennas_rx; i++) {
-        ue->pdcch_vars[th_id][gNB_id]->rho[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*(100*12*4));
-
-        for (j=0; j<4; j++) {
-          int idx = (j*fp->nb_antennas_rx)+i;
-          ue->pdcch_vars[th_id][gNB_id]->dl_ch_estimates[idx] = (int32_t *)malloc16_clear( sizeof(int32_t)*fp->symbols_per_slot*(fp->ofdm_symbol_size+LTE_CE_FILTER_LENGTH) );
-          ue->pdcch_vars[th_id][gNB_id]->dl_ch_estimates_time[idx] = (int32_t *)malloc16_clear( sizeof(int32_t)*fp->ofdm_symbol_size*2 );
-          //  size_t num = 7*2*fp->N_RB_DL*12;
-          size_t num = 4*273*12;  // 4 symbols, 100 PRBs, 12 REs per PRB
-          ue->pdcch_vars[th_id][gNB_id]->rxdataF_comp[idx]        = (int32_t *)malloc16_clear(sizeof(int32_t) * num);
-          ue->pdcch_vars[th_id][gNB_id]->rxdataF_ext[idx]         = (int32_t *)malloc16_clear(sizeof(int32_t) * num);
-          ue->pdcch_vars[th_id][gNB_id]->dl_ch_estimates_ext[idx] = (int32_t *)malloc16_clear(sizeof(int32_t) * num);
-        }
-      }
-    }
-
     // RACH
     prach_vars[gNB_id]->prachF             = (int16_t *)malloc16_clear( sizeof(int)*(7*2*sizeof(int)*(fp->ofdm_symbol_size*12)) );
     prach_vars[gNB_id]->prach              = (int16_t *)malloc16_clear( sizeof(int)*(7*2*sizeof(int)*(fp->ofdm_symbol_size*12)) );
@@ -424,6 +397,8 @@ void term_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB)
 
   for (int slot = 0; slot < fp->slots_per_frame; slot++) {
     for (int symb = 0; symb < fp->symbols_per_slot; symb++) {
+      for (int q=0; q<NR_NB_NSCID; q++)
+        free_and_zero(ue->nr_gold_pusch_dmrs[slot][symb][q]);
       free_and_zero(ue->nr_gold_pusch_dmrs[slot][symb]);
     }
     free_and_zero(ue->nr_gold_pusch_dmrs[slot]);
@@ -457,10 +432,9 @@ void term_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB)
   }
   free_and_zero(ue->nr_gold_pdcch[0]);
 
-  int nb_codewords = NR_MAX_NB_LAYERS > 4 ? 2 : 1;
   for (int slot=0; slot<fp->slots_per_frame; slot++) {
     for (int symb=0; symb<fp->symbols_per_slot; symb++) {
-      for (int q=0; q<nb_codewords; q++) 
+      for (int q=0; q<NR_NB_NSCID; q++)
         free_and_zero(ue->nr_gold_pdsch[0][slot][symb][q]);
       free_and_zero(ue->nr_gold_pdsch[0][slot][symb]);
     }
@@ -468,39 +442,20 @@ void term_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB)
   }
   free_and_zero(ue->nr_gold_pdsch[0]);
 
-  for (int gNB_id = 0; gNB_id < ue->n_connected_gNB; gNB_id++) {
+  for (int gNB_id = 0; gNB_id < ue->n_connected_gNB+1; gNB_id++) {
 
     // PDSCH
     for (int th_id = 0; th_id < RX_NB_TH_MAX; th_id++) {
-
       free_and_zero(ue->pdsch_vars[th_id][gNB_id]->llr_shifts);
       free_and_zero(ue->pdsch_vars[th_id][gNB_id]->llr128_2ndstream);
       phy_term_nr_ue__PDSCH(ue->pdsch_vars[th_id][gNB_id], fp);
       free_and_zero(ue->pdsch_vars[th_id][gNB_id]);
     }
+  }
+  
+  for (int gNB_id = 0; gNB_id < ue->n_connected_gNB; gNB_id++) {
 
     for (int th_id = 0; th_id < RX_NB_TH_MAX; th_id++) {
-      for (int i = 0; i < fp->nb_antennas_rx; i++) {
-        for (int j = 0; j < 4; j++) {
-          int idx = j * fp->nb_antennas_rx + i;
-          free_and_zero(ue->pdcch_vars[th_id][gNB_id]->dl_ch_estimates[idx]);
-          free_and_zero(ue->pdcch_vars[th_id][gNB_id]->dl_ch_estimates_time[idx]);
-          free_and_zero(ue->pdcch_vars[th_id][gNB_id]->rxdataF_comp[idx]);
-          free_and_zero(ue->pdcch_vars[th_id][gNB_id]->rxdataF_ext[idx]);
-          free_and_zero(ue->pdcch_vars[th_id][gNB_id]->dl_ch_estimates_ext[idx]);
-        }
-        free_and_zero(ue->pdcch_vars[th_id][gNB_id]->rho[i]);
-      }
-      free_and_zero(ue->pdcch_vars[th_id][gNB_id]->llr);
-      free_and_zero(ue->pdcch_vars[th_id][gNB_id]->llr16);
-      free_and_zero(ue->pdcch_vars[th_id][gNB_id]->wbar);
-      free_and_zero(ue->pdcch_vars[th_id][gNB_id]->e_rx);
-      free_and_zero(ue->pdcch_vars[th_id][gNB_id]->rxdataF_comp);
-      free_and_zero(ue->pdcch_vars[th_id][gNB_id]->rho);
-      free_and_zero(ue->pdcch_vars[th_id][gNB_id]->rxdataF_ext);
-      free_and_zero(ue->pdcch_vars[th_id][gNB_id]->dl_ch_estimates_ext);
-      free_and_zero(ue->pdcch_vars[th_id][gNB_id]->dl_ch_estimates);
-      free_and_zero(ue->pdcch_vars[th_id][gNB_id]->dl_ch_estimates_time);
 
       free_and_zero(ue->pdcch_vars[th_id][gNB_id]);
     }
diff --git a/openair1/PHY/LTE_ESTIMATION/lte_est_freq_offset.c b/openair1/PHY/LTE_ESTIMATION/lte_est_freq_offset.c
index ed82aeb09e36c602ee2b8d71d2db425176b19b60..80d9fc9cc3144576420b87459bb53185a5bd1498 100644
--- a/openair1/PHY/LTE_ESTIMATION/lte_est_freq_offset.c
+++ b/openair1/PHY/LTE_ESTIMATION/lte_est_freq_offset.c
@@ -102,7 +102,7 @@ int lte_est_freq_offset(int **dl_ch_estimates,
 {
 
   int ch_offset, omega, dl_ch_shift;
-  struct complex16 omega_cpx;
+  c16_t omega_cpx;
   double phase_offset;
   int freq_offset_est;
   unsigned char aa;
@@ -142,8 +142,8 @@ int lte_est_freq_offset(int **dl_ch_estimates,
     //    printf("Computing freq_offset\n");
     omega = dot_product(dl_ch,dl_ch_prev,(frame_parms->N_RB_DL/2 - 1)*12,dl_ch_shift);
     //omega = dot_product(dl_ch,dl_ch_prev,frame_parms->ofdm_symbol_size,15);
-    omega_cpx.r = ((struct complex16*) &omega)->r;
-    omega_cpx.i = ((struct complex16*) &omega)->i;
+    omega_cpx.r = ((c16_t*) &omega)->r;
+    omega_cpx.i = ((c16_t*) &omega)->i;
 
     dl_ch = (int16_t *)&dl_ch_estimates[aa][(((frame_parms->N_RB_DL/2) + 1)*12) + ch_offset];
 
@@ -155,8 +155,8 @@ int lte_est_freq_offset(int **dl_ch_estimates,
     // calculate omega = angle(conj(dl_ch)*dl_ch_prev))
     omega = dot_product(dl_ch,dl_ch_prev,((frame_parms->N_RB_DL/2) - 1)*12,dl_ch_shift);
 
-    omega_cpx.r += ((struct complex16*) &omega)->r;
-    omega_cpx.i += ((struct complex16*) &omega)->i;
+    omega_cpx.r += ((c16_t*) &omega)->r;
+    omega_cpx.i += ((c16_t*) &omega)->i;
 
     //    phase_offset += atan2((double)omega_cpx->i,(double)omega_cpx->r);
     phase_offset += atan2((double)omega_cpx.i,(double)omega_cpx.r);
@@ -195,7 +195,7 @@ int lte_mbsfn_est_freq_offset(int **dl_ch_estimates,
 {
 
   int ch_offset, omega, dl_ch_shift;
-  struct complex16 *omega_cpx;
+  c16_t *omega_cpx;
   double phase_offset;
   int freq_offset_est;
   unsigned char aa;
@@ -234,7 +234,7 @@ int lte_mbsfn_est_freq_offset(int **dl_ch_estimates,
     //    printf("Computing freq_offset\n");
     omega = dot_product(dl_ch,dl_ch_prev,(frame_parms->N_RB_DL/2 - 1)*12,dl_ch_shift);
     //omega = dot_product(dl_ch,dl_ch_prev,frame_parms->ofdm_symbol_size,15);
-    omega_cpx = (struct complex16*) &omega;
+    omega_cpx = (c16_t*) &omega;
 
     //    printf("omega (%d,%d)\n",omega_cpx->r,omega_cpx->i);
 
@@ -247,8 +247,8 @@ int lte_mbsfn_est_freq_offset(int **dl_ch_estimates,
 
     // calculate omega = angle(conj(dl_ch)*dl_ch_prev))
     omega = dot_product(dl_ch,dl_ch_prev,((frame_parms->N_RB_DL/2) - 1)*12,dl_ch_shift);
-    omega_cpx->r += ((struct complex16*) &omega)->r;
-    omega_cpx->i += ((struct complex16*) &omega)->i;
+    omega_cpx->r += ((c16_t*) &omega)->r;
+    omega_cpx->i += ((c16_t*) &omega)->i;
     //    phase_offset += atan2((double)omega_cpx->i,(double)omega_cpx->r);
     phase_offset += atan2((double)omega_cpx->i,(double)omega_cpx->r);
     //    printf("omega (%d,%d) -> %f\n",omega_cpx->r,omega_cpx->i,phase_offset);
diff --git a/openair1/PHY/LTE_ESTIMATION/lte_sync_time.c b/openair1/PHY/LTE_ESTIMATION/lte_sync_time.c
index 1fbc8b7ef2bcd643a718245a9d3873edc3efeb0b..b21f526fcc05851a0253edf585983aafb395e52f 100644
--- a/openair1/PHY/LTE_ESTIMATION/lte_sync_time.c
+++ b/openair1/PHY/LTE_ESTIMATION/lte_sync_time.c
@@ -34,9 +34,9 @@
 // Note: this is for prototype of generate_drs_pusch (OTA synchronization of RRUs)
 #include "PHY/LTE_UE_TRANSPORT/transport_proto_ue.h"
 
-static struct complex16 *primary_synch0_time __attribute__((aligned(32)));
-static struct complex16 *primary_synch1_time __attribute__((aligned(32)));
-static struct complex16 *primary_synch2_time __attribute__((aligned(32)));
+static c16_t *primary_synch0_time __attribute__((aligned(32)));
+static c16_t *primary_synch1_time __attribute__((aligned(32)));
+static c16_t *primary_synch2_time __attribute__((aligned(32)));
 
 static void doIdft(int size, short *in, short *out) {
   switch (size) {
@@ -67,7 +67,7 @@ static void doIdft(int size, short *in, short *out) {
     }
   }
 
-static void copyPrimary( struct complex16 *out, struct complex16 *in, int ofdmSize) {
+static void copyPrimary( c16_t *out, struct complex16 *in, int ofdmSize) {
   int k=ofdmSize-36;
     
   for (int i=0; i<72; i++) {
@@ -83,20 +83,20 @@ static void copyPrimary( struct complex16 *out, struct complex16 *in, int ofdmSi
   }
 
 int lte_sync_time_init(LTE_DL_FRAME_PARMS *frame_parms ) { // LTE_UE_COMMON *common_vars
-  struct complex16 syncF_tmp[2048]__attribute__((aligned(32)))= {{0}};
+  c16_t syncF_tmp[2048]__attribute__((aligned(32)))= {{0}};
   int sz=frame_parms->ofdm_symbol_size*sizeof(*primary_synch0_time);
-  AssertFatal( NULL != (primary_synch0_time = (struct complex16 *)malloc16(sz)),"");
+  AssertFatal( NULL != (primary_synch0_time = (c16_t *)malloc16(sz)),"");
   bzero(primary_synch0_time,sz);
-  AssertFatal( NULL != (primary_synch1_time = (struct complex16 *)malloc16(sz)),"");
+  AssertFatal( NULL != (primary_synch1_time = (c16_t *)malloc16(sz)),"");
   bzero(primary_synch1_time,sz);
-  AssertFatal( NULL != (primary_synch2_time = (struct complex16 *)malloc16(sz)),"");
+  AssertFatal( NULL != (primary_synch2_time = (c16_t *)malloc16(sz)),"");
   bzero(primary_synch2_time,sz);
   // generate oversampled sync_time sequences
-  copyPrimary( syncF_tmp, (struct complex16 *) primary_synch0, frame_parms->ofdm_symbol_size);
+  copyPrimary( syncF_tmp, (c16_t *) primary_synch0, frame_parms->ofdm_symbol_size);
   doIdft(frame_parms->N_RB_DL, (short *)syncF_tmp,(short *)primary_synch0_time);
-  copyPrimary( syncF_tmp, (struct complex16 *) primary_synch1, frame_parms->ofdm_symbol_size);
+  copyPrimary( syncF_tmp, (c16_t *) primary_synch1, frame_parms->ofdm_symbol_size);
   doIdft(frame_parms->N_RB_DL, (short *)syncF_tmp,(short *)primary_synch1_time);
-  copyPrimary( syncF_tmp, (struct complex16 *) primary_synch2, frame_parms->ofdm_symbol_size);
+  copyPrimary( syncF_tmp, (c16_t *) primary_synch2, frame_parms->ofdm_symbol_size);
   doIdft(frame_parms->N_RB_DL, (short *)syncF_tmp,(short *)primary_synch2_time);
 
   if ( LOG_DUMPFLAG(DEBUG_LTEESTIM)){
diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c
index c6b312cc61a1ffd34e38e6573b9aeae8f16a6825..de21b7f4e2e08a52cbe36a32e062dc63d390286c 100644
--- a/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c
+++ b/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c
@@ -2237,7 +2237,7 @@ int dlsch_modulation(PHY_VARS_eNB* phy_vars_eNB,
   int P1_SHIFT[13],P2_SHIFT[13];
   int offset,nushiftmod3;
 
-  uint8_t get_pmi_temp;
+  int get_pmi_temp;
 
   MIMO_mode_t mimo_mode = -1;
   uint8_t mprime=0,Ns;
diff --git a/openair1/PHY/LTE_TRANSPORT/prach.c b/openair1/PHY/LTE_TRANSPORT/prach.c
index eb46a8d663df1d670857d0ad247945467024dcc8..91c419ebe39495931098001711d00ef45af97b28 100644
--- a/openair1/PHY/LTE_TRANSPORT/prach.c
+++ b/openair1/PHY/LTE_TRANSPORT/prach.c
@@ -56,7 +56,7 @@ void rx_prach0(PHY_VARS_eNB *eNB,
                uint8_t ce_level
               ) {
   int i;
-  lte_frame_type_t   frame_type;
+  frame_type_t   frame_type;
   uint16_t           rootSequenceIndex;
   uint8_t            prach_ConfigIndex;
   uint8_t            Ncs_config;
diff --git a/openair1/PHY/LTE_TRANSPORT/prach_common.c b/openair1/PHY/LTE_TRANSPORT/prach_common.c
index e366e8edbc9008c1e5435fcdb4fb18405d6d4729..f3409a90e3a7bcace50d889ab85e082489c48465 100644
--- a/openair1/PHY/LTE_TRANSPORT/prach_common.c
+++ b/openair1/PHY/LTE_TRANSPORT/prach_common.c
@@ -399,7 +399,7 @@ void compute_prach_seq(uint16_t rootSequenceIndex,
                        uint8_t prach_ConfigIndex,
                        uint8_t zeroCorrelationZoneConfig,
                        uint8_t highSpeedFlag,
-                       lte_frame_type_t frame_type,
+                       frame_type_t frame_type,
                        uint32_t X_u[64][839]) {
   // Compute DFT of x_u => X_u[k] = x_u(inv(u)*k)^* X_u[k] = exp(j\pi u*inv(u)*k*(inv(u)*k+1)/N_ZC)
   unsigned int k,inv_u,i,NCS=0,num_preambles;
diff --git a/openair1/PHY/LTE_TRANSPORT/prach_extern.h b/openair1/PHY/LTE_TRANSPORT/prach_extern.h
index 3404646923adc9175b78a018f099f9ff2058a748..340386101120f00ac9a65268a41278db0fa5bc6e 100644
--- a/openair1/PHY/LTE_TRANSPORT/prach_extern.h
+++ b/openair1/PHY/LTE_TRANSPORT/prach_extern.h
@@ -81,7 +81,7 @@ void compute_prach_seq(uint16_t rootSequenceIndex,
 		       uint8_t prach_ConfigIndex,
 		       uint8_t zeroCorrelationZoneConfig,
 		       uint8_t highSpeedFlag,
-		       lte_frame_type_t frame_type,
+		       frame_type_t frame_type,
 		       uint32_t X_u[64][839]);
 
 #endif
diff --git a/openair1/PHY/LTE_TRANSPORT/transport_common_proto.h b/openair1/PHY/LTE_TRANSPORT/transport_common_proto.h
index af8e63c3edc02823e0b9a7ad45f674d579de7dc2..57a7b2ec915eabc2e8458abfb3a8810fbf0d2369 100644
--- a/openair1/PHY/LTE_TRANSPORT/transport_common_proto.h
+++ b/openair1/PHY/LTE_TRANSPORT/transport_common_proto.h
@@ -224,7 +224,7 @@ uint8_t get_num_prach_tdd(module_id_t Mod_id);
   @returns 0-1 accordingly
 */
 /*
-uint8_t get_prach_fmt(uint8_t prach_ConfigIndex,lte_frame_type_t frame_type);
+uint8_t get_prach_fmt(uint8_t prach_ConfigIndex,frame_type_t frame_type);
 */
 
 /*!
@@ -247,7 +247,7 @@ void compute_prach_seq(uint16_t rootSequenceIndex,
                        uint8_t prach_ConfigIndex,
                        uint8_t zeroCorrelationZoneConfig,
                        uint8_t highSpeedFlag,
-                       lte_frame_type_t frame_type,
+                       frame_type_t frame_type,
                        uint32_t X_u[64][839]);
 
 
@@ -299,7 +299,7 @@ uint64_t pmi2hex_2Ar1(uint32_t pmi);
 
 uint64_t pmi2hex_2Ar2(uint32_t pmi);
 
-uint8_t get_pmi(uint8_t N_RB_DL,MIMO_mode_t mode, uint32_t pmi_alloc,uint16_t rb);
+uint8_t get_pmi(int N_RB_DL,MIMO_mode_t mode, uint32_t pmi_alloc,uint16_t rb);
 
 // DL power control functions
 double get_pa_dB(uint8_t pa);
diff --git a/openair1/PHY/LTE_UE_TRANSPORT/dci_tools_ue.c b/openair1/PHY/LTE_UE_TRANSPORT/dci_tools_ue.c
index efde277203d2a93a9c953fd49945105c82090e4f..088e2c0a5e29665d2d64ba86e7a374906af00c52 100644
--- a/openair1/PHY/LTE_UE_TRANSPORT/dci_tools_ue.c
+++ b/openair1/PHY/LTE_UE_TRANSPORT/dci_tools_ue.c
@@ -64,7 +64,7 @@ extern uint16_t beta_cqi[16];
 extern uint16_t beta_ri[16];
 extern uint16_t beta_ack[16];
 
-void extract_dci1A_info(uint8_t N_RB_DL, lte_frame_type_t frame_type, void *dci_pdu, DCI_INFO_EXTRACTED_t *pdci_info_extarcted)
+void extract_dci1A_info(uint8_t N_RB_DL, frame_type_t frame_type, void *dci_pdu, DCI_INFO_EXTRACTED_t *pdci_info_extarcted)
 {
     uint8_t harq_pid=0;
     uint32_t rballoc=0;
@@ -182,7 +182,7 @@ void extract_dci1A_info(uint8_t N_RB_DL, lte_frame_type_t frame_type, void *dci_
     pdci_info_extarcted->dai      = dai;
 }
 
-void extract_dci1C_info(uint8_t N_RB_DL, lte_frame_type_t frame_type, void *dci_pdu, DCI_INFO_EXTRACTED_t *pdci_info_extarcted)
+void extract_dci1C_info(uint8_t N_RB_DL, frame_type_t frame_type, void *dci_pdu, DCI_INFO_EXTRACTED_t *pdci_info_extarcted)
 {
 
     uint32_t rballoc=0;
@@ -222,7 +222,7 @@ void extract_dci1C_info(uint8_t N_RB_DL, lte_frame_type_t frame_type, void *dci_
     pdci_info_extarcted->Ngap     = Ngap;
 }
 
-void extract_dci1_info(uint8_t N_RB_DL, lte_frame_type_t frame_type, void *dci_pdu, DCI_INFO_EXTRACTED_t *pdci_info_extarcted)
+void extract_dci1_info(uint8_t N_RB_DL, frame_type_t frame_type, void *dci_pdu, DCI_INFO_EXTRACTED_t *pdci_info_extarcted)
 {
 
     uint32_t rballoc=0;
@@ -329,7 +329,7 @@ void extract_dci1_info(uint8_t N_RB_DL, lte_frame_type_t frame_type, void *dci_p
 
 }
 
-void extract_dci2_info(uint8_t N_RB_DL, lte_frame_type_t frame_type, uint8_t nb_antenna_ports_eNB, void *dci_pdu, DCI_INFO_EXTRACTED_t *pdci_info_extarcted)
+void extract_dci2_info(uint8_t N_RB_DL, frame_type_t frame_type, uint8_t nb_antenna_ports_eNB, void *dci_pdu, DCI_INFO_EXTRACTED_t *pdci_info_extarcted)
 {
 
     uint32_t rballoc=0;
@@ -615,7 +615,7 @@ void extract_dci2_info(uint8_t N_RB_DL, lte_frame_type_t frame_type, uint8_t nb_
 
 }
 
-void extract_dci2A_info(uint8_t N_RB_DL, lte_frame_type_t frame_type, uint8_t nb_antenna_ports_eNB, void *dci_pdu, DCI_INFO_EXTRACTED_t *pdci_info_extarcted)
+void extract_dci2A_info(uint8_t N_RB_DL, frame_type_t frame_type, uint8_t nb_antenna_ports_eNB, void *dci_pdu, DCI_INFO_EXTRACTED_t *pdci_info_extarcted)
 {
 
     uint32_t rballoc=0;
diff --git a/openair1/PHY/LTE_UE_TRANSPORT/get_pmi.c b/openair1/PHY/LTE_UE_TRANSPORT/get_pmi.c
index 7bbe8e894257d772ae1edc96795df9e84119a0d7..6ab2ad9fddef3926df62b39e3c15d60cce9de9aa 100644
--- a/openair1/PHY/LTE_UE_TRANSPORT/get_pmi.c
+++ b/openair1/PHY/LTE_UE_TRANSPORT/get_pmi.c
@@ -21,7 +21,7 @@
 
 #include "PHY/LTE_UE_TRANSPORT/transport_proto_ue.h"
 
-uint8_t get_pmi(uint8_t N_RB_DL, MIMO_mode_t mode, uint32_t pmi_alloc,uint16_t rb)
+uint8_t get_pmi(int N_RB_DL, MIMO_mode_t mode, uint32_t pmi_alloc,uint16_t rb)
 {
   /*
   MIMO_mode_t mode   = dlsch_harq->mimo_mode;
diff --git a/openair1/PHY/LTE_UE_TRANSPORT/prach_ue.c b/openair1/PHY/LTE_UE_TRANSPORT/prach_ue.c
index 82120dc3c333833eb338083596b2758a422a8b17..4faa8367c3ac87a112a9c7348789f2763f66eb15 100644
--- a/openair1/PHY/LTE_UE_TRANSPORT/prach_ue.c
+++ b/openair1/PHY/LTE_UE_TRANSPORT/prach_ue.c
@@ -46,7 +46,7 @@
 //#define PRACH_DEBUG 1
 
 int32_t generate_prach( PHY_VARS_UE *ue, uint8_t eNB_id, uint8_t subframe, uint16_t Nf ) {
-  lte_frame_type_t frame_type         = ue->frame_parms.frame_type;
+  frame_type_t frame_type         = ue->frame_parms.frame_type;
   //uint8_t tdd_config         = ue->frame_parms.tdd_config;
   uint16_t rootSequenceIndex = ue->frame_parms.prach_config_common.rootSequenceIndex;
   uint8_t prach_ConfigIndex  = ue->frame_parms.prach_config_common.prach_ConfigInfo.prach_ConfigIndex;
diff --git a/openair1/PHY/LTE_UE_TRANSPORT/transport_proto_ue.h b/openair1/PHY/LTE_UE_TRANSPORT/transport_proto_ue.h
index c5d096ceb789573d70aea15784f4aff9e1c8f374..f5b8c6b64a0e287f90078bfbb407171ae6836705 100644
--- a/openair1/PHY/LTE_UE_TRANSPORT/transport_proto_ue.h
+++ b/openair1/PHY/LTE_UE_TRANSPORT/transport_proto_ue.h
@@ -1550,16 +1550,6 @@ uint64_t cqi2hex(uint32_t cqi);
 
 uint16_t computeRIV(uint16_t N_RB_DL,uint16_t RBstart,uint16_t Lcrbs);
 
-
-/** \brief  This routine extracts a single subband PMI from a bitmap coming from UCI or the pmi_extend function
-    @param N_RB_DL number of resource blocks
-    @param mimo_mode
-    @param pmi_alloc subband PMI bitmap
-    @param rb resource block for which to extract PMI
-    @returns subband PMI
-*/
-uint8_t get_pmi(uint8_t N_RB_DL,MIMO_mode_t mode, uint32_t pmi_alloc,uint16_t rb);
-
 int get_nCCE_offset_l1(int *CCE_table,
                        const unsigned char L,
                        const int nCCE,
@@ -1669,7 +1659,7 @@ uint8_t get_num_prach_tdd(module_id_t Mod_id);
   @param frame_type 0-FDD, 1-TDD
   @returns 0-1 accordingly
 */
-uint8_t get_prach_fmt(uint8_t prach_ConfigIndex,lte_frame_type_t frame_type);
+uint8_t get_prach_fmt(uint8_t prach_ConfigIndex,frame_type_t frame_type);
 
 /*!
   \brief Helper for MAC, returns frequency index of PRACH resource in TDD for a particular configuration index
@@ -1691,7 +1681,7 @@ void compute_prach_seq(uint16_t rootSequenceIndex,
                        uint8_t prach_ConfigIndex,
                        uint8_t zeroCorrelationZoneConfig,
                        uint8_t highSpeedFlag,
-                       lte_frame_type_t frame_type,
+                       frame_type_t frame_type,
                        uint32_t X_u[64][839]);
 
 
diff --git a/openair1/PHY/LTE_UE_TRANSPORT/transport_ue.h b/openair1/PHY/LTE_UE_TRANSPORT/transport_ue.h
index 6b84a5f9693981e816767a68a8e09704d83895c3..b4ae44f6eab8b663a98de22b151338385c76bf33 100644
--- a/openair1/PHY/LTE_UE_TRANSPORT/transport_ue.h
+++ b/openair1/PHY/LTE_UE_TRANSPORT/transport_ue.h
@@ -155,8 +155,6 @@ typedef struct {
   uint8_t h[MAX_NUM_CHANNEL_BITS];
   /// Scrambled "b"-sequences (for definition see 36-211 V8.6 2009-03, p.14)
   uint8_t b_tilde[MAX_NUM_CHANNEL_BITS];
-  /// Modulated "d"-sequences (for definition see 36-211 V8.6 2009-03, p.14)
-  int32_t d[MAX_NUM_RE];
   /// Transform-coded "z"-sequences (for definition see 36-211 V8.6 2009-03, p.14-15)
   int32_t z[MAX_NUM_RE];
   /// "q" sequences for CQI/PMI (for definition see 36-212 V8.6 2009-03, p.27)
diff --git a/openair1/PHY/LTE_UE_TRANSPORT/ulsch_modulation.c b/openair1/PHY/LTE_UE_TRANSPORT/ulsch_modulation.c
index 7ec3e7bfb684dac869dc84bc04e4bb924995117b..6a663e89404e5a91a0187a20f52c4bf152863d16 100644
--- a/openair1/PHY/LTE_UE_TRANSPORT/ulsch_modulation.c
+++ b/openair1/PHY/LTE_UE_TRANSPORT/ulsch_modulation.c
@@ -42,7 +42,7 @@
 
 //#define DEBUG_ULSCH_MODULATION
 
-void dft_lte(int32_t *z,int32_t *d, int32_t Msc_PUSCH, uint8_t Nsymb)
+void dft_lte(int32_t *z,struct complex16 *input, int32_t Msc_PUSCH, uint8_t Nsymb)
 {
 
 #if defined(__x86_64__) || defined(__i386__)
@@ -66,7 +66,7 @@ void dft_lte(int32_t *z,int32_t *d, int32_t Msc_PUSCH, uint8_t Nsymb)
 #endif
   //  printf("Doing lte_dft for Msc_PUSCH %d\n",Msc_PUSCH);
 
-  d0 = (uint32_t *)d;
+  d0 = (uint32_t *)input;
   d1 = d0+Msc_PUSCH;
   d2 = d1+Msc_PUSCH;
   d3 = d2+Msc_PUSCH;
@@ -476,7 +476,8 @@ void ulsch_modulation(int32_t **txdataF,
   // Modulation
 
   ulsch_Msymb = G/Q_m;
-
+  /// Modulated "d"-sequences (for definition see 36-211 V8.6 2009-03, p.14)
+  struct complex16 d[MAX_NUM_RE] __attribute__((aligned(32)));
   if(ulsch->cooperation_flag == 2)
     // For Distributed Alamouti Scheme in Collabrative Communication
   {
@@ -488,14 +489,14 @@ void ulsch_modulation(int32_t **txdataF,
 
 
         //UE1, -x1*
-        ((int16_t*)&ulsch->d[i])[0] = (ulsch->b_tilde[j] == 1)  ? (gain_lin_QPSK) : -gain_lin_QPSK;
-        ((int16_t*)&ulsch->d[i])[1] = (ulsch->b_tilde[j+1] == 1)? (-gain_lin_QPSK) : gain_lin_QPSK;
+        d[i].r = (ulsch->b_tilde[j] == 1)  ? (gain_lin_QPSK) : -gain_lin_QPSK;
+        d[i].i = (ulsch->b_tilde[j+1] == 1)? (-gain_lin_QPSK) : gain_lin_QPSK;
         //      if (i<Msc_PUSCH)
         //  printf("input %d (%p): %d,%d\n", i,&ulsch->d[i],((int16_t*)&ulsch->d[i])[0],((int16_t*)&ulsch->d[i])[1]);
 
         // UE1, x0*
-        ((int16_t*)&ulsch->d[i+1])[0] = (ulsch->b_tilde[j-2] == 1)  ? (-gain_lin_QPSK) : gain_lin_QPSK;
-        ((int16_t*)&ulsch->d[i+1])[1] = (ulsch->b_tilde[j-1] == 1)? (gain_lin_QPSK) : -gain_lin_QPSK;
+        d[i+1].r = (ulsch->b_tilde[j-2] == 1)  ? (-gain_lin_QPSK) : gain_lin_QPSK;
+        d[i+1].i = (ulsch->b_tilde[j-1] == 1)? (gain_lin_QPSK) : -gain_lin_QPSK;
 
         break;
 
@@ -521,8 +522,8 @@ void ulsch_modulation(int32_t **txdataF,
           qam16_table_offset_im+=1;
 
 
-        ((int16_t*)&ulsch->d[i])[0]=-(int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_re])>>15);
-        ((int16_t*)&ulsch->d[i])[1]=(int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_im])>>15);
+        d[i].r =-(int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_re])>>15);
+        d[i].i =(int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_im])>>15);
 
         //UE1,x0*
         qam16_table_offset_re = 0;
@@ -544,8 +545,8 @@ void ulsch_modulation(int32_t **txdataF,
 
         //    ((int16_t*)&ulsch->d[i+1])[0]=-(int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_re])>>15);
         //    ((int16_t*)&ulsch->d[i+1])[1]=(int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_im])>>15);
-        ((int16_t*)&ulsch->d[i+1])[0]=(int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_re])>>15);
-        ((int16_t*)&ulsch->d[i+1])[1]=-(int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_im])>>15);
+        d[i+1].r=(int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_re])>>15);
+        d[i+1].i=-(int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_im])>>15);
 
 
         break;
@@ -578,8 +579,8 @@ void ulsch_modulation(int32_t **txdataF,
           qam64_table_offset_im+=1;
 
 
-        ((int16_t*)&ulsch->d[i])[0]=-(int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_re])>>15);
-        ((int16_t*)&ulsch->d[i])[1]=(int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_im])>>15);
+        d[i].r=-(int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_re])>>15);
+        d[i].i=(int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_im])>>15);
 
         //UE1,x0*
         qam64_table_offset_re = 0;
@@ -605,8 +606,8 @@ void ulsch_modulation(int32_t **txdataF,
           qam64_table_offset_im+=1;
 
 
-        ((int16_t*)&ulsch->d[i+1])[0]=(int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_re])>>15);
-        ((int16_t*)&ulsch->d[i+1])[1]=-(int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_im])>>15);
+        d[i+1].r=(int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_re])>>15);
+        d[i+1].i=-(int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_im])>>15);
 
         break;
 
@@ -621,8 +622,8 @@ void ulsch_modulation(int32_t **txdataF,
       case 2:
         // TODO: this has to be updated!!!
 
-        ((int16_t*)&ulsch->d[i])[0] = (ulsch->b_tilde[j] == 1)  ? (-gain_lin_QPSK) : gain_lin_QPSK;
-        ((int16_t*)&ulsch->d[i])[1] = (ulsch->b_tilde[j+1] == 1)? (-gain_lin_QPSK) : gain_lin_QPSK;
+        d[i].r = (ulsch->b_tilde[j] == 1)  ? (-gain_lin_QPSK) : gain_lin_QPSK;
+        d[i].i = (ulsch->b_tilde[j+1] == 1)? (-gain_lin_QPSK) : gain_lin_QPSK;
         //        if (i<Msc_PUSCH)
         //    printf("input %d/%d Msc_PUSCH %d (%p): %d,%d\n", i,Msymb,Msc_PUSCH,&ulsch->d[i],((int16_t*)&ulsch->d[i])[0],((int16_t*)&ulsch->d[i])[1]);
 
@@ -646,8 +647,8 @@ void ulsch_modulation(int32_t **txdataF,
           qam16_table_offset_im+=1;
 
 
-        ((int16_t*)&ulsch->d[i])[0]=(int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_re])>>15);
-        ((int16_t*)&ulsch->d[i])[1]=(int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_im])>>15);
+        d[i].r=(int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_re])>>15);
+        d[i].i=(int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_im])>>15);
         //      printf("input(16qam) %d (%p): %d,%d\n", i,&ulsch->d[i],((int16_t*)&ulsch->d[i])[0],((int16_t*)&ulsch->d[i])[1]);
         break;
 
@@ -676,8 +677,8 @@ void ulsch_modulation(int32_t **txdataF,
           qam64_table_offset_im+=1;
 
 
-        ((int16_t*)&ulsch->d[i])[0]=(int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_re])>>15);
-        ((int16_t*)&ulsch->d[i])[1]=(int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_im])>>15);
+        d[i].r=(int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_re])>>15);
+        d[i].i=(int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_im])>>15);
 
         break;
 
@@ -688,7 +689,7 @@ void ulsch_modulation(int32_t **txdataF,
 
   // Transform Precoding
 
-  dft_lte(ulsch->z,ulsch->d,Msc_PUSCH,ulsch->Nsymb_pusch);
+  dft_lte(ulsch->z,d,Msc_PUSCH,ulsch->Nsymb_pusch);
 
   DevAssert(txdataF);
 
diff --git a/openair1/PHY/MODULATION/slot_fep.c b/openair1/PHY/MODULATION/slot_fep.c
index 8f41735f10cfa5fd4a915a7d8cb825b2305c03ba..b2c7d934c6583c88acaf82f38a8f61d543b76b02 100644
--- a/openair1/PHY/MODULATION/slot_fep.c
+++ b/openair1/PHY/MODULATION/slot_fep.c
@@ -91,7 +91,7 @@ int slot_fep(PHY_VARS_UE *ue,
   }
 
   //  subframe_offset_F = frame_parms->ofdm_symbol_size * frame_parms->symbols_per_tti * (Ns>>1);
-
+ 
   if (l<0 || l>=7-frame_parms->Ncp) {
     printf("slot_fep: l must be between 0 and %d\n",7-frame_parms->Ncp);
     return(-1);
diff --git a/openair1/PHY/NR_ESTIMATION/nr_measurements_gNB.c b/openair1/PHY/NR_ESTIMATION/nr_measurements_gNB.c
index f4761489f578f7828c89ea0405b9eb78cfd680a8..aec5e1b12bffdc77dde439a201d7596a5577ad28 100644
--- a/openair1/PHY/NR_ESTIMATION/nr_measurements_gNB.c
+++ b/openair1/PHY/NR_ESTIMATION/nr_measurements_gNB.c
@@ -107,25 +107,20 @@ void gNB_I0_measurements(PHY_VARS_gNB *gNB,int slot, int first_symb,int num_symb
   NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms;
   NR_gNB_COMMON *common_vars = &gNB->common_vars;
   PHY_MEASUREMENTS_gNB *measurements = &gNB->measurements;
-  int rb, offset, offset0, nb_symb[275], len;
-  int32_t *ul_ch;
-
-  LOG_D(PHY,"slot %d Doing I0 for first_symb %d, num_symb %d\n",slot,first_symb,num_symb);
+  int rb, nb_symb[275]={0};
+   
+  memset(measurements->n0_subband_power, 0, sizeof(measurements->n0_subband_power));
+    
   for (int s=first_symb;s<(first_symb+num_symb);s++) {
     for (rb=0; rb<frame_parms->N_RB_UL; rb++) {
-
-      if (s==first_symb) {
-        nb_symb[rb]=0;
-        for (int aarx=0; aarx<frame_parms->nb_antennas_rx;aarx++) 
-           measurements->n0_subband_power[aarx][rb]=0;   
-      }
-      offset0 = (slot&3)*(frame_parms->symbols_per_slot * frame_parms->ofdm_symbol_size) + (frame_parms->first_carrier_offset + (rb*12))%frame_parms->ofdm_symbol_size;
+      int offset0 = (slot&3)*(frame_parms->symbols_per_slot * frame_parms->ofdm_symbol_size) +
+	(frame_parms->first_carrier_offset + (rb*12))%frame_parms->ofdm_symbol_size;
       if ((gNB->rb_mask_ul[s][rb>>5]&(1<<(rb&31))) == 0) {  // check that rb was not used in this subframe
         nb_symb[rb]++;          
         for (int aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
-          offset = offset0 + (s*frame_parms->ofdm_symbol_size);
-          ul_ch  = &common_vars->rxdataF[aarx][offset];
-          len = 12;
+          int offset = offset0 + (s*frame_parms->ofdm_symbol_size);
+          int32_t *ul_ch  = &common_vars->rxdataF[aarx][offset];
+          int len = 12;
           if (((frame_parms->N_RB_UL&1) == 1) && 
               (rb==(frame_parms->N_RB_UL>>1))) {
             len=6;
diff --git a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c
index 9aaba7fb66789bcda3d29103ff383a4aa944c40d..4a6f8ef9af1b4a5f7d314bbc9ddb7969aaf2216c 100644
--- a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c
+++ b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c
@@ -165,6 +165,11 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
 
   //------------------generate DMRS------------------//
 
+  if(pusch_pdu->ul_dmrs_scrambling_id != gNB->pusch_gold_init[pusch_pdu->scid])  {
+    gNB->pusch_gold_init[pusch_pdu->scid] = pusch_pdu->ul_dmrs_scrambling_id;
+    nr_gold_pusch(gNB, pusch_pdu->scid, pusch_pdu->ul_dmrs_scrambling_id);
+  }
+
   // transform precoding = 1 means disabled
   if (pusch_pdu->transform_precoding == 1) {
     nr_pusch_dmrs_rx(gNB, Ns, gNB->nr_gold_pusch_dmrs[pusch_pdu->scid][Ns][symbol], &pilot[0], 1000, 0, nb_rb_pusch,
@@ -1247,4 +1252,4 @@ int nr_srs_channel_estimation(PHY_VARS_gNB *gNB,
 #endif
 
   return 0;
-}
\ No newline at end of file
+}
diff --git a/openair1/PHY/NR_REFSIG/nr_gold.c b/openair1/PHY/NR_REFSIG/nr_gold.c
index b593dcbb477506d7a547e51eb4c65747e676fa2e..279afc8110c215a33e8fcde415a1964c17e6db79 100644
--- a/openair1/PHY/NR_REFSIG/nr_gold.c
+++ b/openair1/PHY/NR_REFSIG/nr_gold.c
@@ -78,57 +78,47 @@ void nr_init_pdcch_dmrs(PHY_VARS_gNB* gNB, uint32_t Nid)
 }
 
 
-void nr_init_pdsch_dmrs(PHY_VARS_gNB* gNB, uint32_t Nid)
-{
+void nr_init_pdsch_dmrs(PHY_VARS_gNB* gNB, uint8_t nscid, uint32_t Nid) {
   
   uint32_t x1, x2;
   uint8_t reset;
   NR_DL_FRAME_PARMS *fp = &gNB->frame_parms;
   uint32_t ****pdsch_dmrs = gNB->nr_gold_pdsch_dmrs;
   int pdsch_dmrs_init_length =  ((fp->N_RB_DL*12)>>5)+1;
-  int nb_codewords = NR_MAX_NB_LAYERS > 4 ? 2 : 1;
-  uint16_t N_n_scid[2]={Nid, Nid};
-  uint8_t n_scid=0; // again works only for 1_0
+
   for (uint8_t slot=0; slot<fp->slots_per_frame; slot++) {
 
     for (uint8_t symb=0; symb<fp->symbols_per_slot; symb++) {
-        reset = 1;
-        x2 = ((1<<17) * (fp->symbols_per_slot*slot+symb+1) * ((N_n_scid[n_scid]<<1)+1) +((N_n_scid[n_scid]<<1)+n_scid));
-	      LOG_D(PHY,"PDSCH DMRS slot %d, symb %d x2 %x, N_n_scid %d,n_scid %d\n",slot,symb,x2,N_n_scid[n_scid],n_scid);
-        for (uint32_t n=0; n<pdsch_dmrs_init_length; n++) {
-          pdsch_dmrs[slot][symb][0][n] = lte_gold_generic(&x1, &x2, reset);
-          reset = 0;
-        }
-
-        if(nb_codewords>1)
-          memcpy(pdsch_dmrs[slot][symb][1],pdsch_dmrs[slot][symb][0],sizeof(uint32_t)*pdsch_dmrs_init_length);
+      reset = 1;
+      x2 = ((1<<17) * (fp->symbols_per_slot*slot+symb+1) * ((Nid<<1)+1) +((Nid<<1)+nscid));
+      LOG_D(PHY,"PDSCH DMRS slot %d, symb %d x2 %x, Nid %d,nscid %d\n",slot,symb,x2,Nid,nscid);
+      for (uint32_t n=0; n<pdsch_dmrs_init_length; n++) {
+        pdsch_dmrs[slot][symb][nscid][n] = lte_gold_generic(&x1, &x2, reset);
+        reset = 0;
+      }
     }
   }
 }
 
 
-void nr_gold_pusch(PHY_VARS_gNB* gNB, uint32_t *Nid) {
+void nr_gold_pusch(PHY_VARS_gNB* gNB, int nscid, uint32_t nid) {
 
   unsigned char ns;
   unsigned int n,x1,x2;
-  int nscid, reset;
-  unsigned int nid;
+  int reset;
   NR_DL_FRAME_PARMS *fp = &gNB->frame_parms;
   unsigned short l;
   int pusch_dmrs_init_length =  ((fp->N_RB_UL*12)>>5)+1;
 
-  for (nscid=0; nscid<2; nscid++) {
-    nid = Nid[nscid];
-    for (ns=0; ns<fp->slots_per_frame; ns++) {
-      for (l=0; l<fp->symbols_per_slot; l++) {
-        reset = 1;
-        x2 = ((1<<17) * (fp->symbols_per_slot*ns+l+1) * ((nid<<1)+1) +((nid<<1)+nscid));
-        LOG_D(PHY,"DMRS slot %d, symb %d x2 %x\n",ns,l,x2);
-
-        for (n=0; n<pusch_dmrs_init_length; n++) {
-          gNB->nr_gold_pusch_dmrs[nscid][ns][l][n] = lte_gold_generic(&x1, &x2, reset);
-          reset = 0;
-        }
+  for (ns=0; ns<fp->slots_per_frame; ns++) {
+    for (l=0; l<fp->symbols_per_slot; l++) {
+      reset = 1;
+      x2 = ((1<<17) * (fp->symbols_per_slot*ns+l+1) * ((nid<<1)+1) +((nid<<1)+nscid));
+      LOG_D(PHY,"DMRS slot %d, symb %d x2 %x\n",ns,l,x2);
+
+      for (n=0; n<pusch_dmrs_init_length; n++) {
+        gNB->nr_gold_pusch_dmrs[nscid][ns][l][n] = lte_gold_generic(&x1, &x2, reset);
+        reset = 0;
       }
     }
   }
diff --git a/openair1/PHY/NR_REFSIG/nr_gold_ue.c b/openair1/PHY/NR_REFSIG/nr_gold_ue.c
index 932cdba538a2d8c34f7d1a42ce64aaa5a94ecffe..203d6c8625213a24d64e47bcaaff196af9a16158 100644
--- a/openair1/PHY/NR_REFSIG/nr_gold_ue.c
+++ b/openair1/PHY/NR_REFSIG/nr_gold_ue.c
@@ -76,46 +76,38 @@ void nr_gold_pdcch(PHY_VARS_NR_UE* ue,
 }
 
 void nr_gold_pdsch(PHY_VARS_NR_UE* ue,
-                   unsigned short *n_idDMRS)
-{
+                   int nscid,
+                   uint32_t nid) {
 
   unsigned int x1,x2,x2tmp0;
-  unsigned int nid;
   uint8_t reset;
   int pdsch_dmrs_init_length =  ((ue->frame_parms.N_RB_DL*12)>>5)+1;
-  int nb_codewords = NR_MAX_NB_LAYERS > 4 ? 2 : 1;
-  /// to be updated from higher layer
-  //unsigned short lbar = 0;
-
-  for (int nscid=0; nscid<nb_codewords; nscid++) {
-    for (int ns=0; ns<ue->frame_parms.slots_per_frame; ns++) {
 
-      nid = n_idDMRS[nscid];
+  for (int ns=0; ns<ue->frame_parms.slots_per_frame; ns++) {
 
-      for (int l=0; l<ue->frame_parms.symbols_per_slot; l++) {
+    for (int l=0; l<ue->frame_parms.symbols_per_slot; l++) {
 
-        reset = 1;
-        x2tmp0 = ((ue->frame_parms.symbols_per_slot*ns+l+1)*((nid<<1)+1))<<17;
-        x2 = (x2tmp0+(nid<<1)+nscid)%(1U<<31);  //cinit
-        LOG_D(PHY,"UE DMRS slot %d, symb %d, x2 %x, nscid %d\n",ns,l,x2,nscid);
+      reset = 1;
+      x2tmp0 = ((ue->frame_parms.symbols_per_slot*ns+l+1)*((nid<<1)+1))<<17;
+      x2 = (x2tmp0+(nid<<1)+nscid)%(1U<<31);  //cinit
+      LOG_D(PHY,"UE DMRS slot %d, symb %d, x2 %x, nscid %d\n",ns,l,x2,nscid);
 
-        for (int n=0; n<pdsch_dmrs_init_length; n++) {
-          ue->nr_gold_pdsch[0][ns][l][nscid][n] = lte_gold_generic(&x1, &x2, reset);
-          reset = 0;
-        }
+      for (int n=0; n<pdsch_dmrs_init_length; n++) {
+        ue->nr_gold_pdsch[0][ns][l][nscid][n] = lte_gold_generic(&x1, &x2, reset);
+        reset = 0;
       }
     }
   }
 }
 
 void nr_init_pusch_dmrs(PHY_VARS_NR_UE* ue,
-                        uint16_t *N_n_scid,
+                        uint16_t N_n_scid,
                         uint8_t n_scid)
 {
   uint32_t x1, x2, n;
   uint8_t reset, slot, symb;
   NR_DL_FRAME_PARMS *fp = &ue->frame_parms;
-  uint32_t ***pusch_dmrs = ue->nr_gold_pusch_dmrs;
+  uint32_t ****pusch_dmrs = ue->nr_gold_pusch_dmrs;
   int pusch_dmrs_init_length =  ((fp->N_RB_UL*12)>>5)+1;
 
   for (slot=0; slot<fp->slots_per_frame; slot++) {
@@ -123,10 +115,10 @@ void nr_init_pusch_dmrs(PHY_VARS_NR_UE* ue,
     for (symb=0; symb<fp->symbols_per_slot; symb++) {
 
       reset = 1;
-      x2 = ((1<<17) * (fp->symbols_per_slot*slot+symb+1) * ((N_n_scid[n_scid]<<1)+1) +((N_n_scid[n_scid]<<1)+n_scid));
-
+      x2 = ((1<<17) * (fp->symbols_per_slot*slot+symb+1) * ((N_n_scid<<1)+1) +((N_n_scid<<1)+n_scid));
+      LOG_D(PHY,"DMRS slot %d, symb %d x2 %x\n",slot,symb,x2);
       for (n=0; n<pusch_dmrs_init_length; n++) {
-        pusch_dmrs[slot][symb][n] = lte_gold_generic(&x1, &x2, reset);
+        pusch_dmrs[slot][symb][n_scid][n] = lte_gold_generic(&x1, &x2, reset);
         reset = 0;
       }
     }
diff --git a/openair1/PHY/NR_REFSIG/nr_refsig.h b/openair1/PHY/NR_REFSIG/nr_refsig.h
index aedc535c29868a34859e238d61bbc912d3ced356..df3dad1e5903eacc09002fec93eb9b826ca0f212 100644
--- a/openair1/PHY/NR_REFSIG/nr_refsig.h
+++ b/openair1/PHY/NR_REFSIG/nr_refsig.h
@@ -37,10 +37,10 @@ void nr_init_pbch_dmrs(PHY_VARS_gNB* gNB);
 @param Nid is used for the initialization of x2, Physical cell Id by default or upper layer configured pdcch_scrambling_ID
  */
 void nr_init_pdcch_dmrs(PHY_VARS_gNB* gNB, uint32_t Nid);
-void nr_init_pdsch_dmrs(PHY_VARS_gNB* gNB, uint32_t Nid);
+void nr_init_pdsch_dmrs(PHY_VARS_gNB* gNB, uint8_t nscid, uint32_t Nid);
 void nr_init_csi_rs(PHY_VARS_gNB* gNB, uint32_t Nid);
 
-void nr_gold_pusch(PHY_VARS_gNB* gNB, uint32_t *Nid);
+void nr_gold_pusch(PHY_VARS_gNB* gNB, int nscid, uint32_t nid);
 
 int nr_pusch_dmrs_rx(PHY_VARS_gNB *gNB,
                      unsigned int Ns,
diff --git a/openair1/PHY/NR_REFSIG/pss_nr.h b/openair1/PHY/NR_REFSIG/pss_nr.h
index b32d48a2e9f95e126e6dd3d77b2b8c9517a7fd76..c65ca3799d6348c81c39fae8a9a2d627f6fcedfa 100644
--- a/openair1/PHY/NR_REFSIG/pss_nr.h
+++ b/openair1/PHY/NR_REFSIG/pss_nr.h
@@ -113,12 +113,6 @@ EXTERN int16_t *primary_synchro_time_nr[NUMBER_PSS_SEQUENCE]
 #endif
 ;
 
-EXTERN int64_t *pss_corr_ue[NUMBER_PSS_SEQUENCE]
-#ifdef INIT_VARIABLES_PSS_NR_H
-= { NULL, NULL, NULL}
-#endif
-;
-
 /* profiling structure */
 EXTERN time_stats_t generic_time[TIME_LAST];
 
diff --git a/openair1/PHY/NR_REFSIG/ptrs_nr.c b/openair1/PHY/NR_REFSIG/ptrs_nr.c
index 40a6a56611ebbf0db6bbb2f2e2f8a6f4d2859f0b..68134eb02ddb61b2dd7d63b54180cebc05bd64e1 100644
--- a/openair1/PHY/NR_REFSIG/ptrs_nr.c
+++ b/openair1/PHY/NR_REFSIG/ptrs_nr.c
@@ -268,8 +268,8 @@ void nr_ptrs_cpe_estimation(uint8_t K_ptrs,
     return;
   }
   uint16_t              sc_per_symbol    = (nb_rb + K_ptrs - 1)/K_ptrs;
-  struct complex16      ptrs_p[(1 + sc_per_symbol/4)*4];
-  struct complex16      dmrs_comp_p[(1 + sc_per_symbol/4)*4];
+  c16_t      ptrs_p[(1 + sc_per_symbol/4)*4];
+  c16_t      dmrs_comp_p[(1 + sc_per_symbol/4)*4];
   double                abs              = 0.0;
   double                real             = 0.0;
   double                imag             = 0.0;
@@ -422,7 +422,7 @@ void get_slope_from_estimates(uint8_t start, uint8_t end, int16_t *est_p, double
 /* estimate from slope */
 void ptrs_estimate_from_slope(int16_t *error_est, double *slope_p, uint8_t start, uint8_t end)
 {
-  struct complex16 *error=(struct complex16 *) error_est;
+  c16_t *error=(struct complex16 *) error_est;
   for(uint8_t i = 1; i< (end -start);i++) {
     error[start+i].r = error[start].r + (int16_t)(i * slope_p[0]);// real
     error[start+i].i = error[start].i + (int16_t)(i * slope_p[1]); //imag
diff --git a/openair1/PHY/NR_REFSIG/refsig_defs_ue.h b/openair1/PHY/NR_REFSIG/refsig_defs_ue.h
index 1fca2be2a187dd7643d7898ccfba7bd71b09e94c..cd19e5ebcac29ea805d33270419f825251acb224 100644
--- a/openair1/PHY/NR_REFSIG/refsig_defs_ue.h
+++ b/openair1/PHY/NR_REFSIG/refsig_defs_ue.h
@@ -61,10 +61,11 @@ void nr_gold_pdcch(PHY_VARS_NR_UE* ue,
                    unsigned short n_idDMRS);
 
 void nr_gold_pdsch(PHY_VARS_NR_UE* ue,
-                   unsigned short *n_idDMRS);
+                   int nscid,
+                   uint32_t nid);
 
 void nr_init_pusch_dmrs(PHY_VARS_NR_UE* ue,
-                        uint16_t *N_n_scid,
+                        uint16_t N_n_scid,
                         uint8_t n_scid);
 
 #endif
diff --git a/openair1/PHY/NR_TRANSPORT/nr_csi_rs.c b/openair1/PHY/NR_TRANSPORT/nr_csi_rs.c
index b530dcf4823b012e82927da75b81ffff633a599b..694617c4441019c8a00b3bbb21907178b9d197db 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_csi_rs.c
+++ b/openair1/PHY/NR_TRANSPORT/nr_csi_rs.c
@@ -30,7 +30,6 @@
 void nr_generate_csi_rs(PHY_VARS_gNB *gNB,
                         int16_t amp,
                         nfapi_nr_dl_tti_csi_rs_pdu_rel15_t csi_params,
-                        uint16_t cell_id,
                         int slot){
 
   NR_DL_FRAME_PARMS frame_parms=gNB->frame_parms;
@@ -52,20 +51,10 @@ void nr_generate_csi_rs(PHY_VARS_gNB *gNB,
 
   AssertFatal(b!=0, "Invalid CSI frequency domain mapping: no bit selected in bitmap\n");
 
-  // pre-computed for scrambling id equel to cell id
-  // if the scrambling id is not the cell id we need to re-initialize the rs
-  if (csi_params.scramb_id != cell_id) {
-    uint8_t reset;
-    uint32_t x1, x2;
-    uint32_t Nid = csi_params.scramb_id;
-    for (uint8_t symb=0; symb<frame_parms.symbols_per_slot; symb++) {
-      reset = 1;
-      x2 = ((1<<10) * (frame_parms.symbols_per_slot*slot+symb+1) * ((Nid<<1)+1) + (Nid));
-      for (uint32_t n=0; n<(csi_rs_length>>5)+1; n++) {
-        gold_csi_rs[symb][n] = lte_gold_generic(&x1, &x2, reset);
-        reset = 0;
-      }
-    }
+  // if the scrambling id is not the one previously used to initialize we need to re-initialize the rs
+  if (csi_params.scramb_id != gNB->csi_gold_init) {
+    gNB->csi_gold_init = csi_params.scramb_id;
+    nr_init_csi_rs(gNB, csi_params.scramb_id);
   }
 
   switch (csi_params.row) {
diff --git a/openair1/PHY/NR_TRANSPORT/nr_dci.c b/openair1/PHY/NR_TRANSPORT/nr_dci.c
index 0af56ba706a9fc8643120037517fcd6983b91b4c..47961640369f80d19d5f0a74f6d7e8bb8f479c71 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_dci.c
+++ b/openair1/PHY/NR_TRANSPORT/nr_dci.c
@@ -66,11 +66,12 @@ void nr_pdcch_scrambling(uint32_t *in,
   }
 }
 
-void nr_generate_dci(nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15,
-                     uint32_t **gold_pdcch_dmrs,
+void nr_generate_dci(PHY_VARS_gNB *gNB,
+                     nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15,
                      int32_t *txdataF,
                      int16_t amp,
-                     NR_DL_FRAME_PARMS *frame_parms) {
+                     NR_DL_FRAME_PARMS *frame_parms,
+                     int slot) {
 
   int16_t mod_dmrs[NR_MAX_CSET_DURATION][NR_MAX_PDCCH_DMRS_LENGTH>>1] __attribute__((aligned(16))); // 3 for the max coreset duration
   uint16_t cset_start_sc;
@@ -81,7 +82,7 @@ void nr_generate_dci(nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15,
     
   int rb_offset;
   int n_rb;
-  
+
   // compute rb_offset and n_prb based on frequency allocation
   nr_cce_t cce_list[MAX_DCI_CORESET][NR_MAX_PDCCH_AGG_LEVEL];
   nr_fill_cce_list(cce_list,0,pdcch_pdu_rel15);
@@ -95,6 +96,13 @@ void nr_generate_dci(nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15,
      * in time: by its first slot and its first symbol*/
     const nfapi_nr_dl_dci_pdu_t *dci_pdu = &pdcch_pdu_rel15->dci_pdu[d];
 
+    if(dci_pdu->ScramblingId != gNB->pdcch_gold_init) {
+      gNB->pdcch_gold_init = dci_pdu->ScramblingId;
+      nr_init_pdcch_dmrs(gNB, dci_pdu->ScramblingId);
+    }
+
+    uint32_t **gold_pdcch_dmrs = gNB->nr_gold_pdcch_dmrs[slot];
+
     cset_start_symb = pdcch_pdu_rel15->StartSymbolIndex;
     cset_nsymb = pdcch_pdu_rel15->DurationSymbols;
     dci_idx = 0;
@@ -104,8 +112,8 @@ void nr_generate_dci(nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15,
     uint32_t dmrs_length = n_rb*6; //2(QPSK)*3(per RB)*6(REG per CCE)
     uint32_t encoded_length = dci_pdu->AggregationLevel*108; //2(QPSK)*9(per RB)*6(REG per CCE)
     LOG_D(PHY, "DL_DCI : rb_offset %d, nb_rb %d, DMRS length per symbol %d\t DCI encoded length %d (precoder_granularity %d,reg_mapping %d),Scrambling_Id %d,ScramblingRNTI %x,PayloadSizeBits %d\n",
-    rb_offset, n_rb,dmrs_length, encoded_length,pdcch_pdu_rel15->precoderGranularity,pdcch_pdu_rel15->CceRegMappingType,
-    dci_pdu->ScramblingId,dci_pdu->ScramblingRNTI,dci_pdu->PayloadSizeBits);
+          rb_offset, n_rb,dmrs_length, encoded_length,pdcch_pdu_rel15->precoderGranularity,pdcch_pdu_rel15->CceRegMappingType,
+          dci_pdu->ScramblingId,dci_pdu->ScramblingRNTI,dci_pdu->PayloadSizeBits);
     dmrs_length += rb_offset*6; // To accommodate more DMRS symbols in case of rb offset
       
     /// DMRS QPSK modulation
@@ -115,10 +123,10 @@ void nr_generate_dci(nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15,
       
 #ifdef DEBUG_PDCCH_DMRS
        if(dci_pdu->RNTI!=0xFFFF) {      
-      for (int i=0; i<dmrs_length>>1; i++)
-	printf("symb %d i %d %p gold seq 0x%08x mod_dmrs %d %d\n", symb, i,
-	       &gold_pdcch_dmrs[symb][i>>5],gold_pdcch_dmrs[symb][i>>5], mod_dmrs[symb][i<<1], mod_dmrs[symb][(i<<1)+1] );
-    }  
+         for (int i=0; i<dmrs_length>>1; i++)
+	   printf("symb %d i %d %p gold seq 0x%08x mod_dmrs %d %d\n", symb, i,
+	          &gold_pdcch_dmrs[symb][i>>5],gold_pdcch_dmrs[symb][i>>5], mod_dmrs[symb][i<<1], mod_dmrs[symb][(i<<1)+1] );
+       }
 #endif
     }
     
@@ -133,6 +141,7 @@ void nr_generate_dci(nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15,
     polar_encoder_fast((uint64_t*)dci_pdu->Payload, (void*)encoder_output, n_RNTI, 1, 
                        NR_POLAR_DCI_MESSAGE_TYPE, dci_pdu->PayloadSizeBits, dci_pdu->AggregationLevel);
 #ifdef DEBUG_CHANNEL_CODING
+//debug dump dci
     printf("polar rnti %x,length %d, L %d\n",n_RNTI, dci_pdu->PayloadSizeBits,pdcch_pdu_rel15->dci_pdu->AggregationLevel);
     printf("DCI PDU: [0]->0x%lx \t [1]->0x%lx\n",
 	   ((uint64_t*)dci_pdu->Payload)[0], ((uint64_t*)dci_pdu->Payload)[1]);
@@ -248,15 +257,16 @@ void nr_generate_dci(nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15,
 }
 
 void nr_generate_dci_top(processingData_L1tx_t *msgTx,
-                         uint32_t **gold_pdcch_dmrs,
+                         int slot,
                          int32_t *txdataF,
                          int16_t amp,
                          NR_DL_FRAME_PARMS *frame_parms) {
 
+
   for (int i=0; i<msgTx->num_ul_pdcch; i++)
-    nr_generate_dci(&msgTx->ul_pdcch_pdu[i].pdcch_pdu.pdcch_pdu_rel15,gold_pdcch_dmrs,txdataF,amp,frame_parms);
+    nr_generate_dci(msgTx->gNB,&msgTx->ul_pdcch_pdu[i].pdcch_pdu.pdcch_pdu_rel15,txdataF,amp,frame_parms,slot);
   for (int i=0; i<msgTx->num_dl_pdcch; i++)
-    nr_generate_dci(&msgTx->pdcch_pdu[i].pdcch_pdu_rel15,gold_pdcch_dmrs,txdataF,amp,frame_parms);
+    nr_generate_dci(msgTx->gNB,&msgTx->pdcch_pdu[i].pdcch_pdu_rel15,txdataF,amp,frame_parms,slot);
 
 }
 
diff --git a/openair1/PHY/NR_TRANSPORT/nr_dci.h b/openair1/PHY/NR_TRANSPORT/nr_dci.h
index bdc8509d12a2768b033370bede1b0da97b589c90..490a8b528682fa3d64b7a8d0de5f7a8f223372cb 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_dci.h
+++ b/openair1/PHY/NR_TRANSPORT/nr_dci.h
@@ -30,7 +30,7 @@ uint16_t nr_get_dci_size(nfapi_nr_dci_format_e format,
                          uint16_t N_RB);
 
 void nr_generate_dci_top(processingData_L1tx_t *msgTx,
-                         uint32_t **gold_pdcch_dmrs,
+                         int slot,
                          int32_t *txdataF,
                          int16_t amp,
                          NR_DL_FRAME_PARMS *frame_parms);
diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch.c b/openair1/PHY/NR_TRANSPORT/nr_dlsch.c
index 47d6c48373b4e93203e2e957434164909baab16b..2c4fb26c5adab7508063f45ab6f18da919d82254 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_dlsch.c
+++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch.c
@@ -58,7 +58,6 @@ void nr_generate_pdsch(processingData_L1tx_t *msgTx,
 
   PHY_VARS_gNB *gNB = msgTx->gNB;
   NR_gNB_DLSCH_t *dlsch;
-  uint32_t ***pdsch_dmrs = gNB->nr_gold_pdsch_dmrs[slot];
   int32_t** txdataF = gNB->common_vars.txdataF;
   int16_t amp = AMP;
   int xOverhead = 0;
@@ -93,12 +92,17 @@ void nr_generate_pdsch(processingData_L1tx_t *msgTx,
     }
     n_dmrs = (rel15->BWPStart+rel15->rbStart+rel15->rbSize)*nb_re_dmrs;
 
+    if(rel15->dlDmrsScramblingId != gNB->pdsch_gold_init[rel15->SCID])  {
+      gNB->pdsch_gold_init[rel15->SCID] = rel15->dlDmrsScramblingId;
+      nr_init_pdsch_dmrs(gNB, rel15->SCID, rel15->dlDmrsScramblingId);
+    }
+
+    uint32_t ***pdsch_dmrs = gNB->nr_gold_pdsch_dmrs[slot];
     uint16_t dmrs_symbol_map = rel15->dlDmrsSymbPos;//single DMRS: 010000100 Double DMRS 110001100
     uint8_t dmrs_len = get_num_dmrs(rel15->dlDmrsSymbPos);
     uint16_t nb_re = ((12*rel15->NrOfSymbols)-nb_re_dmrs*dmrs_len-xOverhead)*rel15->rbSize*rel15->nrOfLayers;
     uint8_t Qm = rel15->qamModOrder[0];
     uint32_t encoded_length = nb_re*Qm;
-    uint32_t scrambled_output[rel15->NrOfCodewords][(encoded_length>>5)+1];
     int16_t mod_dmrs[n_dmrs<<1] __attribute__ ((aligned(16)));
 
     /* PTRS */
@@ -125,7 +129,7 @@ void nr_generate_pdsch(processingData_L1tx_t *msgTx,
     start_meas(dlsch_encoding_stats);
 
     if (nr_dlsch_encoding(gNB,
-                          harq->pdu, frame, slot, dlsch, frame_parms,output,tinput,tprep,tparity,toutput,
+                          frame, slot, harq, frame_parms,output,tinput,tprep,tparity,toutput,
                           dlsch_rate_matching_stats,
                           dlsch_interleaving_stats,
                           dlsch_segmentation_stats) == -1)
@@ -147,63 +151,63 @@ void nr_generate_pdsch(processingData_L1tx_t *msgTx,
     printf("\n");
 #endif
 
-    /// scrambling
-    start_meas(dlsch_scrambling_stats);
     for (int q=0; q<rel15->NrOfCodewords; q++) {
-      memset((void*)scrambled_output[q], 0, ((encoded_length>>5)+1)*sizeof(uint32_t));
+      /// scrambling
+      start_meas(dlsch_scrambling_stats);
+      uint32_t scrambled_output[(encoded_length>>5)+4]; // modulator acces by 4 bytes in some cases
+      memset(scrambled_output, 0, sizeof(scrambled_output));
+      if ( encoded_length > rel15->rbSize * NR_SYMBOLS_PER_SLOT * NR_NB_SC_PER_RB * Qm * rel15->nrOfLayers) abort();
       nr_pdsch_codeword_scrambling(output,
                                    encoded_length,
                                    q,
                                    rel15->dataScramblingId,
                                    rel15->rnti,
-                                   scrambled_output[q]);
-    }
-    
-    stop_meas(dlsch_scrambling_stats);
+                                   scrambled_output);
+
 #ifdef DEBUG_DLSCH
-    printf("PDSCH scrambling:\n");
-    for (int i=0; i<encoded_length>>8; i++) {
-      for (int j=0; j<8; j++)
-	printf("0x%08x\t", scrambled_output[0][(i<<3)+j]);
-      printf("\n");
-    }
+      printf("PDSCH scrambling:\n");
+      for (int i=0; i<encoded_length>>8; i++) {
+        for (int j=0; j<8; j++)
+          printf("0x%08x\t", scrambled_output[(i<<3)+j]);
+        printf("\n");
+      }
 #endif
-    
-    /// Modulation
-    start_meas(dlsch_modulation_stats);
-    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_PDSCH_MODULATION, 1);
-    for (int q=0; q<rel15->NrOfCodewords; q++)
-      nr_modulation(scrambled_output[q],
-		    encoded_length,
-		    Qm,
-		    mod_symbs[q]);
-    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_PDSCH_MODULATION, 0);
-    stop_meas(dlsch_modulation_stats);
+
+      stop_meas(dlsch_scrambling_stats);
+      /// Modulation
+      start_meas(dlsch_modulation_stats);
+      nr_modulation(scrambled_output,
+                    encoded_length,
+                    Qm,
+                    mod_symbs[q]);
+      VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_PDSCH_MODULATION, 0);
+      stop_meas(dlsch_modulation_stats);
 #ifdef DEBUG_DLSCH
-    printf("PDSCH Modulation: Qm %d(%d)\n", Qm, nb_re);
-    for (int i=0; i<nb_re>>3; i++) {
-      for (int j=0; j<8; j++) {
-	printf("%d %d\t", mod_symbs[0][((i<<3)+j)<<1], mod_symbs[0][(((i<<3)+j)<<1)+1]);
+      printf("PDSCH Modulation: Qm %d(%d)\n", Qm, nb_re);
+      for (int i=0; i<nb_re>>3; i++) {
+        for (int j=0; j<8; j++) {
+          printf("%d %d\t", mod_symbs[0][((i<<3)+j)<<1], mod_symbs[0][(((i<<3)+j)<<1)+1]);
+        }
+        printf("\n");
       }
-      printf("\n");
-    }
 #endif
+    }
     
     start_meas(&gNB->dlsch_layer_mapping_stats); 
     /// Layer mapping
     nr_layer_mapping(mod_symbs,
-		     rel15->nrOfLayers,
-		     nb_re,
-		     tx_layers);
+                     rel15->nrOfLayers,
+                     nb_re,
+                     tx_layers);
 #ifdef DEBUG_DLSCH
     printf("Layer mapping (%d layers):\n", rel15->nrOfLayers);
     for (int l=0; l<rel15->nrOfLayers; l++)
       for (int i=0; i<(nb_re/rel15->nrOfLayers)>>3; i++) {
-	printf("layer %d, Re %d..%d : ",l,i<<3,(i<<3)+7);
-	for (int j=0; j<8; j++) {
-	  printf("l%d %d\t", tx_layers[l][((i<<3)+j)<<1], tx_layers[l][(((i<<3)+j)<<1)+1]);
-	}
-	printf("\n");
+        printf("layer %d, Re %d..%d : ",l,i<<3,(i<<3)+7);
+        for (int j=0; j<8; j++) {
+          printf("l%d %d\t", tx_layers[l][((i<<3)+j)<<1], tx_layers[l][(((i<<3)+j)<<1)+1]);
+        }
+        printf("\n");
       }
 #endif
 
@@ -222,7 +226,7 @@ void nr_generate_pdsch(processingData_L1tx_t *msgTx,
 
 #ifdef DEBUG_DLSCH_MAPPING
     printf("PDSCH resource mapping started (start SC %d\tstart symbol %d\tN_PRB %d\tnb_re %d,nb_layers %d)\n",
-	   start_sc, rel15->StartSymbolIndex, rel15->rbSize, nb_re,rel15->nrOfLayers);
+           start_sc, rel15->StartSymbolIndex, rel15->rbSize, nb_re,rel15->nrOfLayers);
 #endif
 
     start_meas(&gNB->dlsch_resource_mapping_stats);
@@ -275,7 +279,7 @@ void nr_generate_pdsch(processingData_L1tx_t *msgTx,
             l_prime = 0;
           }
           /// DMRS QPSK modulation
-          nr_modulation(pdsch_dmrs[l][0], n_dmrs*2, DMRS_MOD_ORDER, mod_dmrs); // currently only codeword 0 is modulated. Qm = 2 as DMRS is QPSK modulated
+          nr_modulation(pdsch_dmrs[l][rel15->SCID], n_dmrs*2, DMRS_MOD_ORDER, mod_dmrs); // Qm = 2 as DMRS is QPSK modulated
 
 #ifdef DEBUG_DLSCH
           printf("DMRS modulation (symbol %d, %d symbols, type %d):\n", l, n_dmrs, dmrs_Type);
@@ -296,7 +300,7 @@ void nr_generate_pdsch(processingData_L1tx_t *msgTx,
           if(ptrs_symbol) {
             /* PTRS QPSK Modulation for each OFDM symbol in a slot */
             LOG_D(PHY,"Doing ptrs modulation for symbol %d, n_ptrs %d\n",l,n_ptrs);
-            nr_modulation(pdsch_dmrs[l][0], (n_ptrs<<1), DMRS_MOD_ORDER, mod_ptrs);
+            nr_modulation(pdsch_dmrs[l][rel15->SCID], (n_ptrs<<1), DMRS_MOD_ORDER, mod_ptrs);
           }
         }
         uint16_t k = start_sc;
diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch.h b/openair1/PHY/NR_TRANSPORT/nr_dlsch.h
index 28676b49f26ae9f51bbf2e720c6c9f39e56825f5..daa4ed17230af7ae0078a809797f1e3dfd343c52 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_dlsch.h
+++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch.h
@@ -78,9 +78,9 @@ int16_t find_nr_dlsch(uint16_t rnti, PHY_VARS_gNB *gNB,find_type_t type);
 NR_gNB_SCH_STATS_t *find_nr_dlsch_stats(uint16_t rnti, PHY_VARS_gNB *gNB,find_type_t type);
 
 int nr_dlsch_encoding(PHY_VARS_gNB *gNB,
-		      unsigned char *a,int frame,
+		      int frame,
 		      uint8_t slot,
-		      NR_gNB_DLSCH_t *dlsch,
+		      NR_DL_gNB_HARQ_t *harq,
 		      NR_DL_FRAME_PARMS* frame_parms,
 		      unsigned char * output,
 		      time_stats_t *tinput,
diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c b/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c
index 229f59032e0aaebb90ad5d8aec7a711310f36a45..bf33457aaa3776ad7be58545f106a4c5e414ea95 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c
+++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c
@@ -286,10 +286,9 @@ void ldpc8blocks( void *p) {
 }
 
 int nr_dlsch_encoding(PHY_VARS_gNB *gNB,
-                      unsigned char *a,
                       int frame,
                       uint8_t slot,
-                      NR_gNB_DLSCH_t *dlsch,
+                      NR_DL_gNB_HARQ_t *harq,
                       NR_DL_FRAME_PARMS *frame_parms,
 		      unsigned char * output,
                       time_stats_t *tinput,time_stats_t *tprep,time_stats_t *tparity,time_stats_t *toutput,
@@ -298,13 +297,12 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB,
   encoder_implemparams_t impp;
   impp.output=output;
   unsigned int crc=1;
-  NR_DL_gNB_HARQ_t *harq = &dlsch->harq_process;
   nfapi_nr_dl_tti_pdsch_pdu_rel15_t *rel15 = &harq->pdsch_pdu.pdsch_pdu_rel15;
-  impp.Zc = &dlsch->harq_process.Z;
+  impp.Zc = &harq->Z;
   float Coderate = 0.0;
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_DLSCH_ENCODING, VCD_FUNCTION_IN);
   uint32_t A = rel15->TBSize[0]<<3;
-
+  unsigned char *a=harq->pdu;
   if ( rel15->rnti != SI_RNTI)
     trace_NRpdu(DIRECTION_DOWNLINK, a, rel15->TBSize[0], 0, WS_C_RNTI, rel15->rnti, frame, slot,0, 0);
 
@@ -317,14 +315,14 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB,
       stats=&gNB->dlsch_stats[i];
     }
 
-    if (gNB->dlsch_stats[i].rnti == dlsch->rnti) {
+    if (gNB->dlsch_stats[i].rnti == rel15->rnti) {
       stats=&gNB->dlsch_stats[i];
       break;
     }
   }
 
   if (stats) {
-    stats->rnti = dlsch->rnti;
+    stats->rnti = rel15->rnti;
     stats->total_bytes_tx += rel15->TBSize[0];
     stats->current_RI   = rel15->nrOfLayers;
     stats->current_Qm   = rel15->qamModOrder[0];
diff --git a/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h b/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h
index f9478b7633282abe3f14926387be019b4d586f08..9b24504a1414f609e29e26a69a287d7c73a4fce6 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h
+++ b/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h
@@ -338,7 +338,6 @@ uint8_t get_nr_prach_duration(uint8_t prach_format);
 void nr_generate_csi_rs(PHY_VARS_gNB *gNB,
                         int16_t amp,
                         nfapi_nr_dl_tti_csi_rs_pdu_rel15_t csi_params,
-                        uint16_t cell_id,
                         int slot);
 
 void free_nr_prach_entry(PHY_VARS_gNB *gNB, int prach_id);
diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c
index 49c1b898cc7372c8a7eb94a0b4dfac9b7b616966..bfbd696d9b005fe4d84795587cb9733c0ba840f8 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c
+++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c
@@ -76,8 +76,6 @@ void free_gNB_ulsch(NR_gNB_ULSCH_t **ulschptr, uint16_t N_RB_UL)
         free_and_zero(ulsch->harq_processes[i]->c[r]);
         free_and_zero(ulsch->harq_processes[i]->d[r]);
         free_and_zero(ulsch->harq_processes[i]->w[r]);
-        nrLDPC_free_mem(ulsch->harq_processes[i]->p_nrLDPC_procBuf[r]);
-        ulsch->harq_processes[i]->p_nrLDPC_procBuf[r] = NULL;
       }
       free_and_zero(ulsch->harq_processes[i]);
       ulsch->harq_processes[i] = NULL;
@@ -101,22 +99,21 @@ NR_gNB_ULSCH_t *new_gNB_ulsch(uint8_t max_ldpc_iterations, uint16_t N_RB_UL)
 
   uint32_t ulsch_bytes = a_segments*1056;  // allocated bytes per segment
   ulsch = (NR_gNB_ULSCH_t *)malloc16_clear(sizeof(NR_gNB_ULSCH_t));
-  
+
   ulsch->max_ldpc_iterations = max_ldpc_iterations;
   ulsch->Mlimit = 4;
-  
+
   for (i=0; i<NR_MAX_ULSCH_HARQ_PROCESSES; i++) {
-    
+
     ulsch->harq_processes[i] = (NR_UL_gNB_HARQ_t *)malloc16_clear(sizeof(NR_UL_gNB_HARQ_t));
     ulsch->harq_processes[i]->b = (uint8_t*)malloc16_clear(ulsch_bytes);
     for (r=0; r<a_segments; r++) {
-      ulsch->harq_processes[i]->p_nrLDPC_procBuf[r] = nrLDPC_init_mem();
       ulsch->harq_processes[i]->c[r] = (uint8_t*)malloc16_clear(8448*sizeof(uint8_t));
       ulsch->harq_processes[i]->d[r] = (int16_t*)malloc16_clear((68*384)*sizeof(int16_t));
       ulsch->harq_processes[i]->w[r] = (int16_t*)malloc16_clear((3*(6144+64))*sizeof(int16_t));
     }
   }
-  
+
   return(ulsch);
 }
 
@@ -360,7 +357,6 @@ void nr_processULSegment(void* arg) {
   no_iteration_ldpc = nrLDPC_decoder(p_decoderParms,
                                      (int8_t*)&pl[0],
                                      llrProcBuf,
-                                     ulsch_harq->p_nrLDPC_procBuf[r],
                                      p_procTime);
 
   if (check_crc((uint8_t*)llrProcBuf,length_dec,ulsch_harq->F,crc_type)) {
diff --git a/openair1/PHY/NR_TRANSPORT/pucch_rx.c b/openair1/PHY/NR_TRANSPORT/pucch_rx.c
index 50c3b62f5023931ad28924a9f96d96bfcf9c80e7..cd368a68cc31ec33092d19089f22e07d0b492739 100644
--- a/openair1/PHY/NR_TRANSPORT/pucch_rx.c
+++ b/openair1/PHY/NR_TRANSPORT/pucch_rx.c
@@ -243,7 +243,7 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB,
    * x(l*12+n) = r_u_v_alpha_delta(n)
    */
   // the value of u,v (delta always 0 for PUCCH) has to be calculated according to TS 38.211 Subclause 6.3.2.2.1
-  uint8_t u[2]={0,0},v[2]={0,0};
+  uint8_t u[2]={0},v[2]={0};
 
   // x_n contains the sequence r_u_v_alpha_delta(n)
 
@@ -262,7 +262,7 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB,
 
 
   AssertFatal(pucch_pdu->nr_of_symbols < 3,"nr_of_symbols %d not allowed\n",pucch_pdu->nr_of_symbols);
-  uint32_t re_offset[2]={0,0};
+  uint32_t re_offset[2]={0};
   uint8_t l2;
 
   const int16_t *x_re[2],*x_im[2];
@@ -271,16 +271,10 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB,
   x_re[1] = table_5_2_2_2_2_Re[u[1]];
   x_im[1] = table_5_2_2_2_2_Im[u[1]];
 
-  int16_t xr[1+frame_parms->nb_antennas_rx][1+pucch_pdu->nr_of_symbols][24]  __attribute__((aligned(32)));
+  c64_t xr[frame_parms->nb_antennas_rx][pucch_pdu->nr_of_symbols][12]  __attribute__((aligned(32)));
   int64_t xrtmag=0,xrtmag_next=0;
   uint8_t maxpos=0;
   uint8_t index=0;
-  for (int l=0; l<pucch_pdu->nr_of_symbols; l++) {
-    for (int aarx=0;aarx<frame_parms->nb_antennas_rx;aarx++) {
-      memset((void*)xr[aarx][l],0,24*sizeof(int16_t));
-    }
-  }
-  int n2;
 
   for (int l=0; l<pucch_pdu->nr_of_symbols; l++) {
     l2 = l+pucch_pdu->start_symbol_index;
@@ -289,75 +283,68 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB,
       re_offset[l]-=frame_parms->ofdm_symbol_size;
   
     AssertFatal(re_offset[l]+12 < frame_parms->ofdm_symbol_size,"pucch straddles DC carrier, handle this!\n");
-    int16_t *r;
     for (int aa=0;aa<frame_parms->nb_antennas_rx;aa++) {
-      r=(int16_t*)&rxdataF[aa][soffset+(l2*frame_parms->ofdm_symbol_size)+re_offset[l]];
-      n2=0;
-      for (n=0;n<12;n++,n2+=2) {
-        xr[aa][l][n2]  +=(int16_t)(((int32_t)x_re[l][n]*r[n2]+(int32_t)x_im[l][n]*r[n2+1])>>15);
-        xr[aa][l][n2+1]+=(int16_t)(((int32_t)x_re[l][n]*r[n2+1]-(int32_t)x_im[l][n]*r[n2])>>15);
+      c16_t *r=(c16_t*)&rxdataF[aa][soffset+(l2*frame_parms->ofdm_symbol_size)+re_offset[l]];
+      for (n=0;n<12;n++) {
+        xr[aa][l][n].r = (int32_t)x_re[l][n] * r[n].r + (int32_t)x_im[l][n] * r[n].i;
+        xr[aa][l][n].i = (int32_t)x_re[l][n] * r[n].i - (int32_t)x_im[l][n] * r[n].r;
 #ifdef DEBUG_NR_PUCCH_RX
-        printf("x (%d,%d), r%d.%d (%d,%d), xr (%d,%d)\n",
-	               x_re[l][n],x_im[l][n],l2,re_offset[l],r[n2],r[n2+1],xr[aa][l][n2],xr[aa][l][n2+1]);
+        printf("x (%d,%d), r%d.%d (%d,%d), xr (%lld,%lld)\n",
+	             x_re[l][n],x_im[l][n],l2,re_offset[l],r[n].r,r[n].i,xr[aa][l][n].r,xr[aa][l][n].i);
 #endif
       }
     }
   }
 
-  int32_t corr_re[1+frame_parms->nb_antennas_rx][2];
-  int32_t corr_im[1+frame_parms->nb_antennas_rx][2];
   //int32_t no_corr = 0;
   int seq_index = 0;
   int64_t temp;
 
   for(i=0;i<nr_sequences;i++){
-
-    for (int l=0;l<pucch_pdu->nr_of_symbols;l++) {
-      seq_index = (pucch_pdu->initial_cyclic_shift+
-		   mcs[i]+
-		   gNB->pucch0_lut.lut[cs_ind][slot][l+pucch_pdu->start_symbol_index])%12;
+    c64_t corr[frame_parms->nb_antennas_rx][2];
+    for (int aa=0;aa<frame_parms->nb_antennas_rx;aa++) {
+      for (int l=0;l<pucch_pdu->nr_of_symbols;l++) {
+        seq_index = (pucch_pdu->initial_cyclic_shift+
+                     mcs[i]+
+                     gNB->pucch0_lut.lut[cs_ind][slot][l+pucch_pdu->start_symbol_index])%12;
 #ifdef DEBUG_NR_PUCCH_RX
-      printf("PUCCH symbol %d seq %d, seq_index %d, mcs %d\n",l,i,seq_index,mcs[i]);
+        printf("PUCCH symbol %d seq %d, seq_index %d, mcs %d\n",l,i,seq_index,mcs[i]);
 #endif
-      for (int aa=0;aa<frame_parms->nb_antennas_rx;aa++) {
-        corr_re[aa][l]=0;
-        corr_im[aa][l]=0;
-
-        n2=0;
-        for (n=0;n<12;n++,n2+=2) {
-          corr_re[aa][l]+=(xr[aa][l][n2]*idft12_re[seq_index][n]+xr[aa][l][n2+1]*idft12_im[seq_index][n])>>15;
-          corr_im[aa][l]+=(xr[aa][l][n2]*idft12_im[seq_index][n]-xr[aa][l][n2+1]*idft12_re[seq_index][n])>>15;
+        corr[aa][l]=(c64_t){0};
+        for (n = 0; n < 12; n++) {
+          corr[aa][l].r += xr[aa][l][n].r * idft12_re[seq_index][n] + xr[aa][l][n].i * idft12_im[seq_index][n];
+          corr[aa][l].i += xr[aa][l][n].r * idft12_im[seq_index][n] - xr[aa][l][n].i * idft12_re[seq_index][n];
         }
+	corr[aa][l].r >>= 31;
+	corr[aa][l].i >>= 31;
       }
     }
-    LOG_D(PHY,"PUCCH IDFT[%d/%d] = (%d,%d)=>%f\n",
-          mcs[i],seq_index,corr_re[0][0],corr_im[0][0],
-          10*log10((double)corr_re[0][0]*corr_re[0][0] + (double)corr_im[0][0]*corr_im[0][0]));
+    LOG_D(PHY,"PUCCH IDFT[%d/%d] = (%ld,%ld)=>%f\n",
+          mcs[i],seq_index,corr[0][0].r,corr[0][0].i,
+          10*log10((double)squaredMod(corr[0][0])));
     if (pucch_pdu->nr_of_symbols==2)
-       LOG_D(PHY,"PUCCH 2nd symbol IDFT[%d/%d] = (%d,%d)=>%f\n",
-             mcs[i],seq_index,corr_re[0][1],corr_im[0][1],
-             10*log10((double)corr_re[0][1]*corr_re[0][1] + (double)corr_im[0][1]*corr_im[0][1]));
+       LOG_D(PHY,"PUCCH 2nd symbol IDFT[%d/%d] = (%ld,%ld)=>%f\n",
+             mcs[i],seq_index,corr[0][1].r,corr[0][1].i,
+             10*log10((double)squaredMod(corr[0][1])));
     if (pucch_pdu->freq_hop_flag == 0) {
        if (pucch_pdu->nr_of_symbols==1) {// non-coherent correlation
           temp=0;
           for (int aa=0;aa<frame_parms->nb_antennas_rx;aa++)
-             temp+=(int64_t)corr_re[aa][0]*corr_re[aa][0] + (int64_t)corr_im[aa][0]*corr_im[aa][0];
+            temp+=squaredMod(corr[aa][0]);
         } else {
-          int64_t corr_re2=0;
-          int64_t corr_im2=0;
           temp=0;
           for (int aa=0;aa<frame_parms->nb_antennas_rx;aa++) {
-             corr_re2 = (int64_t)corr_re[aa][0]+corr_re[aa][1];
-             corr_im2 = (int64_t)corr_im[aa][0]+corr_im[aa][1];
-             // coherent combining of 2 symbols and then complex modulus for single-frequency case
-             temp+=corr_re2*corr_re2 + corr_im2*corr_im2;
+            c64_t corr2;
+            csum(corr2, corr[aa][0], corr[aa][1]);
+            // coherent combining of 2 symbols and then complex modulus for single-frequency case
+            temp+=corr2.r*corr2.r + corr2.i*corr2.i;
           }
         }
     } else if (pucch_pdu->freq_hop_flag == 1) {
       // full non-coherent combining of 2 symbols for frequency-hopping case
       temp=0;
       for (int aa=0;aa<frame_parms->nb_antennas_rx;aa++)
-        temp += (int64_t)corr_re[aa][0]*corr_re[aa][0] + (int64_t)corr_im[aa][0]*corr_im[aa][0] + (int64_t)corr_re[aa][1]*corr_re[aa][1] + (int64_t)corr_im[aa][1]*corr_im[aa][1];
+        temp += squaredMod(corr[aa][0]) + squaredMod(corr[aa][1]);
     }
     else AssertFatal(1==0,"shouldn't happen\n");
 
@@ -369,9 +356,9 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB,
       uci_stats->current_pucch0_stat0 = 0;
       int64_t temp2=0,temp3=0;;
       for (int aa=0;aa<frame_parms->nb_antennas_rx;aa++) {
-        temp2 += ((int64_t)corr_re[aa][0]*corr_re[aa][0] + (int64_t)corr_im[aa][0]*corr_im[aa][0]);
+        temp2 += squaredMod(corr[aa][0]);
         if (pucch_pdu->nr_of_symbols==2)
-	  temp3 += ((int64_t)corr_re[aa][1]*corr_re[aa][1] + (int64_t)corr_im[aa][1]*corr_im[aa][1]);
+	  temp3 += squaredMod(corr[aa][1]);
       }
       uci_stats->current_pucch0_stat0= dB_fixed64(temp2);
       if ( pucch_pdu->nr_of_symbols==2)
@@ -392,7 +379,8 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB,
   uci_stats->pucch0_n01 = gNB->measurements.n0_subband_power_tot_dB[prb_offset[1]];
   LOG_D(PHY,"n00[%d] = %d, n01[%d] = %d\n",prb_offset[0],uci_stats->pucch0_n00,prb_offset[1],uci_stats->pucch0_n01);
   // estimate CQI for MAC (from antenna port 0 only)
-  int max_n0 = uci_stats->pucch0_n00>uci_stats->pucch0_n01 ? uci_stats->pucch0_n00:uci_stats->pucch0_n01;
+  int max_n0 = max(gNB->measurements.n0_subband_power_tot_dB[prb_offset[0]],
+		   gNB->measurements.n0_subband_power_tot_dB[prb_offset[1]]);
   int SNRtimes10,sigenergy=0;
   for (int aa=0;aa<frame_parms->nb_antennas_rx;aa++)
     sigenergy += signal_energy_nodc(&rxdataF[aa][soffset+
@@ -407,8 +395,15 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB,
   uci_stats->pucch0_thres = gNB->pucch0_thres; /* + (10*max_n0);*/
   bool no_conf=false;
   if (nr_sequences>1) {
-    if (xrtmag_dBtimes10 < (50+xrtmag_next_dBtimes10) || SNRtimes10 < uci_stats->pucch0_thres)
+    if (xrtmag_dBtimes10 < (50+xrtmag_next_dBtimes10) || SNRtimes10 < gNB->pucch0_thres) {
       no_conf=true;
+      LOG_D(PHY,"%d.%d PUCCH bad confidence: %d threshold, %d, %d, %d\n",
+	  frame, slot,
+	  uci_stats->pucch0_thres,
+	  SNRtimes10,
+	  xrtmag_dBtimes10,
+	  xrtmag_next_dBtimes10);
+    }
   }
   gNB->bad_pucch += no_conf;
   // first bit of bitmap for sr presence and second bit for acknack presence
@@ -422,11 +417,12 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB,
   if (pucch_pdu->bit_len_harq==0) {
     uci_pdu->harq = NULL;
     uci_pdu->sr = calloc(1,sizeof(*uci_pdu->sr));
-    uci_pdu->sr->sr_confidence_level = no_conf ? 1 : 0;
+    uci_pdu->sr->sr_confidence_level = SNRtimes10 < uci_stats->pucch0_thres;
     uci_stats->pucch0_sr_trials++;
-    if (xrtmag_dBtimes10>(10*gNB->measurements.n0_power_tot_dB)) {
+    if (xrtmag_dBtimes10>(10*max_n0+100)) {
       uci_pdu->sr->sr_indication = 1;
       uci_stats->pucch0_positive_SR++;
+      LOG_D(PHY,"PUCCH0 got positive SR. Cumulative number of positive SR %d\n", uci_stats->pucch0_positive_SR);
     } else {
       uci_pdu->sr->sr_indication = 0;
     }
@@ -434,35 +430,50 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB,
   else if (pucch_pdu->bit_len_harq==1) {
     uci_pdu->harq = calloc(1,sizeof(*uci_pdu->harq));
     uci_pdu->harq->num_harq = 1;
-    uci_pdu->harq->harq_confidence_level = no_conf ? 1 : 0;
-    uci_pdu->harq->harq_list = (nfapi_nr_harq_t*)malloc(1);
+    uci_pdu->harq->harq_confidence_level = no_conf;
+    uci_pdu->harq->harq_list = (nfapi_nr_harq_t*)malloc(sizeof *uci_pdu->harq->harq_list);
 
     uci_pdu->harq->harq_list[0].harq_value = !(index&0x01);
-    LOG_D(PHY, "[DLSCH/PDSCH/PUCCH] %d.%d HARQ value %d (0 pass, 1 fail) with confidence level %d (0 is good, 1 is bad) xrt_mag %d xrt_mag_next %d n0 %d (%d,%d) pucch0_thres %d, cqi %d, SNRtimes10 %d, energy %f, sync_pos %d\n",
-          frame,slot,uci_pdu->harq->harq_list[0].harq_value,uci_pdu->harq->harq_confidence_level,xrtmag_dBtimes10,xrtmag_next_dBtimes10,max_n0,uci_stats->pucch0_n00,uci_stats->pucch0_n01,uci_stats->pucch0_thres,cqi,SNRtimes10,10*log10((double)sigenergy),gNB->ulsch_stats[0].sync_pos);
+    LOG_D(PHY, "[DLSCH/PDSCH/PUCCH] %d.%d HARQ %s with confidence level %s xrt_mag %d xrt_mag_next %d n0 %d (%d,%d) pucch0_thres %d, cqi %d, SNRtimes10 %d, energy %f, sync_pos %d\n",
+          frame,slot,uci_pdu->harq->harq_list[0].harq_value==0?"ACK":"NACK",
+	  uci_pdu->harq->harq_confidence_level==0?"good":"bad",
+	  xrtmag_dBtimes10,xrtmag_next_dBtimes10,max_n0,uci_stats->pucch0_n00,uci_stats->pucch0_n01,uci_stats->pucch0_thres,cqi,SNRtimes10,10*log10((double)sigenergy),gNB->ulsch_stats[0].sync_pos);
 
     if (pucch_pdu->sr_flag == 1) {
       uci_pdu->sr = calloc(1,sizeof(*uci_pdu->sr));
-      uci_pdu->sr->sr_indication = (index>1) ? 1 : 0;
-      uci_pdu->sr->sr_confidence_level = no_conf ? 1 : 0;
-      uci_stats->pucch0_positive_SR++;
+      uci_pdu->sr->sr_indication = (index>1);
+      uci_pdu->sr->sr_confidence_level = no_conf;
+      if(uci_pdu->sr->sr_indication == 1 && uci_pdu->sr->sr_confidence_level == 0) {
+        uci_stats->pucch0_positive_SR++;
+        LOG_D(PHY,"PUCCH0 got positive SR. Cumulative number of positive SR %d\n", uci_stats->pucch0_positive_SR);
+      }
     }
     uci_stats->pucch01_trials++;
   }
   else {
     uci_pdu->harq = calloc(1,sizeof(*uci_pdu->harq));
     uci_pdu->harq->num_harq = 2;
-    uci_pdu->harq->harq_confidence_level = (no_conf) ? 1 : 0;
-    uci_pdu->harq->harq_list = (nfapi_nr_harq_t*)malloc(2);
+    uci_pdu->harq->harq_confidence_level = no_conf;
+    uci_pdu->harq->harq_list = (nfapi_nr_harq_t*)malloc(2 * sizeof( *uci_pdu->harq->harq_list));
 
     uci_pdu->harq->harq_list[1].harq_value = !(index&0x01);
     uci_pdu->harq->harq_list[0].harq_value = !((index>>1)&0x01);
-    LOG_D(PHY, "[DLSCH/PDSCH/PUCCH] %d.%d HARQ values %d and %d (0 pass, 1 fail) with confidence level %d (0 is good, 1 is bad), xrt_mag %d xrt_mag_next %d n0 %d (%d,%d) pucch0_thres %d, cqi %d, SNRtimes10 %d,sync_pos %d\n",
-          frame,slot,uci_pdu->harq->harq_list[1].harq_value,uci_pdu->harq->harq_list[0].harq_value,uci_pdu->harq->harq_confidence_level,xrtmag_dBtimes10,xrtmag_next_dBtimes10,max_n0,uci_stats->pucch0_n00,uci_stats->pucch0_n01,uci_stats->pucch0_thres,cqi,SNRtimes10,gNB->ulsch_stats[0].sync_pos);
+    LOG_D(PHY, "[DLSCH/PDSCH/PUCCH] %d.%d HARQ values (%s, %s) with confidence level %s, xrt_mag %d xrt_mag_next %d n0 %d (%d,%d) pucch0_thres %d, cqi %d, SNRtimes10 %d,sync_pos %d\n",
+          frame,slot,
+          uci_pdu->harq->harq_list[1].harq_value == 0 ? "ACK" : "NACK",
+          uci_pdu->harq->harq_list[0].harq_value == 0 ? "ACK" : "NACK",
+          uci_pdu->harq->harq_confidence_level == 0 ? "good" : "bad",
+          xrtmag_dBtimes10,xrtmag_next_dBtimes10,max_n0,
+          uci_stats->pucch0_n00,uci_stats->pucch0_n01,uci_stats->pucch0_thres,cqi,
+          SNRtimes10,gNB->ulsch_stats[0].sync_pos);
     if (pucch_pdu->sr_flag == 1) {
       uci_pdu->sr = calloc(1,sizeof(*uci_pdu->sr));
       uci_pdu->sr->sr_indication = (index>3) ? 1 : 0;
-      uci_pdu->sr->sr_confidence_level = (no_conf) ? 1 : 0;
+      uci_pdu->sr->sr_confidence_level = no_conf;
+      if(uci_pdu->sr->sr_indication == 1 && uci_pdu->sr->sr_confidence_level == 0) {
+        uci_stats->pucch0_positive_SR++;
+        LOG_D(PHY,"PUCCH0 got positive SR. Cumulative number of positive SR %d\n", uci_stats->pucch0_positive_SR);
+      }
     }
   }
 }
@@ -1671,7 +1682,8 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB,
     LOG_D(PHY,"metric %d dB\n",corr_dB);
   }
 
-    // estimate CQI for MAC (from antenna port 0 only)
+  // estimate CQI for MAC (from antenna port 0 only)
+  // TODO this computation is wrong -> to be ignored at MAC for now
   int SNRtimes10 = dB_fixed_times10(signal_energy_nodc(&rxdataF[0][soffset+(l2*frame_parms->ofdm_symbol_size)+re_offset[0]],
                                                        12*pucch_pdu->prb_size)) -
                                                        (10*gNB->measurements.n0_power_tot_dB);
diff --git a/openair1/PHY/NR_UE_ESTIMATION/nr_adjust_synch_ue.c b/openair1/PHY/NR_UE_ESTIMATION/nr_adjust_synch_ue.c
index f4f183793f97675d6ec2727403fef56b3489a551..045197adc1c6f0ff05ee608b2decb40bf06ec194 100644
--- a/openair1/PHY/NR_UE_ESTIMATION/nr_adjust_synch_ue.c
+++ b/openair1/PHY/NR_UE_ESTIMATION/nr_adjust_synch_ue.c
@@ -36,7 +36,8 @@
 void nr_adjust_synch_ue(NR_DL_FRAME_PARMS *frame_parms,
                         PHY_VARS_NR_UE *ue,
                         module_id_t gNB_id,
-			const int estimateSz, struct complex16 dl_ch_estimates_time[][estimateSz],
+                        const int estimateSz,
+                        struct complex16 dl_ch_estimates_time[][estimateSz],
                         uint8_t frame,
                         uint8_t subframe,
                         unsigned char clear,
diff --git a/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c b/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c
index 30836ded01426a2645122656dd43ffa4c1f8564c..3b4ce9a42354c76b127bc338bbc822c3974f95f3 100644
--- a/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c
+++ b/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c
@@ -197,9 +197,9 @@ int nr_pbch_dmrs_correlation(PHY_VARS_NR_UE *ue,
 
 
 int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue,
-			       int estimateSz,
-			       struct complex16 dl_ch_estimates [][estimateSz],
-			       struct complex16 dl_ch_estimates_time [][estimateSz],
+                               int estimateSz,
+                               struct complex16 dl_ch_estimates [][estimateSz],
+                               struct complex16 dl_ch_estimates_time [][ue->frame_parms.ofdm_symbol_size],
                                UE_nr_rxtx_proc_t *proc,
                                uint8_t gNB_id,
                                unsigned char Ns,
@@ -320,7 +320,7 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue,
     rxF   = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)];
     dl_ch = (int16_t *)&dl_ch_estimates[aarx][ch_offset];
 
-    memset(dl_ch,0,sizeof(*dl_ch)*(ue->frame_parms.ofdm_symbol_size));
+    memset(dl_ch,0,sizeof(struct complex16)*(ue->frame_parms.ofdm_symbol_size));
 
 #ifdef DEBUG_CH
     printf("pbch ch est pilot addr %p RB_DL %d\n",&pilot[0], ue->frame_parms.N_RB_DL);
@@ -387,10 +387,10 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue,
 
       // in 2nd symbol, skip middle  REs (48 with DMRS,  144 for SSS, and another 48 with DMRS) 
       if (dmrss == 1 && pilot_cnt == 12) {
-	pilot_cnt=48;
-	re_offset = (re_offset+144) % ue->frame_parms.ofdm_symbol_size;
-	rxF   = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)];
-	dl_ch += 288;
+        pilot_cnt=48;
+        re_offset = (re_offset+144) % ue->frame_parms.ofdm_symbol_size;
+        rxF   = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)];
+        dl_ch += 288;
       }
       ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
       ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
@@ -452,10 +452,12 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue,
 	   (int16_t*) &dl_ch_estimates[aarx][ch_offset],
 	   (int16_t*) dl_ch_estimates_time[aarx],
 	   1);
-}
-}
+    }
+  }
+
   if (dmrss == 2)
     UEscopeCopy(ue, pbchDlChEstimateTime, (void*)dl_ch_estimates_time, sizeof(struct complex16), ue->frame_parms.nb_antennas_rx, idftsizeidx);
+
   return(0);
 }
 
@@ -464,8 +466,11 @@ int nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue,
                                 uint8_t gNB_id,
                                 unsigned char Ns,
                                 unsigned char symbol,
+                                unsigned short scrambling_id,
                                 unsigned short coreset_start_subcarrier,
-                                unsigned short nb_rb_coreset)
+                                unsigned short nb_rb_coreset,
+                                int32_t pdcch_est_size,
+                                int32_t pdcch_dl_ch_estimates[][pdcch_est_size])
 {
 
   unsigned char aarx;
@@ -474,7 +479,6 @@ int nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue,
   int16_t ch[2],*pil,*rxF,*dl_ch,*fl,*fm,*fr;
   int ch_offset,symbol_offset;
 
-  int **dl_ch_estimates  =ue->pdcch_vars[proc->thread_id][gNB_id]->dl_ch_estimates;
   int **rxdataF=ue->common_vars.common_vars_rx_data_per_thread[proc->thread_id].rxdataF;
 
   ch_offset     = ue->frame_parms.ofdm_symbol_size*symbol;
@@ -491,13 +495,11 @@ int nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue,
   fm = filt16a_m1;
   fr = filt16a_r1;
 
-
   // checking if re-initialization of scrambling IDs is needed (should be done here but scrambling ID for PDCCH is not taken from RRC)
-/*  if (( != ue->scramblingID_pdcch){
-    ue->scramblingID_pdcch=;
-    nr_gold_pdsch(ue,ue->scramblingID_pdcch);
-  }*/
-
+  if (scrambling_id != ue->scramblingID_pdcch){
+    ue->scramblingID_pdcch = scrambling_id;
+    nr_gold_pdcch(ue,ue->scramblingID_pdcch);
+  }
 
   // generate pilot
   int pilot[nb_rb_coreset * 3] __attribute__((aligned(16))); 
@@ -509,7 +511,7 @@ int nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue,
     k = coreset_start_subcarrier;
     pil   = (int16_t *)&pilot[0];
     rxF   = (int16_t *)&rxdataF[aarx][(symbol_offset+k+1)];
-    dl_ch = (int16_t *)&dl_ch_estimates[aarx][ch_offset];
+    dl_ch = (int16_t *)&pdcch_dl_ch_estimates[aarx][ch_offset];
 
     memset(dl_ch,0,4*(ue->frame_parms.ofdm_symbol_size));
 
@@ -664,6 +666,8 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue,
                                 unsigned char Ns,
                                 unsigned short p,
                                 unsigned char symbol,
+                                unsigned char nscid,
+                                unsigned short scrambling_id,
                                 unsigned short BWPStart,
                                 uint8_t config_type,
                                 unsigned short bwp_start_subcarrier,
@@ -701,11 +705,10 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue,
   int8_t delta = get_delta(p, config_type);
 
   // checking if re-initialization of scrambling IDs is needed
-  /*if ((XXX.scramblingID0 != ue->scramblingID[0]) || (XXX.scramblingID1 != ue->scramblingID[1])){
-    ue->scramblingID[0] = XXX.scramblingID0;
-    ue->scramblingID[1] = XXX.scramblingID1;
-    nr_gold_pdsch(ue,ue->scramblingID);
-  }*/
+  if (scrambling_id != ue->scramblingID_dlsch[nscid]){
+    ue->scramblingID_dlsch[nscid] = scrambling_id;
+    nr_gold_pdsch(ue, nscid, scrambling_id);
+  }
 
   nr_pdsch_dmrs_rx(ue, Ns, ue->nr_gold_pdsch[gNB_id][Ns][symbol][0], &pilot[0], 1000+p, 0, nb_rb_pdsch+rb_offset, config_type);
 
diff --git a/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h b/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h
index aa4b78e1453cef70f784e4f3e7cedd325a076a3a..ce99f0f9c96a770b4f9d1261475328b1879225bf 100644
--- a/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h
+++ b/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h
@@ -44,8 +44,11 @@ int nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue,
                                 uint8_t gNB_id,
                                 unsigned char Ns,
                                 unsigned char symbol,
+                                unsigned short scrambling_id,
                                 unsigned short coreset_start_subcarrier,
-                                unsigned short nb_rb_coreset);
+                                unsigned short nb_rb_coreset,
+                                int32_t pdcch_est_size,
+                                int32_t pdcch_dl_ch_estimates[][pdcch_est_size]);
 
 int nr_pbch_dmrs_correlation(PHY_VARS_NR_UE *ue,
                              UE_nr_rxtx_proc_t *proc,
@@ -74,6 +77,8 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue,
                                 unsigned char Ns,
                                 unsigned short p,
                                 unsigned char symbol,
+                                unsigned char nscid,
+                                unsigned short scrambling_id,
                                 unsigned short BWPStart,
                                 uint8_t config_type,
                                 unsigned short bwp_start_subcarrier,
diff --git a/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c b/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c
index b5cc765be4443a8086bfbb58aa1016b8d7dfd786..336d388d40d794644f9774418bcbfe92399abd78 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c
@@ -42,6 +42,7 @@
 #include "PHY/CODING/coding_extern.h"
 #include "PHY/sse_intrin.h"
 #include "common/utils/nr/nr_common.h"
+#include <openair1/PHY/TOOLS/phy_scope_interface.h>
 
 #include "assertions.h"
 #include "T.h"
@@ -79,8 +80,8 @@ char nr_dci_format_string[8][30] = {
 //static const int16_t conjugate[8]__attribute__((aligned(32))) = {-1,1,-1,1,-1,1,-1,1};
 
 
-void nr_pdcch_demapping_deinterleaving(uint32_t *llr,
-                                       uint32_t *z,
+static void nr_pdcch_demapping_deinterleaving(uint32_t *llr,
+                                       uint32_t *e_rx,
                                        uint8_t coreset_time_dur,
                                        uint8_t start_symbol,
                                        uint32_t coreset_nbr_rb,
@@ -186,10 +187,10 @@ void nr_pdcch_demapping_deinterleaving(uint32_t *llr,
             index_z = data_sc * rb_count;
             index_llr = (uint16_t) (f*B_rb + rb + symbol_idx * coreset_nbr_rb) * data_sc;
             for (int i = 0; i < data_sc; i++) {
-              z[index_z + i] = llr[index_llr + i];
+              e_rx[index_z + i] = llr[index_llr + i];
 #ifdef NR_PDCCH_DCI_DEBUG
               LOG_I(PHY,"[candidate=%d,symbol_idx=%d,cce=%d,REG bundle=%d,PRB=%d] z[%d]=(%d,%d) <-> \t llr[%d]=(%d,%d) \n",
-                    c_id,symbol_idx,cce_count,k,f*B_rb + rb,(index_z + i),*(int16_t *) &z[index_z + i],*(1 + (int16_t *) &z[index_z + i]),
+                    c_id,symbol_idx,cce_count,k,f*B_rb + rb,(index_z + i),*(int16_t *) &e_rx[index_z + i],*(1 + (int16_t *) &e_rx[index_z + i]),
                     (index_llr + i),*(int16_t *) &llr[index_llr + i], *(1 + (int16_t *) &llr[index_llr + i]));
 #endif
             }
@@ -201,7 +202,7 @@ void nr_pdcch_demapping_deinterleaving(uint32_t *llr,
   }
 }
 
-int32_t nr_pdcch_llr(NR_DL_FRAME_PARMS *frame_parms, int32_t **rxdataF_comp,
+int32_t nr_pdcch_llr(NR_DL_FRAME_PARMS *frame_parms, int32_t rx_size, int32_t rxdataF_comp[][rx_size],
                      int16_t *pdcch_llr, uint8_t symbol,uint32_t coreset_nbr_rb) {
   int16_t *rxF = (int16_t *) &rxdataF_comp[0][(symbol * coreset_nbr_rb * 12)];
   int32_t i;
@@ -270,7 +271,8 @@ int32_t pdcch_llr(NR_DL_FRAME_PARMS *frame_parms,
 //__m128i avg128P;
 
 //compute average channel_level on each (TX,RX) antenna pair
-void nr_pdcch_channel_level(int32_t **dl_ch_estimates_ext,
+void nr_pdcch_channel_level(int32_t rx_size,
+                            int32_t dl_ch_estimates_ext[][rx_size],
                             NR_DL_FRAME_PARMS *frame_parms,
                             int32_t *avg,
                             int symbol,
@@ -337,9 +339,11 @@ void nr_pdcch_channel_level(int32_t **dl_ch_estimates_ext,
 
 // This function will extract the mapped DM-RS PDCCH REs as per 38.211 Section 7.4.1.3.2 (Mapping to physical resources)
 void nr_pdcch_extract_rbs_single(int32_t **rxdataF,
-                                 int32_t **dl_ch_estimates,
-                                 int32_t **rxdataF_ext,
-                                 int32_t **dl_ch_estimates_ext,
+                                 int32_t est_size,
+                                 int32_t dl_ch_estimates[][est_size],
+                                 int32_t rx_size,
+                                 int32_t rxdataF_ext[][rx_size],
+                                 int32_t dl_ch_estimates_ext[][rx_size],
                                  uint8_t symbol,
                                  NR_DL_FRAME_PARMS *frame_parms,
                                  uint8_t *coreset_freq_dom,
@@ -515,9 +519,9 @@ void nr_pdcch_extract_rbs_single(int32_t **rxdataF,
 
 #define print_shorts(s,x) printf("%s %d,%d,%d,%d,%d,%d,%d,%d\n",s,(x)[0],(x)[1],(x)[2],(x)[3],(x)[4],(x)[5],(x)[6],(x)[7])
 
-void nr_pdcch_channel_compensation(int32_t **rxdataF_ext,
-                                   int32_t **dl_ch_estimates_ext,
-                                   int32_t **rxdataF_comp,
+void nr_pdcch_channel_compensation(int32_t rx_size, int32_t rxdataF_ext[][rx_size],
+                                   int32_t dl_ch_estimates_ext[][rx_size],
+                                   int32_t rxdataF_comp[][rx_size],
                                    int32_t **rho,
                                    NR_DL_FRAME_PARMS *frame_parms,
                                    uint8_t symbol,
@@ -628,7 +632,8 @@ void nr_pdcch_channel_compensation(int32_t **rxdataF_ext,
 
 
 void nr_pdcch_detection_mrc(NR_DL_FRAME_PARMS *frame_parms,
-                         int32_t **rxdataF_comp,
+                         int32_t rx_size,
+                         int32_t rxdataF_comp[][rx_size],
                          uint8_t symbol) {
 #if defined(__x86_64__) || defined(__i386__)
   __m128i *rxdataF_comp128_0,*rxdataF_comp128_1;
@@ -664,18 +669,31 @@ void nr_pdcch_detection_mrc(NR_DL_FRAME_PARMS *frame_parms,
 
 int32_t nr_rx_pdcch(PHY_VARS_NR_UE *ue,
                     UE_nr_rxtx_proc_t *proc,
+                    int32_t pdcch_est_size,
+                    int32_t pdcch_dl_ch_estimates[][pdcch_est_size],
+                    int16_t *pdcch_e_rx,
                     fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15) {
 
   uint32_t frame = proc->frame_rx;
   uint32_t slot  = proc->nr_slot_rx;
   NR_UE_COMMON *common_vars      = &ue->common_vars;
   NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
-  NR_UE_PDCCH *pdcch_vars        = ue->pdcch_vars[proc->thread_id][0];
 
   uint8_t log2_maxh, aarx;
   int32_t avgs;
   int32_t avgP[4];
   int n_rb,rb_offset;
+
+  // Pointers to extracted PDCCH symbols in frequency-domain.
+  int32_t rx_size = 4*273*12;
+  int32_t rxdataF_ext[4*frame_parms->nb_antennas_rx][rx_size];
+  int32_t rxdataF_comp[4*frame_parms->nb_antennas_rx][rx_size];
+  int32_t pdcch_dl_ch_estimates_ext[4*frame_parms->nb_antennas_rx][rx_size];
+
+  // Pointer to llrs, 4-bit resolution.
+  int32_t llr_size = 2*4*100*12;
+  int16_t llr[llr_size];
+
   get_coreset_rballoc(rel15->coreset.frequency_domain_resource,&n_rb,&rb_offset);
   LOG_D(PHY,"pdcch coreset: freq %x, n_rb %d, rb_offset %d\n",
         rel15->coreset.frequency_domain_resource[0],n_rb,rb_offset);
@@ -683,9 +701,11 @@ int32_t nr_rx_pdcch(PHY_VARS_NR_UE *ue,
     LOG_D(PHY,"in nr_pdcch_extract_rbs_single(rxdataF -> rxdataF_ext || dl_ch_estimates -> dl_ch_estimates_ext)\n");
 
     nr_pdcch_extract_rbs_single(common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF,
-                                pdcch_vars->dl_ch_estimates,
-                                pdcch_vars->rxdataF_ext,
-                                pdcch_vars->dl_ch_estimates_ext,
+                                pdcch_est_size,
+                                pdcch_dl_ch_estimates,
+                                rx_size,
+                                rxdataF_ext,
+                                pdcch_dl_ch_estimates_ext,
                                 s,
                                 frame_parms,
                                 rel15->coreset.frequency_domain_resource,
@@ -695,7 +715,8 @@ int32_t nr_rx_pdcch(PHY_VARS_NR_UE *ue,
     LOG_D(PHY,"we enter nr_pdcch_channel_level(avgP=%d) => compute channel level based on ofdm symbol 0, pdcch_vars[eNB_id]->dl_ch_estimates_ext\n",*avgP);
     LOG_D(PHY,"in nr_pdcch_channel_level(dl_ch_estimates_ext -> dl_ch_estimates_ext)\n");
     // compute channel level based on ofdm symbol 0
-    nr_pdcch_channel_level(pdcch_vars->dl_ch_estimates_ext,
+    nr_pdcch_channel_level(rx_size,
+                           pdcch_dl_ch_estimates_ext,
                            frame_parms,
                            avgP,
                            s,
@@ -717,26 +738,33 @@ int32_t nr_rx_pdcch(PHY_VARS_NR_UE *ue,
     LOG_D(PHY,"we enter nr_pdcch_channel_compensation(log2_maxh=%d)\n",log2_maxh);
     LOG_D(PHY,"in nr_pdcch_channel_compensation(rxdataF_ext x dl_ch_estimates_ext -> rxdataF_comp)\n");
     // compute LLRs for ofdm symbol 0 only
-    nr_pdcch_channel_compensation(pdcch_vars->rxdataF_ext,
-                                  pdcch_vars->dl_ch_estimates_ext,
-                                  pdcch_vars->rxdataF_comp,
+    nr_pdcch_channel_compensation(rx_size, rxdataF_ext,
+                                  pdcch_dl_ch_estimates_ext,
+                                  rxdataF_comp,
                                   NULL,
                                   frame_parms,
                                   s,
                                   log2_maxh,
                                   n_rb); // log2_maxh+I0_shift
+
+    UEscopeCopy(ue, pdcchRxdataF_comp, rxdataF_comp, sizeof(struct complex16), frame_parms->nb_antennas_rx, rx_size);
+
     if (frame_parms->nb_antennas_rx > 1) {
       LOG_D(PHY,"we enter nr_pdcch_detection_mrc(frame_parms->nb_antennas_rx=%d)\n", frame_parms->nb_antennas_rx);
-      nr_pdcch_detection_mrc(frame_parms, pdcch_vars->rxdataF_comp,s);
+      nr_pdcch_detection_mrc(frame_parms, rx_size, rxdataF_comp,s);
     }
 
     LOG_D(PHY,"we enter nr_pdcch_llr(for symbol %d), pdcch_vars[eNB_id]->rxdataF_comp ---> pdcch_vars[eNB_id]->llr \n",s);
     LOG_D(PHY,"in nr_pdcch_llr(rxdataF_comp -> llr)\n");
     nr_pdcch_llr(frame_parms,
-                 pdcch_vars->rxdataF_comp,
-                 pdcch_vars->llr,
+                 rx_size,
+                 rxdataF_comp,
+                 llr,
                  s,
                  n_rb);
+
+    UEscopeCopy(ue, pdcchLlr, llr, sizeof(int16_t), 1, llr_size);
+
 #if T_TRACER
     
     //  T(T_UE_PHY_PDCCH_IQ, T_INT(frame_parms->N_RB_DL), T_INT(frame_parms->N_RB_DL),
@@ -750,8 +778,8 @@ int32_t nr_rx_pdcch(PHY_VARS_NR_UE *ue,
   }
 
   LOG_D(PHY,"we enter nr_pdcch_demapping_deinterleaving(), number of candidates %d\n",rel15->number_of_candidates);
-  nr_pdcch_demapping_deinterleaving((uint32_t *) pdcch_vars->llr,
-                                    (uint32_t *) pdcch_vars->e_rx,
+  nr_pdcch_demapping_deinterleaving((uint32_t *) llr,
+                                    (uint32_t *) pdcch_e_rx,
                                     rel15->coreset.duration,
                                     rel15->coreset.StartSymbolIndex,
                                     n_rb,
@@ -770,7 +798,7 @@ int32_t nr_rx_pdcch(PHY_VARS_NR_UE *ue,
 
 
 
-void nr_pdcch_unscrambling(int16_t *z,
+void nr_pdcch_unscrambling(int16_t *e_rx,
                            uint16_t scrambling_RNTI,
                            uint32_t length,
                            uint16_t pdcch_DMRS_scrambling_id,
@@ -793,8 +821,10 @@ void nr_pdcch_unscrambling(int16_t *z,
       reset = 0;
     }
 
-    if (((s >> (i % 32)) & 1) == 1) z2[i] = -z[i];
-    else z2[i]=z[i];
+    if (((s >> (i % 32)) & 1) == 1)
+      z2[i] = -e_rx[i];
+    else
+      z2[i]=e_rx[i];
   }
 }
 
@@ -832,10 +862,10 @@ static uint16_t nr_dci_false_detection(uint64_t *dci,
 
 uint8_t nr_dci_decoding_procedure(PHY_VARS_NR_UE *ue,
                                   UE_nr_rxtx_proc_t *proc,
+                                  int16_t *pdcch_e_rx,
                                   fapi_nr_dci_indication_t *dci_ind,
-                                  fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15) {
-
-  NR_UE_PDCCH *pdcch_vars = ue->pdcch_vars[proc->thread_id][0];
+                                  fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15,
+                                  NR_UE_PDCCH_CONFIG *phy_pdcch_config) {
 
   //int gNB_id = 0;
   int16_t tmp_e[16*108];
@@ -847,6 +877,7 @@ uint8_t nr_dci_decoding_procedure(PHY_VARS_NR_UE *ue,
     int L = rel15->L[j];
 
     // Loop over possible DCI lengths
+    
     for (int k = 0; k < rel15->num_dci_options; k++) {
       // skip this candidate if we've already found one with the
       // same rnti and format at a different aggregation level
@@ -865,10 +896,11 @@ uint8_t nr_dci_decoding_procedure(PHY_VARS_NR_UE *ue,
       LOG_D(PHY, "(%i.%i) Trying DCI candidate %d of %d number of candidates, CCE %d (%d), L %d, length %d, format %s\n",
             proc->frame_rx, proc->nr_slot_rx, j, rel15->number_of_candidates, CCEind, e_rx_cand_idx, L, dci_length, nr_dci_format_string[rel15->dci_format_options[k]]);
 
-      nr_pdcch_unscrambling(&pdcch_vars->e_rx[e_rx_cand_idx], rel15->coreset.scrambling_rnti, L*108, rel15->coreset.pdcch_dmrs_scrambling_id, tmp_e);
+
+      nr_pdcch_unscrambling(&pdcch_e_rx[e_rx_cand_idx], rel15->coreset.scrambling_rnti, L*108, rel15->coreset.pdcch_dmrs_scrambling_id, tmp_e);
 
 #ifdef DEBUG_DCI_DECODING
-      uint32_t *z = (uint32_t *) &pdcch_vars->e_rx[e_rx_cand_idx];
+      uint32_t *z = (uint32_t *) &e_rx[e_rx_cand_idx];
       for (int index_z = 0; index_z < L*6; index_z++){
         for (int i=0; i<9; i++) {
           LOG_I(PHY,"z[%d]=(%d,%d) \n", (9*index_z + i), *(int16_t *) &z[9*index_z + i],*(1 + (int16_t *) &z[9*index_z + i]));
@@ -881,8 +913,8 @@ uint8_t nr_dci_decoding_procedure(PHY_VARS_NR_UE *ue,
                                          NR_POLAR_DCI_MESSAGE_TYPE, dci_length, L);
 
       n_rnti = rel15->rnti;
-      LOG_D(PHY, "(%i.%i) dci indication (rnti %x,dci format %s,n_CCE %d,payloadSize %d)\n",
-            proc->frame_rx, proc->nr_slot_rx,n_rnti,nr_dci_format_string[rel15->dci_format_options[k]],CCEind,dci_length);
+      LOG_D(PHY, "(%i.%i) dci indication (rnti %x,dci format %s,n_CCE %d,payloadSize %d,payload %llx )\n",
+            proc->frame_rx, proc->nr_slot_rx,n_rnti,nr_dci_format_string[rel15->dci_format_options[k]],CCEind,dci_length, *(unsigned long long*)dci_estimation);
       if (crc == n_rnti) {
         LOG_D(PHY, "(%i.%i) Received dci indication (rnti %x,dci format %s,n_CCE %d,payloadSize %d,payload %llx)\n",
               proc->frame_rx, proc->nr_slot_rx,n_rnti,nr_dci_format_string[rel15->dci_format_options[k]],CCEind,dci_length,*(unsigned long long*)dci_estimation);
@@ -910,7 +942,7 @@ uint8_t nr_dci_decoding_procedure(PHY_VARS_NR_UE *ue,
     }
     e_rx_cand_idx += 9*L*6*2; //e_rx index for next candidate (L CCEs, 6 REGs per CCE and 9 REs per REG and 2 uint16_t per RE)
   }
-  pdcch_vars->nb_search_space = 0;
+  phy_pdcch_config->nb_search_space = 0;
   return(dci_ind->number_of_dcis);
 }
 
diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c
index 8bdd83087a5fb200e290e63be8cad53dbfd26bcf..95d2cd95779347f81396d59b61b3c0e87b14ff84 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c
@@ -104,11 +104,9 @@ void free_nr_ue_dlsch(NR_UE_DLSCH_t **dlschptr, uint16_t N_RB_DL) {
           dlsch->harq_processes[i]->c[r] = NULL;
           free16(dlsch->harq_processes[i]->d[r],5*8448);
           dlsch->harq_processes[i]->d[r] = NULL;
-          nrLDPC_free_mem(dlsch->harq_processes[i]->p_nrLDPC_procBuf[r]);
         }
         free16(dlsch->harq_processes[i]->c,a_segments);
         free16(dlsch->harq_processes[i]->d,a_segments);
-        free16(dlsch->harq_processes[i]->p_nrLDPC_procBuf,a_segments);
 
         free16(dlsch->harq_processes[i],sizeof(NR_DL_UE_HARQ_t));
         dlsch->harq_processes[i] = NULL;
@@ -161,9 +159,7 @@ NR_UE_DLSCH_t *new_nr_ue_dlsch(uint8_t Kmimo,uint8_t Mdlharq,uint32_t Nsoft,uint
 
         dlsch->harq_processes[i]->c = (uint8_t **)malloc16(a_segments*sizeof(uint8_t *));
         dlsch->harq_processes[i]->d = (int16_t **)malloc16(a_segments*sizeof(int16_t *));
-        dlsch->harq_processes[i]->p_nrLDPC_procBuf = (t_nrLDPC_procBuf **)malloc16(a_segments*sizeof(t_nrLDPC_procBuf *));
         for (int r=0; r<a_segments; r++) {
-          dlsch->harq_processes[i]->p_nrLDPC_procBuf[r] = nrLDPC_init_mem();
           dlsch->harq_processes[i]->c[r] = (uint8_t *)malloc16(1056);
           dlsch->harq_processes[i]->d[r] = (int16_t *)malloc16(5*8448*sizeof(int16_t));
           if (dlsch->harq_processes[i]->c[r])
@@ -172,6 +168,7 @@ NR_UE_DLSCH_t *new_nr_ue_dlsch(uint8_t Kmimo,uint8_t Mdlharq,uint32_t Nsoft,uint
             memset(dlsch->harq_processes[i]->d[r],0,5*8448);
           else
             exit_flag=2;
+
         }
       } else {
         exit_flag=1;
@@ -225,7 +222,7 @@ bool nr_ue_postDecode(PHY_VARS_NR_UE *phy_vars_ue, notifiedFIFO_elt_t *req, bool
       //LOG_D(PHY,"[UE %d] DLSCH: Setting ACK for nr_slot_rx %d TBS %d mcs %d nb_rb %d harq_process->round %d\n",
       //      phy_vars_ue->Mod_id,nr_slot_rx,harq_process->TBS,harq_process->mcs,harq_process->nb_rb, harq_process->round);
       harq_process->status = SCH_IDLE;
-      harq_process->round  = 0;
+      harq_process->DLround  = 0;
       harq_process->ack = 1;
 
       //LOG_D(PHY,"[UE %d] DLSCH: Setting ACK for SFN/SF %d/%d (pid %d, status %d, round %d, TBS %d, mcs %d)\n",
@@ -240,9 +237,9 @@ bool nr_ue_postDecode(PHY_VARS_NR_UE *phy_vars_ue, notifiedFIFO_elt_t *req, bool
       //LOG_D(PHY,"[UE %d] DLSCH: Setting NAK for SFN/SF %d/%d (pid %d, status %d, round %d, TBS %d, mcs %d) Kr %d r %d harq_process->round %d\n",
       //      phy_vars_ue->Mod_id, frame, nr_slot_rx, harq_pid,harq_process->status, harq_process->round,harq_process->TBS,harq_process->mcs,Kr,r,harq_process->round);
       harq_process->ack = 0;
-      if (harq_process->round >= dlsch->Mlimit) {
+      if (harq_process->DLround >= dlsch->Mlimit) {
         harq_process->status = SCH_IDLE;
-        harq_process->round  = 0;
+        harq_process->DLround  = 0;
         phy_vars_ue->dl_stats[4]++;
       }
 
@@ -299,134 +296,130 @@ void nr_processDLSegment(void* arg) {
   K_bits_F = Kr-harq_process->F;
 
   t_nrLDPC_time_stats procTime = {0};
-  t_nrLDPC_time_stats* p_procTime     = &procTime ;
-
-  t_nrLDPC_procBuf **p_nrLDPC_procBuf = harq_process->p_nrLDPC_procBuf;
-
-
-    int16_t w[5*8448];
-    memset(w,0,(5*8448)*sizeof(short));
-
-    start_meas(&rdata->ts_deinterleave);
-
-    //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_DEINTERLEAVING, VCD_FUNCTION_IN);
-    nr_deinterleaving_ldpc(E,
-                           Qm,
-                           w, // [hna] w is e
-                           dlsch_llr+r_offset);
-    //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_DEINTERLEAVING, VCD_FUNCTION_OUT);
-    stop_meas(&rdata->ts_deinterleave);
-
-    start_meas(&rdata->ts_rate_unmatch);
-    /* LOG_D(PHY,"HARQ_PID %d Rate Matching Segment %d (coded bits %d,E %d, F %d,unpunctured/repeated bits %d, TBS %d, mod_order %d, nb_rb %d, Nl %d, rv %d, round %d)...\n",
-          harq_pid,r, G,E,harq_process->F,
-          Kr*3,
-          harq_process->TBS,
-          Qm,
-          harq_process->nb_rb,
-          harq_process->Nl,
-          harq_process->rvidx,
-          harq_process->round); */
-    //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_RATE_MATCHING, VCD_FUNCTION_IN);
-
-    if (nr_rate_matching_ldpc_rx(Ilbrm,
-                                 Tbslbrm,
-                                 p_decoderParms->BG,
-                                 p_decoderParms->Z,
-                                 harq_process->d[r],
-                                 w,
-                                 harq_process->C,
-                                 harq_process->rvidx,
-                                 (harq_process->first_rx==1)?1:0,
-                                 E,
-                                 harq_process->F,
-                                 Kr-harq_process->F-2*(p_decoderParms->Z))==-1) {
-      //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_RATE_MATCHING, VCD_FUNCTION_OUT);
-      stop_meas(&rdata->ts_rate_unmatch);
-      LOG_E(PHY,"dlsch_decoding.c: Problem in rate_matching\n");
-      rdata->decodeIterations = dlsch->max_ldpc_iterations + 1;
-      return;
-    }
-    stop_meas(&rdata->ts_rate_unmatch);
 
-    r_offset += E;
 
-    if (LOG_DEBUGFLAG(DEBUG_DLSCH_DECOD)) {
-      LOG_D(PHY,"decoder input(segment %u) :",r);
 
-      for (int i=0; i<E; i++)
-        LOG_D(PHY,"%d : %d\n",i,harq_process->d[r][i]);
+  start_meas(&rdata->ts_deinterleave);
+
+  //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_DEINTERLEAVING, VCD_FUNCTION_IN);
+    int16_t w[E];
+    memset(w, 0, sizeof(w));
+  nr_deinterleaving_ldpc(E,
+                         Qm,
+                         w, // [hna] w is e
+                         dlsch_llr+r_offset);
+  //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_DEINTERLEAVING, VCD_FUNCTION_OUT);
+  stop_meas(&rdata->ts_deinterleave);
+
+  start_meas(&rdata->ts_rate_unmatch);
+  /* LOG_D(PHY,"HARQ_PID %d Rate Matching Segment %d (coded bits %d,E %d, F %d,unpunctured/repeated bits %d, TBS %d, mod_order %d, nb_rb %d, Nl %d, rv %d, round %d)...\n",
+        harq_pid,r, G,E,harq_process->F,
+        Kr*3,
+        harq_process->TBS,
+        Qm,
+        harq_process->nb_rb,
+        harq_process->Nl,
+        harq_process->rvidx,
+        harq_process->round); */
+  //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_RATE_MATCHING, VCD_FUNCTION_IN);
+
+  if (nr_rate_matching_ldpc_rx(Ilbrm,
+                               Tbslbrm,
+                               p_decoderParms->BG,
+                               p_decoderParms->Z,
+                               harq_process->d[r],
+                               w,
+                               harq_process->C,
+                               harq_process->rvidx,
+                               (harq_process->first_rx==1)?1:0,
+                               E,
+                               harq_process->F,
+                               Kr-harq_process->F-2*(p_decoderParms->Z))==-1) {
+    //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_RATE_MATCHING, VCD_FUNCTION_OUT);
+    stop_meas(&rdata->ts_rate_unmatch);
+    LOG_E(PHY,"dlsch_decoding.c: Problem in rate_matching\n");
+    rdata->decodeIterations = dlsch->max_ldpc_iterations + 1;
+    return;
+  }
+  stop_meas(&rdata->ts_rate_unmatch);
 
-      LOG_D(PHY,"\n");
-    }
+  r_offset += E;
 
-    memset(harq_process->c[r],0,Kr_bytes);
+  if (LOG_DEBUGFLAG(DEBUG_DLSCH_DECOD)) {
+    LOG_D(PHY,"decoder input(segment %u) :",r);
 
-    if (harq_process->C == 1) {
-      if (A > NR_MAX_PDSCH_TBS)
-        crc_type = CRC24_A;
-      else
-        crc_type = CRC16;
+    for (int i=0; i<E; i++)
+      LOG_D(PHY,"%d : %d\n",i,harq_process->d[r][i]);
 
-      length_dec = harq_process->B;
-    } else {
-      crc_type = CRC24_B;
-      length_dec = (harq_process->B+24*harq_process->C)/harq_process->C;
-    }
+    LOG_D(PHY,"\n");
+  }
 
-    {
-      start_meas(&rdata->ts_ldpc_decode);
-      //set first 2*Z_c bits to zeros
-      memset(&z[0],0,2*harq_process->Z*sizeof(int16_t));
-      //set Filler bits
-      memset((&z[0]+K_bits_F),127,harq_process->F*sizeof(int16_t));
-      //Move coded bits before filler bits
-      memcpy((&z[0]+2*harq_process->Z),harq_process->d[r],(K_bits_F-2*harq_process->Z)*sizeof(int16_t));
-      //skip filler bits
-      memcpy((&z[0]+Kr),harq_process->d[r]+(Kr-2*harq_process->Z),(kc*harq_process->Z-Kr)*sizeof(int16_t));
-
-      //Saturate coded bits before decoding into 8 bits values
-      for (i=0, j=0; j < ((kc*harq_process->Z)>>4)+1;  i+=2, j++) {
-        pl[j] = _mm_packs_epi16(pv[i],pv[i+1]);
-      }
+  memset(harq_process->c[r],0,Kr_bytes);
 
-      //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_LDPC, VCD_FUNCTION_IN);
-      p_decoderParms->block_length=length_dec;
-      nrLDPC_initcall(p_decoderParms, (int8_t*)&pl[0], llrProcBuf);
-      no_iteration_ldpc = nrLDPC_decoder(p_decoderParms,
-                                         (int8_t *)&pl[0],
-                                         llrProcBuf,
-                                         p_nrLDPC_procBuf[r],
-                                         p_procTime);
-      //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_LDPC, VCD_FUNCTION_OUT);
-
-      // Fixme: correct type is unsigned, but nrLDPC_decoder and all called behind use signed int
-      if (check_crc((uint8_t *)llrProcBuf,length_dec,harq_process->F,crc_type)) {
-        LOG_D(PHY,"Segment %u CRC OK\n",r);
-
-        if (r==0) {
-          for (int i=0; i<10; i++) LOG_D(PHY,"byte %d : %x\n",i,((uint8_t *)llrProcBuf)[i]);
-        }
+  if (harq_process->C == 1) {
+    if (A > NR_MAX_PDSCH_TBS)
+      crc_type = CRC24_A;
+    else
+      crc_type = CRC16;
 
-        //Temporary hack
-        no_iteration_ldpc = dlsch->max_ldpc_iterations;
-        rdata->decodeIterations = no_iteration_ldpc;
-      } else {
-        LOG_D(PHY,"CRC NOT OK\n");
-      }
+    length_dec = harq_process->B;
+  } else {
+    crc_type = CRC24_B;
+    length_dec = (harq_process->B+24*harq_process->C)/harq_process->C;
+  }
 
-      nb_total_decod++;
+  {
+    start_meas(&rdata->ts_ldpc_decode);
+    //set first 2*Z_c bits to zeros
+    memset(&z[0],0,2*harq_process->Z*sizeof(int16_t));
+    //set Filler bits
+    memset((&z[0]+K_bits_F),127,harq_process->F*sizeof(int16_t));
+    //Move coded bits before filler bits
+    memcpy((&z[0]+2*harq_process->Z),harq_process->d[r],(K_bits_F-2*harq_process->Z)*sizeof(int16_t));
+    //skip filler bits
+    memcpy((&z[0]+Kr),harq_process->d[r]+(Kr-2*harq_process->Z),(kc*harq_process->Z-Kr)*sizeof(int16_t));
+
+    //Saturate coded bits before decoding into 8 bits values
+    for (i=0, j=0; j < ((kc*harq_process->Z)>>4)+1;  i+=2, j++) {
+      pl[j] = _mm_packs_epi16(pv[i],pv[i+1]);
+    }
 
-      if (no_iteration_ldpc > dlsch->max_ldpc_iterations) {
-        nb_error_decod++;
+    //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_LDPC, VCD_FUNCTION_IN);
+    p_decoderParms->block_length=length_dec;
+    nrLDPC_initcall(p_decoderParms, (int8_t*)&pl[0], llrProcBuf);
+    no_iteration_ldpc = nrLDPC_decoder(p_decoderParms,
+                                       (int8_t *)&pl[0],
+                                       llrProcBuf,
+                                       &procTime);
+    //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_LDPC, VCD_FUNCTION_OUT);
+
+    // Fixme: correct type is unsigned, but nrLDPC_decoder and all called behind use signed int
+    if (check_crc((uint8_t *)llrProcBuf,length_dec,harq_process->F,crc_type)) {
+      LOG_D(PHY,"Segment %u CRC OK\n",r);
+
+      if (r==0) {
+        for (int i=0; i<10; i++) LOG_D(PHY,"byte %d : %x\n",i,((uint8_t *)llrProcBuf)[i]);
       }
 
-      for (int m=0; m < Kr>>3; m ++) {
-        harq_process->c[r][m]= (uint8_t) llrProcBuf[m];
-      }
+      //Temporary hack
+      no_iteration_ldpc = dlsch->max_ldpc_iterations;
+      rdata->decodeIterations = no_iteration_ldpc;
+    } else {
+      LOG_D(PHY,"CRC NOT OK\n");
+    }
 
-      stop_meas(&rdata->ts_ldpc_decode);
+    nb_total_decod++;
+
+    if (no_iteration_ldpc > dlsch->max_ldpc_iterations) {
+      nb_error_decod++;
     }
+
+    for (int m=0; m < Kr>>3; m ++) {
+      harq_process->c[r][m]= (uint8_t) llrProcBuf[m];
+    }
+
+    stop_meas(&rdata->ts_ldpc_decode);
+  }
 }
 
 uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
@@ -455,8 +448,8 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
   }
 
   // HARQ stats
-  phy_vars_ue->dl_stats[harq_process->round]++;
-  LOG_D(PHY,"Round %d RV idx %d\n",harq_process->round,harq_process->rvidx);
+  phy_vars_ue->dl_stats[harq_process->DLround]++;
+  LOG_D(PHY,"Round %d RV idx %d\n",harq_process->DLround,harq_process->rvidx);
   uint8_t kc;
   uint32_t Tbslbrm;// = 950984;
   uint16_t nb_rb;// = 30;
@@ -509,7 +502,7 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
   }
   */
   nb_rb = harq_process->nb_rb;
-  harq_process->trials[harq_process->round]++;
+  harq_process->trials[harq_process->DLround]++;
   uint16_t nb_rb_oh = 0; // it was not computed at UE side even before and set to 0 in nr_compute_tbs
   harq_process->TBS = nr_compute_tbs(harq_process->Qm,harq_process->R,nb_rb,nb_symb_sch,nb_re_dmrs*dmrs_length, nb_rb_oh, 0, harq_process->Nl);
   A = harq_process->TBS;
diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c
index 69eccaf02e7c541c826a1d99a5c1c4a0faa97d68..9cedc333569b4f3d86275135bc1d2018abb4db99 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c
@@ -117,7 +117,6 @@ static int nr_dlsch_llr(NR_UE_PDSCH **pdsch_vars,
                         unsigned char first_symbol_flag,
                         unsigned char symbol,
                         unsigned short nb_rb,
-                        unsigned short round,
                         int32_t codeword_TB0,
                         int32_t codeword_TB1,
                         uint32_t len,
@@ -154,7 +153,6 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
 
   unsigned char aatx=0,aarx=0;
 
-  unsigned short round;
   int avgs = 0;// rb;
   NR_DL_UE_HARQ_t *dlsch0_harq, *dlsch1_harq = NULL;
 
@@ -278,8 +276,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
   nb_rb_pdsch =  dlsch0_harq->nb_rb;
 
   DevAssert(dlsch0_harq);
-  round = dlsch0_harq->round;
-  //printf("round = %d\n", round);
+
 
   if (gNB_id > 2) {
     LOG_W(PHY, "In %s: Illegal gNB_id %d\n", __FUNCTION__, gNB_id);
@@ -522,7 +519,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
                      rx_type, harq_pid,
                      gNB_id, gNB_id_i,
                      first_symbol_flag,
-                     i, nb_rb_pdsch, round,
+                     i, nb_rb_pdsch,
                      codeword_TB0, codeword_TB1,
                      pdsch_vars[gNB_id]->dl_valid_re[i-1],
                      nr_slot_rx, beamforming_mode);
@@ -2479,7 +2476,6 @@ static int nr_dlsch_llr(NR_UE_PDSCH **pdsch_vars,
                         unsigned char first_symbol_flag,
                         unsigned char symbol,
                         unsigned short nb_rb,
-                        unsigned short round,
                         int32_t codeword_TB0,
                         int32_t codeword_TB1,
                         uint32_t len,
diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c b/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c
index ac918b4f3e85e0451f235ac29e729917faebd892..e248ce87cb23ca88ddcf34a506be282e61d46b32 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c
@@ -101,7 +101,7 @@ void free_list(NR_UE_SSB *node) {
 }
 
 
-int nr_pbch_detection(UE_nr_rxtx_proc_t * proc, PHY_VARS_NR_UE *ue, int pbch_initial_symbol)
+int nr_pbch_detection(UE_nr_rxtx_proc_t * proc, PHY_VARS_NR_UE *ue, int pbch_initial_symbol, NR_UE_PDCCH_CONFIG *phy_pdcch_config)
 {
   NR_DL_FRAME_PARMS *frame_parms=&ue->frame_parms;
   int ret =-1;
@@ -146,23 +146,27 @@ int nr_pbch_detection(UE_nr_rxtx_proc_t * proc, PHY_VARS_NR_UE *ue, int pbch_ini
 
     start_meas(&ue->dlsch_channel_estimation_stats);
   // computing channel estimation for selected best ssb
-    const int estimateSz=7*2*frame_parms->ofdm_symbol_size;
+    const int estimateSz = frame_parms->symbols_per_slot * frame_parms->ofdm_symbol_size;
     __attribute__ ((aligned(32))) struct complex16 dl_ch_estimates[frame_parms->nb_antennas_rx][estimateSz];
-    __attribute__ ((aligned(32))) struct complex16 dl_ch_estimates_time[frame_parms->nb_antennas_rx][estimateSz];
+    __attribute__ ((aligned(32))) struct complex16 dl_ch_estimates_time[frame_parms->nb_antennas_rx][frame_parms->ofdm_symbol_size];
+
     for(int i=pbch_initial_symbol; i<pbch_initial_symbol+3;i++)
       nr_pbch_channel_estimation(ue,estimateSz, dl_ch_estimates, dl_ch_estimates_time, 
                                  proc,0,0,i,i-pbch_initial_symbol,temp_ptr->i_ssb,temp_ptr->n_hf);
+
     stop_meas(&ue->dlsch_channel_estimation_stats);
     fapiPbch_t result;
     ret = nr_rx_pbch(ue,
                      proc,
-                     estimateSz, dl_ch_estimates,
-		     ue->pbch_vars[0],
+                     estimateSz,
+                     dl_ch_estimates,
+                     ue->pbch_vars[0],
                      frame_parms,
                      0,
                      temp_ptr->i_ssb,
                      SISO,
-		     &result);
+                     phy_pdcch_config,
+                     &result);
 
     temp_ptr=temp_ptr->next_ssb;
   }
@@ -212,6 +216,8 @@ int nr_initial_sync(UE_nr_rxtx_proc_t *proc,
   NR_DL_FRAME_PARMS *fp = &ue->frame_parms;
   int ret=-1;
   int rx_power=0; //aarx,
+
+  NR_UE_PDCCH_CONFIG phy_pdcch_config={0};
   
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_NR_INITIAL_UE_SYNC, VCD_FUNCTION_IN);
 
@@ -302,7 +308,7 @@ int nr_initial_sync(UE_nr_rxtx_proc_t *proc,
 #endif
 
       int freq_offset_sss = 0;
-      rx_sss_nr(ue, proc, &metric_tdd_ncp, &phase_tdd_ncp, &freq_offset_sss);
+      ret = rx_sss_nr(ue, proc, &metric_tdd_ncp, &phase_tdd_ncp, &freq_offset_sss);
 
       accumulated_freq_offset += freq_offset_sss;
 
@@ -330,8 +336,10 @@ int nr_initial_sync(UE_nr_rxtx_proc_t *proc,
         }
       }
 
-      nr_gold_pbch(ue);
-      ret = nr_pbch_detection(proc, ue, 1);  // start pbch detection at first symbol after pss
+      if (ret==0) { //we got sss channel
+        nr_gold_pbch(ue);
+        ret = nr_pbch_detection(proc, ue, 1, &phy_pdcch_config);  // start pbch detection at first symbol after pss
+      }
 
       if (ret == 0) {
         // sync at symbol ue->symbol_offset
@@ -349,15 +357,17 @@ int nr_initial_sync(UE_nr_rxtx_proc_t *proc,
         nr_gold_pdcch(ue,fp->Nid_cell);
 
         // compute the scrambling IDs for PDSCH DMRS
-        for (int i=0; i<2; i++)
-          ue->scramblingID[i]=fp->Nid_cell;
-
-        nr_gold_pdsch(ue,ue->scramblingID);
+        for (int i=0; i<NR_NB_NSCID; i++) {
+          ue->scramblingID_dlsch[i]=fp->Nid_cell;
+          nr_gold_pdsch(ue, i, ue->scramblingID_dlsch[i]);
+        }
 
         // initialize the pusch dmrs
-        uint16_t N_n_scid[2] = {fp->Nid_cell,fp->Nid_cell};
-        int n_scid = 0; // This quantity is indicated by higher layer parameter dmrs-SeqInitialization
-        nr_init_pusch_dmrs(ue, N_n_scid, n_scid);
+        for (int i=0; i<NR_NB_NSCID; i++) {
+          ue->scramblingID_ulsch[i]=fp->Nid_cell;
+          nr_init_pusch_dmrs(ue, ue->scramblingID_ulsch[i], i);
+        }
+
 
         // we also need to take into account the shift by samples_per_frame in case the if is true
         if (ue->ssb_offset < sync_pos_frame){
@@ -526,33 +536,40 @@ int nr_initial_sync(UE_nr_rxtx_proc_t *proc,
   // if stand alone and sync on ssb do sib1 detection as part of initial sync
   if (sa==1 && ret==0) {
     bool dec = false;
-    NR_UE_PDCCH *pdcch_vars  = ue->pdcch_vars[proc->thread_id][0];
     int gnb_id = 0; //FIXME
     int coreset_nb_rb=0;
     int coreset_start_rb=0;
 
-    for(int n_ss = 0; n_ss<pdcch_vars->nb_search_space; n_ss++) {
-      uint8_t nb_symb_pdcch = pdcch_vars->pdcch_config[n_ss].coreset.duration;
-      int start_symb = pdcch_vars->pdcch_config[n_ss].coreset.StartSymbolIndex;
-      get_coreset_rballoc(pdcch_vars->pdcch_config[n_ss].coreset.frequency_domain_resource,&coreset_nb_rb,&coreset_start_rb);
+    // Hold the channel estimates in frequency domain.
+    int32_t pdcch_est_size = ((((fp->symbols_per_slot*(fp->ofdm_symbol_size+LTE_CE_FILTER_LENGTH))+15)/16)*16);
+    __attribute__ ((aligned(16))) int32_t pdcch_dl_ch_estimates[4*fp->nb_antennas_rx][pdcch_est_size];
+
+
+    for(int n_ss = 0; n_ss<phy_pdcch_config.nb_search_space; n_ss++) {
+      uint8_t nb_symb_pdcch = phy_pdcch_config.pdcch_config[n_ss].coreset.duration;
+      int start_symb = phy_pdcch_config.pdcch_config[n_ss].coreset.StartSymbolIndex;
+      get_coreset_rballoc(phy_pdcch_config.pdcch_config[n_ss].coreset.frequency_domain_resource,&coreset_nb_rb,&coreset_start_rb);
       for (uint16_t l=start_symb; l<start_symb+nb_symb_pdcch; l++) {
         nr_slot_fep_init_sync(ue,
                               proc,
                               l, // the UE PHY has no notion of the symbols to be monitored in the search space
-                              pdcch_vars->slot,
-                              is*fp->samples_per_frame+pdcch_vars->sfn*fp->samples_per_frame+ue->rx_offset);
+                              phy_pdcch_config.slot,
+                              is*fp->samples_per_frame+phy_pdcch_config.sfn*fp->samples_per_frame+ue->rx_offset);
 
         if (coreset_nb_rb > 0)
           nr_pdcch_channel_estimation(ue,
                                       proc,
                                       0,
-                                      pdcch_vars->slot,
+                                      phy_pdcch_config.slot,
                                       l,
-                                      fp->first_carrier_offset+(pdcch_vars->pdcch_config[n_ss].BWPStart + coreset_start_rb)*12,
-                                      coreset_nb_rb);
+                                      fp->Nid_cell,
+                                      fp->first_carrier_offset+(phy_pdcch_config.pdcch_config[n_ss].BWPStart + coreset_start_rb)*12,
+                                      coreset_nb_rb,
+                                      pdcch_est_size,
+                                      pdcch_dl_ch_estimates);
 
       }
-      int  dci_cnt = nr_ue_pdcch_procedures(gnb_id, ue, proc, n_ss);
+      int  dci_cnt = nr_ue_pdcch_procedures(gnb_id, ue, proc, pdcch_est_size, pdcch_dl_ch_estimates, &phy_pdcch_config, n_ss);
       if (dci_cnt>0){
         NR_UE_DLSCH_t *dlsch = ue->dlsch_SI[gnb_id];
         if (dlsch && (dlsch->active == 1)) {
@@ -565,8 +582,8 @@ int nr_initial_sync(UE_nr_rxtx_proc_t *proc,
             nr_slot_fep_init_sync(ue,
                                   proc,
                                   m,
-                                  pdcch_vars->slot,  // same slot and offset as pdcch
-                                  is*fp->samples_per_frame+pdcch_vars->sfn*fp->samples_per_frame+ue->rx_offset);
+                                  phy_pdcch_config.slot,  // same slot and offset as pdcch
+                                  is*fp->samples_per_frame+phy_pdcch_config.sfn*fp->samples_per_frame+ue->rx_offset);
           }
 
           int ret = nr_ue_pdsch_procedures(ue,
diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c b/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c
index 2705132bc6adccc1aa917766c1ef5c9232d429e0..48b08d761ece8f76e29eb3f1e737f8a686ac4393 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c
@@ -391,6 +391,7 @@ int nr_rx_pbch( PHY_VARS_NR_UE *ue,
                 uint8_t gNB_id,
                 uint8_t i_ssb,
                 MIMO_mode_t mimo_mode,
+                NR_UE_PDCCH_CONFIG *phy_pdcch_config,
                 fapiPbch_t *result) {
   NR_UE_COMMON *nr_ue_common_vars = &ue->common_vars;
   int max_h=0;
@@ -577,7 +578,8 @@ int nr_rx_pbch( PHY_VARS_NR_UE *ue,
   nr_downlink_indication_t dl_indication;
   fapi_nr_rx_indication_t *rx_ind=calloc(sizeof(*rx_ind),1);
   uint16_t number_pdus = 1;
-  nr_fill_dl_indication(&dl_indication, NULL, rx_ind, proc, ue, gNB_id);
+
+  nr_fill_dl_indication(&dl_indication, NULL, rx_ind, proc, ue, gNB_id, phy_pdcch_config);
   nr_fill_rx_indication(rx_ind, FAPI_NR_RX_PDU_TYPE_SSB, gNB_id, ue, NULL, NULL, number_pdus, proc,(void *)result);
 
   if (ue->if_inst && ue->if_inst->dl_indication)
diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h
index e1df279abf47f7c5935bcef0e0a7d3e102e23419..4491f9dc0f5d8f1041ae3ce954d1cbd7544645aa 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h
@@ -1076,6 +1076,9 @@ uint32_t dlsch_decoding_emul(PHY_VARS_NR_UE *phy_vars_ue,
 
 int32_t nr_rx_pdcch(PHY_VARS_NR_UE *ue,
                     UE_nr_rxtx_proc_t *proc,
+                    int32_t pdcch_est_size,
+                    int32_t pdcch_dl_ch_estimates[][pdcch_est_size],
+                    int16_t *pdcch_e_rx,
                     fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15);
 
 
@@ -1130,11 +1133,13 @@ int nr_rx_pbch( PHY_VARS_NR_UE *ue,
                 uint8_t eNB_id,
                 uint8_t i_ssb,
                 MIMO_mode_t mimo_mode,
-		fapiPbch_t* result);
+                NR_UE_PDCCH_CONFIG *phy_pdcch_config,
+                fapiPbch_t* result);
 
 int nr_pbch_detection(UE_nr_rxtx_proc_t *proc,
-		      PHY_VARS_NR_UE *ue,
-                      int pbch_initial_symbol);
+		              PHY_VARS_NR_UE *ue,
+                      int pbch_initial_symbol,
+                      NR_UE_PDCCH_CONFIG *phy_pdcch_config);
 
 uint16_t rx_pbch_emul(PHY_VARS_NR_UE *phy_vars_ue,
                       uint8_t eNB_id,
@@ -1451,16 +1456,6 @@ uint64_t cqi2hex(uint32_t cqi);
 
 uint16_t computeRIV(uint16_t N_RB_DL,uint16_t RBstart,uint16_t Lcrbs);
 
-
-/** \brief  This routine extracts a single subband PMI from a bitmap coming from UCI or the pmi_extend function
-    @param N_RB_DL number of resource blocks
-    @param mimo_mode
-    @param pmi_alloc subband PMI bitmap
-    @param rb resource block for which to extract PMI
-    @returns subband PMI
-*/
-uint8_t get_pmi(uint8_t N_RB_DL,MIMO_mode_t mode, uint32_t pmi_alloc,uint16_t rb);
-
 int get_nCCE_offset_l1(int *CCE_table,
                        const unsigned char L,
                        const int nCCE,
@@ -1562,7 +1557,7 @@ uint8_t get_num_prach_tdd(module_id_t Mod_id);
   @param frame_type 0-FDD, 1-TDD
   @returns 0-1 accordingly
 */
-uint8_t get_prach_fmt(uint8_t prach_ConfigIndex,lte_frame_type_t frame_type);
+uint8_t get_prach_fmt(uint8_t prach_ConfigIndex,frame_type_t frame_type);
 
 /*!
   \brief Helper for MAC, returns frequency index of PRACH resource in TDD for a particular configuration index
@@ -1584,7 +1579,7 @@ void compute_prach_seq(uint16_t rootSequenceIndex,
 		       uint8_t prach_ConfigIndex,
 		       uint8_t zeroCorrelationZoneConfig,
 		       uint8_t highSpeedFlag,
-		       lte_frame_type_t frame_type,
+		       frame_type_t frame_type,
 		       uint32_t X_u[64][839]);
 
 
@@ -1640,8 +1635,10 @@ uint8_t get_prach_prb_offset(NR_DL_FRAME_PARMS *frame_parms,
 
 uint8_t nr_dci_decoding_procedure(PHY_VARS_NR_UE *ue,
                                   UE_nr_rxtx_proc_t *proc,
+                                  int16_t *pdcch_e_rx,
                                   fapi_nr_dci_indication_t *dci_ind,
-                                  fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15);
+                                  fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15,
+                                  NR_UE_PDCCH_CONFIG *phy_pdcch_config);
 
 
 /** \brief This function is the top-level entry point to PDSCH demodulation, after frequency-domain transformation and channel estimation.  It performs
diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h
index f76119250f5164a8c2859ce0a7bc926fe9fc283a..4086f60f02e956f5f2fe4c10bea0f5f9a7cbbf8b 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h
@@ -181,9 +181,10 @@ typedef struct {
   /// Pointers to transport block segments
   uint8_t **c;
   /// soft bits for each received segment ("d"-sequence)(for definition see 36-212 V8.6 2009-03, p.15)
+  /// Accumulates the soft bits for each round to increase decoding success (HARQ)
   int16_t **d;
   /// Index of current HARQ round for this DLSCH
-  uint8_t round;
+  uint8_t DLround;
   /// MCS table for this DLSCH
   uint8_t mcs_table;
   /// MCS format for this DLSCH
@@ -196,8 +197,6 @@ typedef struct {
   uint8_t rvidx;
   /// MIMO mode for this DLSCH
   MIMO_nrmode_t mimo_mode;
-  /// LDPC processing buffers
-  t_nrLDPC_procBuf **p_nrLDPC_procBuf;
   /// Number of code segments 
   uint32_t C;
   /// Number of bits in code segments
@@ -261,6 +260,8 @@ typedef struct {
   uint16_t ptrs_symbols;
   // PTRS symbol index, to be updated every PTRS symbol within a slot.
   uint8_t ptrs_symbol_index;
+  uint8_t nscid;
+  uint16_t dlDmrsScramblingId;
   /// PDU BITMAP 
   uint16_t pduBitmap;
 } NR_DL_UE_HARQ_t;
diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c
index 802cb55e03445dcd26ce7c17f3272022efb85c3f..bab0c75aff198ee80778f809d62c3de80eb43ca9 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c
@@ -32,6 +32,7 @@
 #include <stdint.h>
 #include "PHY/NR_REFSIG/dmrs_nr.h"
 #include "PHY/NR_REFSIG/ptrs_nr.h"
+#include "PHY/NR_REFSIG/refsig_defs_ue.h"
 #include "PHY/NR_UE_TRANSPORT/nr_transport_ue.h"
 #include "PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h"
 #include "PHY/MODULATION/nr_modulation.h"
@@ -215,9 +216,16 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
 
   /////////////////////////DMRS Modulation/////////////////////////
   ///////////
-  uint32_t **pusch_dmrs = UE->nr_gold_pusch_dmrs[slot];
+
+  if(pusch_pdu->ul_dmrs_scrambling_id != UE->scramblingID_ulsch[pusch_pdu->scid])  {
+    UE->scramblingID_ulsch[pusch_pdu->scid] = pusch_pdu->ul_dmrs_scrambling_id;
+    nr_init_pusch_dmrs(UE, pusch_pdu->scid, pusch_pdu->ul_dmrs_scrambling_id);
+  }
+
+  uint32_t ***pusch_dmrs = UE->nr_gold_pusch_dmrs[slot];
   uint16_t n_dmrs = (pusch_pdu->bwp_start + start_rb + nb_rb)*((dmrs_type == pusch_dmrs_type1) ? 6:4);
   int16_t mod_dmrs[n_dmrs<<1] __attribute((aligned(16)));
+
   ///////////
   ////////////////////////////////////////////////////////////////////////
 
@@ -382,7 +390,7 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
           // TODO: performance improvement, we can skip the modulation of DMRS symbols outside the bandwidth part
           // Perform this on gold sequence, not required when SC FDMA operation is done,
           LOG_D(PHY,"DMRS in symbol %d\n",l);
-          nr_modulation(pusch_dmrs[l], n_dmrs*2, DMRS_MOD_ORDER, mod_dmrs); // Qm = 2 as DMRS is QPSK modulated
+          nr_modulation(pusch_dmrs[l][pusch_pdu->scid], n_dmrs*2, DMRS_MOD_ORDER, mod_dmrs); // currently only codeword 0 is modulated. Qm = 2 as DMRS is QPSK modulated
         } else {
           dmrs_idx = 0;
         }
@@ -392,7 +400,7 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
 
         if(is_ptrs_symbol(l, ulsch_ue->ptrs_symbols)) {
           is_ptrs_sym = 1;
-          nr_modulation(pusch_dmrs[l], nb_rb, DMRS_MOD_ORDER, mod_ptrs);
+          nr_modulation(pusch_dmrs[l][pusch_pdu->scid], nb_rb, DMRS_MOD_ORDER, mod_ptrs);
         }
       }
 
diff --git a/openair1/PHY/NR_UE_TRANSPORT/pss_nr.c b/openair1/PHY/NR_UE_TRANSPORT/pss_nr.c
index 54712cb64e5b72cec804638c1592d6edfa4f6b99..13ed436273ee9d0f79ee8b308b6596873c559dd8 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/pss_nr.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/pss_nr.c
@@ -381,7 +381,6 @@ void init_context_pss_nr(NR_DL_FRAME_PARMS *frame_parms_ue)
   int sizePss = LENGTH_PSS_NR * IQ_SIZE;  /* complex value i & q signed 16 bits */
   int size = ofdm_symbol_size * IQ_SIZE; /* i and q samples signed 16 bits */
   int16_t *p = NULL;
-  int64_t *q = NULL;
 
   AssertFatal(ofdm_symbol_size > 127, "illegal ofdm_symbol_size %d\n",ofdm_symbol_size);
   for (int i = 0; i < NUMBER_PSS_SEQUENCE; i++) {
@@ -410,17 +409,6 @@ void init_context_pss_nr(NR_DL_FRAME_PARMS *frame_parms_ue)
      assert(0);
     }
 
-    size = sizeof(int64_t)*(frame_parms_ue->samples_per_frame + (2*ofdm_symbol_size));
-    q = (int64_t*)malloc16(size);
-    if (q != NULL) {
-      pss_corr_ue[i] = q;
-      bzero( pss_corr_ue[i], size);
-    }
-    else {
-      LOG_E(PHY,"Fatal memory allocation problem \n");
-      assert(0);
-    }
-
     generate_pss_nr(frame_parms_ue,i);
   }
 }
@@ -443,7 +431,6 @@ void free_context_pss_nr(void)
     free_and_zero(primary_synchro_nr[i]);
     free_and_zero(primary_synchro_nr2[i]);
     free_and_zero(primary_synchro_time_nr[i]);
-    free_and_zero(pss_corr_ue[i]);
   }
 }
 
@@ -801,7 +788,6 @@ static inline double angle64(int64_t x)
 *********************************************************************/
 
 #define DOT_PRODUCT_SCALING_SHIFT    (17)
-
 int pss_search_time_nr(int **rxdata, ///rx data in time domain
                        NR_DL_FRAME_PARMS *frame_parms,
 		       int fo_flag,
@@ -812,7 +798,7 @@ int pss_search_time_nr(int **rxdata, ///rx data in time domain
   unsigned int n, ar, peak_position, pss_source;
   int64_t peak_value;
   int64_t result;
-  int64_t avg[NUMBER_PSS_SEQUENCE];
+  int64_t avg[NUMBER_PSS_SEQUENCE]={0};
   double ffo_est=0;
 
   // performing the correlation on a frame length plus one symbol for the first of the two frame
@@ -823,9 +809,8 @@ int pss_search_time_nr(int **rxdata, ///rx data in time domain
   else
     length = frame_parms->samples_per_frame;
 
-  AssertFatal(length>0,"illegal length %d\n",length);
-  for (int i = 0; i < NUMBER_PSS_SEQUENCE; i++) AssertFatal(pss_corr_ue[i] != NULL,"pss_corr_ue[%d] not yet allocated! Exiting.\n", i);
 
+  AssertFatal(length>0,"illegal length %d\n",length);
   peak_value = 0;
   peak_position = 0;
   pss_source = 0;
@@ -846,47 +831,41 @@ int pss_search_time_nr(int **rxdata, ///rx data in time domain
   /* Correlation computation is based on a a dot product which is realized thank to SIMS extensions */
 
   for (int pss_index = 0; pss_index < NUMBER_PSS_SEQUENCE; pss_index++) {
-    avg[pss_index]=0;
-    memset(pss_corr_ue[pss_index],0,length*sizeof(int64_t)); 
-  }
-
-  for (n=0; n < length; n+=4) { //
 
-    for (int pss_index = 0; pss_index < NUMBER_PSS_SEQUENCE; pss_index++) {
+    for (n=0; n < length; n+=4) { //
 
-      if ( n < (length - frame_parms->ofdm_symbol_size)) {
+      int64_t pss_corr_ue=0;
+      /* calculate dot product of primary_synchro_time_nr and rxdata[ar][n]
+       * (ar=0..nb_ant_rx) and store the sum in temp[n]; */
+      for (ar=0; ar<frame_parms->nb_antennas_rx; ar++) {
 
-        /* calculate dot product of primary_synchro_time_nr and rxdata[ar][n] (ar=0..nb_ant_rx) and store the sum in temp[n]; */
-        for (ar=0; ar<frame_parms->nb_antennas_rx; ar++) {
-
-          /* perform correlation of rx data and pss sequence ie it is a dot product */
-          result  = dot_product64((short*)primary_synchro_time_nr[pss_index], 
-				  (short*)&(rxdata[ar][n+is*frame_parms->samples_per_frame]), 
-				  frame_parms->ofdm_symbol_size, 
-				  shift);
-	  pss_corr_ue[pss_index][n] += abs64(result);
-          //((short*)pss_corr_ue[pss_index])[2*n] += ((short*) &result)[0];   /* real part */
-          //((short*)pss_corr_ue[pss_index])[2*n+1] += ((short*) &result)[1]; /* imaginary part */
-          //((short*)&synchro_out)[0] += ((int*) &result)[0];               /* real part */
-          //((short*)&synchro_out)[1] += ((int*) &result)[1];               /* imaginary part */
+        /* perform correlation of rx data and pss sequence ie it is a dot product */
+        result  = dot_product64((short*)primary_synchro_time_nr[pss_index],
+                                (short*)&(rxdata[ar][n+is*frame_parms->samples_per_frame]),
+                                frame_parms->ofdm_symbol_size,
+                                shift);
+        pss_corr_ue += abs64(result);
+        //((short*)pss_corr_ue[pss_index])[2*n] += ((short*) &result)[0];   /* real part */
+        //((short*)pss_corr_ue[pss_index])[2*n+1] += ((short*) &result)[1]; /* imaginary part */
+        //((short*)&synchro_out)[0] += ((int*) &result)[0];               /* real part */
+        //((short*)&synchro_out)[1] += ((int*) &result)[1];               /* imaginary part */
 
-        }
       }
- 
+      
       /* calculate the absolute value of sync_corr[n] */
-      avg[pss_index]+=pss_corr_ue[pss_index][n];
-      if (pss_corr_ue[pss_index][n] > peak_value) {
-        peak_value = pss_corr_ue[pss_index][n];
+      avg[pss_index]+=pss_corr_ue;
+      if (pss_corr_ue > peak_value) {
+        peak_value = pss_corr_ue;
         peak_position = n;
         pss_source = pss_index;
-
+        
 #ifdef DEBUG_PSS_NR
-        printf("pss_index %d: n %6u peak_value %15llu\n", pss_index, n, (unsigned long long)pss_corr_ue[pss_index][n]);
+        printf("pss_index %d: n %6u peak_value %15llu\n", pss_index, n, (unsigned long long)pss_corr_ue[n]);
 #endif
       }
     }
   }
-
+  
   if (fo_flag){
 
 	  // fractional frequency offset computation according to Cross-correlation Synchronization Algorithm Using PSS
@@ -922,7 +901,8 @@ int pss_search_time_nr(int **rxdata, ///rx data in time domain
   // computing absolute value of frequency offset
   *f_off = ffo_est*frame_parms->subcarrier_spacing;  
 
-  for (int pss_index = 0; pss_index < NUMBER_PSS_SEQUENCE; pss_index++) avg[pss_index]/=(length/4);
+  for (int pss_index = 0; pss_index < NUMBER_PSS_SEQUENCE; pss_index++)
+    avg[pss_index]/=(length/4);
 
   *eNB_id = pss_source;
 
@@ -937,9 +917,6 @@ int pss_search_time_nr(int **rxdata, ///rx data in time domain
   static int debug_cnt = 0;
 
   if (debug_cnt == 0) {
-    LOG_M("pss_corr_ue0.m","pss_corr_ue0",pss_corr_ue[0],length,1,6);
-    LOG_M("pss_corr_ue1.m","pss_corr_ue1",pss_corr_ue[1],length,1,6);
-    LOG_M("pss_corr_ue2.m","pss_corr_ue2",pss_corr_ue[2],length,1,6);
     if (is)
       LOG_M("rxdata1.m","rxd0",rxdata[frame_parms->samples_per_frame],length,1,1); 
     else
diff --git a/openair1/PHY/NR_UE_TRANSPORT/sss_nr.c b/openair1/PHY/NR_UE_TRANSPORT/sss_nr.c
index dc73fe0add1226bfaeff3d433ee7d613d9d601ce..ff8d5d42ff803118d1b2650d2044bd1647e3af73 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/sss_nr.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/sss_nr.c
@@ -558,8 +558,15 @@ int rx_sss_nr(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int32_t *tot_metric,
   }
   //#endif
 
+  if (Nid1==N_ID_1_NUMBER)
+    return -1;
+  
   int re = 0;
   int im = 0;
+  if (Nid1 == N_ID_1_NUMBER) {
+    LOG_I(PHY,"Failled to detect SSS after PSS\n");
+    return -1;
+  }
   d = (int16_t *)&d_sss[Nid2][Nid1];
   for(i = 0; i<LENGTH_SSS_NR; i++) {
     re += d[i]*sss[2*i];
diff --git a/openair1/PHY/TOOLS/angle.c b/openair1/PHY/TOOLS/angle.c
index a06640d1cf4a8762121b515c4b78bd9db0c0a42d..89ffc3cb608d1172b324401b21a146d586c2d3b7 100644
--- a/openair1/PHY/TOOLS/angle.c
+++ b/openair1/PHY/TOOLS/angle.c
@@ -29,7 +29,7 @@
 #include "costable.h"
 #include "defs.h"
 
-unsigned int angle(struct complex16 perror)
+unsigned int angle(c16_t perror)
 {
   int a;
 
diff --git a/openair1/PHY/TOOLS/cadd_sv.c b/openair1/PHY/TOOLS/cadd_sv.c
index caa8d1cc04197480ee30483bf544dc03baeb75bf..56dcb718478c25ad843bee62eabfa535e6c11d72 100644
--- a/openair1/PHY/TOOLS/cadd_sv.c
+++ b/openair1/PHY/TOOLS/cadd_sv.c
@@ -129,7 +129,7 @@ main ()
   short output[256] __attribute__((aligned(16)));
 
   int i;
-  struct complex16 alpha;
+  c16_t alpha;
 
   Zero_Buffer(output,256*2);
 
diff --git a/openair1/PHY/TOOLS/cadd_vv.c b/openair1/PHY/TOOLS/cadd_vv.c
index 77346a97f7facdcf1e68a78b7397a709d9af6b12..08bf514cb357b2f032b3922810b0440f2d29cfb0 100644
--- a/openair1/PHY/TOOLS/cadd_vv.c
+++ b/openair1/PHY/TOOLS/cadd_vv.c
@@ -278,7 +278,7 @@ main ()
   short output[256] __attribute__((aligned(16)));
 
   int i;
-  struct complex16 alpha;
+  c16_t alpha;
 
   Zero_Buffer(output,256*2);
 
diff --git a/openair1/PHY/TOOLS/calibration_test.c b/openair1/PHY/TOOLS/calibration_test.c
index 5dced270604cfa0ec5f8b6a40a4886d2758d9021..650d5e420cacfe5d361f947922a6f2dc0b3de098 100644
--- a/openair1/PHY/TOOLS/calibration_test.c
+++ b/openair1/PHY/TOOLS/calibration_test.c
@@ -305,15 +305,15 @@ int main(int argc, char **argv) {
   
   openair0_device_load(&rfdevice,&openair0_cfg);
 
-  void ** samplesRx = (void **)malloc16(antennas* sizeof(struct complex16 *) );
-  void ** samplesTx = (void **)malloc16(antennas* sizeof(struct complex16 *) );
+  void ** samplesRx = (void **)malloc16(antennas* sizeof(c16_t *) );
+  void ** samplesTx = (void **)malloc16(antennas* sizeof(c16_t *) );
 
   int fd=open(getenv("rftestInputFile"),O_RDONLY);
   AssertFatal(fd>=0,"%s",strerror(errno));
   
   for (int i=0; i<antennas; i++) {
-    samplesRx[i] = (int32_t *)malloc16_clear( DFT*sizeof(struct complex16) );
-    samplesTx[i] = (int32_t *)malloc16_clear( DFT*sizeof(struct complex16) );
+    samplesRx[i] = (int32_t *)malloc16_clear( DFT*sizeof(c16_t) );
+    samplesTx[i] = (int32_t *)malloc16_clear( DFT*sizeof(c16_t) );
   }
 
   CalibrationInitScope(samplesRx, &rfdevice);
@@ -322,7 +322,7 @@ int main(int argc, char **argv) {
   
   while(!oai_exit) {
     for (int i=0; i<antennas; i++)
-      read(fd, samplesTx[i], DFT*sizeof(struct complex16));
+      read(fd, samplesTx[i], DFT*sizeof(c16_t));
     int readBlockSize = rfdevice.trx_read_func(&rfdevice,
 					       &timestamp,
 					       samplesRx,
diff --git a/openair1/PHY/TOOLS/dB_routines.h b/openair1/PHY/TOOLS/dB_routines.h
deleted file mode 100644
index 185913cf5b052e0a607a9bdd3abebc7a166a0579..0000000000000000000000000000000000000000
--- a/openair1/PHY/TOOLS/dB_routines.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * 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
- */
-
-/*
- * dB_routines.h
- *
- *  Created on: Nov 12, 2013
- *      Author: winckel
- */
-
-#ifndef DB_ROUTINES_H_
-#define DB_ROUTINES_H_
-
-int16_t dB_fixed_times10(uint32_t x);
-int16_t dB_fixed_x10(uint32_t x);
-
-#endif /* DB_ROUTINES_H_ */
diff --git a/openair1/PHY/TOOLS/nr_phy_scope.c b/openair1/PHY/TOOLS/nr_phy_scope.c
index fe0f785ef4ce44a07ef85f7472329fb2e995f6f0..723813fbb62632ba31b8f82e609a5dc74685174a 100644
--- a/openair1/PHY/TOOLS/nr_phy_scope.c
+++ b/openair1/PHY/TOOLS/nr_phy_scope.c
@@ -37,7 +37,7 @@
 const FL_COLOR rx_antenna_colors[4] = {FL_RED,FL_BLUE,FL_GREEN,FL_YELLOW};
 const FL_COLOR water_colors[4] = {FL_BLUE,FL_GREEN,FL_YELLOW,FL_RED};
 
-typedef struct complex16 scopeSample_t;
+typedef c16_t scopeSample_t;
 #define SquaredNorm(VaR) ((VaR).r*(VaR).r+(VaR).i*(VaR).i)
 
 typedef struct {
@@ -678,52 +678,42 @@ static void uePbchIQ  (scopeGraphData_t **data, OAIgraph_t *graph, PHY_VARS_NR_U
 
 static void uePcchLLR  (scopeGraphData_t **data, OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id) {
   // PDCCH LLRs
-  if (!phy_vars_ue->pdcch_vars[0][eNB_id]->llr)
+  if (!data[pdcchLlr])
     return;
 
   //int num_re = 4*273*12; // 12*frame_parms->N_RB_DL*num_pdcch_symbols
   //int Qm = 2;
-  int coded_bits_per_codeword = 2*4*100*12; //num_re*Qm;
+  const int sz=data[pdcchLlr]->lineSz;
   float *llr, *bit;
-  oai_xygraph_getbuff(graph, &bit, &llr, coded_bits_per_codeword*RX_NB_TH_MAX, 0);
-  int base=0;
+  oai_xygraph_getbuff(graph, &bit, &llr, sz, 0);
 
-  for (int thr=0 ; thr < RX_NB_TH_MAX ; thr ++ ) {
-    int16_t *pdcch_llr = (int16_t *) phy_vars_ue->pdcch_vars[thr][eNB_id]->llr;
-
-    for (int i=0; i<coded_bits_per_codeword; i++) {
-      llr[base+i] = (float) pdcch_llr[i];
-    }
+  int16_t *pdcch_llr = (int16_t *)(data[pdcchLlr]+1);
 
-    base+=coded_bits_per_codeword;
+  for (int i=0; i<sz; i++) {
+    llr[i] = (float) pdcch_llr[i];
   }
 
-  AssertFatal(base <= coded_bits_per_codeword*RX_NB_TH_MAX, "");
-  oai_xygraph(graph,bit,llr,base,0,10);
+  oai_xygraph(graph,bit,llr,sz,0,10);
 }
 static void uePcchIQ  (scopeGraphData_t **data, OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id) {
   // PDCCH I/Q of MF Output
-  if (!phy_vars_ue->pdcch_vars[0][eNB_id]->rxdataF_comp[0])
+  if (!data[pdcchRxdataF_comp])
     return;
 
-  int nb=4*273*12; // 12*frame_parms->N_RB_DL*num_pdcch_symbols
+  const int sz=data[pdcchRxdataF_comp]->lineSz;
+  //const int antennas=data[pdcchRxdataF_comp]->colSz;
+  // We take the first antenna only for now
   float *I, *Q;
-  oai_xygraph_getbuff(graph, &I, &Q, nb*RX_NB_TH_MAX, 0);
-  int base=0;
-
-  for (int thr=0 ; thr < RX_NB_TH_MAX ; thr ++ ) {
-    scopeSample_t *pdcch_comp = (scopeSample_t *) phy_vars_ue->pdcch_vars[thr][eNB_id]->rxdataF_comp[0];
+  oai_xygraph_getbuff(graph, &I, &Q, sz, 0);
 
-    for (int i=0; i< nb; i++) {
-      I[base+i] = pdcch_comp[i].r;
-      Q[base+i] = pdcch_comp[i].i;
-    }
+  scopeSample_t *pdcch_comp = (scopeSample_t *) (data[pdcchRxdataF_comp]+1);
 
-    base+=nb;
+  for (int i=0; i<sz; i++) {
+    I[i] = pdcch_comp[i].r;
+    Q[i] = pdcch_comp[i].i;
   }
 
-  AssertFatal(base <= nb*RX_NB_TH_MAX, "");
-  oai_xygraph(graph,I,Q,base,0,10);
+  oai_xygraph(graph,I,Q,sz,0,10);
 }
 static void uePdschLLR  (scopeGraphData_t **data, OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id) {
   // PDSCH LLRs
@@ -908,7 +898,6 @@ static void *nrUEscopeThread(void *arg) {
   char *name="5G-UE-scope";
   fl_initialize (&fl_argc, &name, NULL, 0, 0);
   OAI_phy_scope_t  *form_nrue=create_phy_scope_nrue(0);
-  (( scopeData_t *)ue->scopeData)->liveData=calloc(sizeof(scopeGraphData_t *), UEdataTypeNumberOfItems);
 
   while (!oai_exit) {
     fl_freeze_form(form_nrue->phy_scope);
@@ -925,28 +914,43 @@ static void *nrUEscopeThread(void *arg) {
 }
 
 void UEcopyData(PHY_VARS_NR_UE *ue, enum UEdataType type, void *dataIn, int elementSz, int colSz, int lineSz) {
+  // Local static copy of the scope data bufs
+  // The active data buf is alterned to avoid interference between the Scope thread (display) and the Rx thread (data input)
+  // Index of "2" could be set to the number of Rx threads + 1
+  static scopeGraphData_t *copyDataBufs[UEdataTypeNumberOfItems][2] = {0};
+  static int  copyDataBufsIdx[UEdataTypeNumberOfItems] = {0};
+
   scopeData_t *tmp=(scopeData_t *)ue->scopeData;
 
   if (tmp) {
-    scopeGraphData_t *live= ((scopeGraphData_t **)tmp->liveData)[type];
+    // Begin of critical zone between UE Rx threads that might copy new data at the same time: might require a mutex
+    int newCopyDataIdx = (copyDataBufsIdx[type]==0)?1:0;
+    copyDataBufsIdx[type] = newCopyDataIdx;
+    // End of critical zone between UE Rx threads
 
-    if (live == NULL || live->dataSize < elementSz*colSz*lineSz) {
-      scopeGraphData_t *ptr=realloc(live, sizeof(scopeGraphData_t) + elementSz*colSz*lineSz);
+    // New data will be copied in a different buffer than the live one
+    scopeGraphData_t *copyData= copyDataBufs[type][newCopyDataIdx];
+
+    if (copyData == NULL || copyData->dataSize < elementSz*colSz*lineSz) {
+      scopeGraphData_t *ptr=realloc(copyData, sizeof(scopeGraphData_t) + elementSz*colSz*lineSz);
 
       if (!ptr) {
         LOG_E(PHY,"can't realloc\n");
         return;
       } else {
-        live=ptr;
+        copyData=ptr;
       }
     }
 
-    live->dataSize=elementSz*colSz*lineSz;
-    live->elementSz=elementSz;
-    live->colSz=colSz;
-    live->lineSz=lineSz;
-    memcpy(live+1, dataIn,  elementSz*colSz*lineSz);
-    ((scopeGraphData_t **)tmp->liveData)[type]=live;
+    copyData->dataSize=elementSz*colSz*lineSz;
+    copyData->elementSz=elementSz;
+    copyData->colSz=colSz;
+    copyData->lineSz=lineSz;
+    memcpy(copyData+1, dataIn,  elementSz*colSz*lineSz);
+    copyDataBufs[type][newCopyDataIdx] = copyData;
+
+    // The new data just copied in the local static buffer becomes live now
+    ((scopeGraphData_t **)tmp->liveData)[type]=copyData;
   }
 }
 
@@ -954,6 +958,7 @@ void nrUEinitScope(PHY_VARS_NR_UE *ue) {
   AssertFatal(ue->scopeData=malloc(sizeof(scopeData_t)),"");
   scopeData_t *scope=(scopeData_t *) ue->scopeData;
   scope->copyData=UEcopyData;
+  AssertFatal(scope->liveData=calloc(sizeof(scopeGraphData_t *), UEdataTypeNumberOfItems),"");
   pthread_t forms_thread;
   threadCreate(&forms_thread, nrUEscopeThread, ue, "scope", -1, OAI_PRIORITY_RT_LOW);
 }
diff --git a/openair1/PHY/TOOLS/oai_dfts.c b/openair1/PHY/TOOLS/oai_dfts.c
index 83207426fde1a4906866a2bdc1b082debcaa6441..c2b6a55210822fd4e066adf7888d4463309f164d 100644
--- a/openair1/PHY/TOOLS/oai_dfts.c
+++ b/openair1/PHY/TOOLS/oai_dfts.c
@@ -7082,43 +7082,40 @@ static inline void dft12f(simd_q15_t *x0,
 
   simd_q15_t tmp_dft12[12];
 
-  simd_q15_t *tmp_dft12_ptr = &tmp_dft12[0];
-
   // msg("dft12\n");
 
   bfly4_tw1(x0,
             x3,
             x6,
             x9,
-            tmp_dft12_ptr,
-            tmp_dft12_ptr+3,
-            tmp_dft12_ptr+6,
-            tmp_dft12_ptr+9);
-
+            tmp_dft12,
+            tmp_dft12+3,
+            tmp_dft12+6,
+            tmp_dft12+9);
 
   bfly4_tw1(x1,
             x4,
             x7,
             x10,
-            tmp_dft12_ptr+1,
-            tmp_dft12_ptr+4,
-            tmp_dft12_ptr+7,
-            tmp_dft12_ptr+10);
+            tmp_dft12+1,
+            tmp_dft12+4,
+            tmp_dft12+7,
+            tmp_dft12+10);
 
 
   bfly4_tw1(x2,
             x5,
             x8,
             x11,
-            tmp_dft12_ptr+2,
-            tmp_dft12_ptr+5,
-            tmp_dft12_ptr+8,
-            tmp_dft12_ptr+11);
+            tmp_dft12+2,
+            tmp_dft12+5,
+            tmp_dft12+8,
+            tmp_dft12+11);
 
   //  k2=0;
-  bfly3_tw1(tmp_dft12_ptr,
-            tmp_dft12_ptr+1,
-            tmp_dft12_ptr+2,
+  bfly3_tw1(tmp_dft12,
+            tmp_dft12+1,
+            tmp_dft12+2,
             y0,
             y4,
             y8);
@@ -7126,9 +7123,9 @@ static inline void dft12f(simd_q15_t *x0,
 
 
   //  k2=1;
-  bfly3(tmp_dft12_ptr+3,
-        tmp_dft12_ptr+4,
-        tmp_dft12_ptr+5,
+  bfly3(tmp_dft12+3,
+        tmp_dft12+4,
+        tmp_dft12+5,
         y1,
         y5,
         y9,
@@ -7138,9 +7135,9 @@ static inline void dft12f(simd_q15_t *x0,
 
 
   //  k2=2;
-  bfly3(tmp_dft12_ptr+6,
-        tmp_dft12_ptr+7,
-        tmp_dft12_ptr+8,
+  bfly3(tmp_dft12+6,
+        tmp_dft12+7,
+        tmp_dft12+8,
         y2,
         y6,
         y10,
@@ -7148,9 +7145,9 @@ static inline void dft12f(simd_q15_t *x0,
         W4_12);
 
   //  k2=3;
-  bfly3(tmp_dft12_ptr+9,
-        tmp_dft12_ptr+10,
-        tmp_dft12_ptr+11,
+  bfly3(tmp_dft12+9,
+        tmp_dft12+10,
+        tmp_dft12+11,
         y3,
         y7,
         y11,
@@ -10606,15 +10603,43 @@ int dfts_autoinit(void)
 
 #ifndef MR_MAIN
 
-void dft(uint8_t sizeidx, int16_t *sigF,int16_t *sig,unsigned char scale_flag){
-	AssertFatal((sizeidx>=0 && sizeidx<(int)DFT_SIZE_IDXTABLESIZE),"Invalid dft size index %i\n",sizeidx);
-	dft_ftab[sizeidx](sigF,sig,scale_flag);
+void dft(uint8_t sizeidx, int16_t *input,int16_t *output,unsigned char scale_flag){
+	AssertFatal((sizeidx >= 0 && sizeidx<DFT_SIZE_IDXTABLESIZE),"Invalid dft size index %i\n",sizeidx);
+        int algn=0xF;
+        #ifdef __AVX2__
+        if ( (dft_ftab[sizeidx].size%3) != 0 ) // there is no AVX2 implementation for multiples of 3 DFTs
+          algn=0x1F;
+        #endif 
+        AssertFatal(((intptr_t)output&algn)==0,"Buffers should be aligned %p",output);
+        if (((intptr_t)input)&algn) {
+          LOG_D(PHY, "DFT called with input not aligned, add a memcpy, size %d\n", sizeidx);
+          int sz=dft_ftab[sizeidx].size;
+          if (sizeidx==DFT_12) // This case does 8 DFTs in //
+            sz*=8;
+          int16_t tmp[sz*2] __attribute__ ((aligned(32))); // input and output are not in right type (int16_t instead of c16_t)
+          memcpy(tmp, input, sizeof tmp);
+          dft_ftab[sizeidx].func(tmp,output,scale_flag);
+        } else
+          dft_ftab[sizeidx].func(input,output,scale_flag);
 };
 
-void idft(uint8_t sizeidx, int16_t *sigF,int16_t *sig,unsigned char scale_flag){
-	AssertFatal((sizeidx>=0 && sizeidx<(int)IDFT_SIZE_IDXTABLESIZE),"Invalid idft size index %i\n",sizeidx);
-	idft_ftab[sizeidx](sigF,sig,scale_flag);
+void idft(uint8_t sizeidx, int16_t *input,int16_t *output,unsigned char scale_flag){
+	AssertFatal((sizeidx>=0 && sizeidx<DFT_SIZE_IDXTABLESIZE),"Invalid idft size index %i\n",sizeidx);
+        int algn=0xF;
+        #ifdef __AVX2__
+          algn=0x1F;
+        #endif
+        AssertFatal( ((intptr_t)output&algn)==0,"Buffers should be 16 bytes aligned %p",output);
+        if (((intptr_t)input)&algn ) {  
+          LOG_D(PHY, "DFT called with input not aligned, add a memcpy\n");
+          int sz=idft_ftab[sizeidx].size;
+          int16_t tmp[sz*2] __attribute__ ((aligned(32))); // input and output are not in right type (int16_t instead of c16_t)
+          memcpy(tmp, input, sizeof tmp);
+          dft_ftab[sizeidx].func(tmp,output,scale_flag);
+        } else
+          idft_ftab[sizeidx].func(input,output,scale_flag);
 };
+
 #endif
 
 /*---------------------------------------------------------------------------------------*/
diff --git a/openair1/PHY/TOOLS/phy_scope_interface.h b/openair1/PHY/TOOLS/phy_scope_interface.h
index 9cd8e1dc40c0924d3b01f1ef7561bd46b46f1561..6162e1eee58023622c0aaccc5e2de962aa62bb67 100644
--- a/openair1/PHY/TOOLS/phy_scope_interface.h
+++ b/openair1/PHY/TOOLS/phy_scope_interface.h
@@ -45,6 +45,8 @@ enum UEdataType {
   pbchDlChEstimateTime,
   pbchLlr,
   pbchRxdataF_comp,
+  pdcchLlr,
+  pdcchRxdataF_comp,
   UEdataTypeNumberOfItems
 };
 
diff --git a/openair1/PHY/TOOLS/tools_defs.h b/openair1/PHY/TOOLS/tools_defs.h
index 966e93440e9b017752734da7f4b4cc9398dc5019..145fbe4a31a2867e21f1ba645ea0ebef125a0a55 100644
--- a/openair1/PHY/TOOLS/tools_defs.h
+++ b/openair1/PHY/TOOLS/tools_defs.h
@@ -39,26 +39,33 @@ extern "C" {
 #define CEILIDIV(a,b) ((a+b-1)/b)
 #define ROUNDIDIV(a,b) (((a<<1)+b)/(b<<1))
 
-struct complexd {
+typedef struct complexd {
   double r;
   double i;
-};
+} cd_t;
 
-struct complexf {
+typedef struct complexf {
   float r;
   float i;
-};
+} cf_t;
 
-struct complex16 {
+typedef struct complex16 {
   int16_t r;
   int16_t i;
-};
+} c16_t;
 
-struct complex32 {
+typedef struct complex32 {
   int32_t r;
   int32_t i;
-};
-
+} c32_t;
+  
+typedef struct complex64 {
+  int64_t r;
+  int64_t i;
+} c64_t;
+
+#define squaredMod(a) ((a).r*(a).r+(a).i*(a).i)
+#define csum(res, i1, i2) (res).r=(i1).r+(i2).r ; (res).i=(i1).i+(i2).i  
 //cmult_sv.h
 
 /*!\fn void multadd_real_vector_complex_scalar(int16_t *x,int16_t *alpha,int16_t *y,uint32_t N)
@@ -181,159 +188,156 @@ This function performs optimized fixed-point radix-2 FFT/IFFT.
         );
 */
 
-
+#define FOREACH_DFTSZ(SZ_DEF) \
+  SZ_DEF(12) \
+  SZ_DEF(24) \
+  SZ_DEF(36) \
+  SZ_DEF(48) \
+  SZ_DEF(60) \
+  SZ_DEF(64) \
+  SZ_DEF(72) \
+  SZ_DEF(96) \
+  SZ_DEF(108) \
+  SZ_DEF(120) \
+  SZ_DEF(128) \
+  SZ_DEF(144) \
+  SZ_DEF(180) \
+  SZ_DEF(192) \
+  SZ_DEF(216) \
+  SZ_DEF(240) \
+  SZ_DEF(256) \
+  SZ_DEF(288) \
+  SZ_DEF(300) \
+  SZ_DEF(324) \
+  SZ_DEF(360) \
+  SZ_DEF(384) \
+  SZ_DEF(432) \
+  SZ_DEF(480) \
+  SZ_DEF(512) \
+  SZ_DEF(540) \
+  SZ_DEF(576) \
+  SZ_DEF(600) \
+  SZ_DEF(648) \
+  SZ_DEF(720) \
+  SZ_DEF(768) \
+  SZ_DEF(864) \
+  SZ_DEF(900) \
+  SZ_DEF(960) \
+  SZ_DEF(972) \
+  SZ_DEF(1024) \
+  SZ_DEF(1080) \
+  SZ_DEF(1152) \
+  SZ_DEF(1200) \
+  SZ_DEF(1296) \
+  SZ_DEF(1440) \
+  SZ_DEF(1500) \
+  SZ_DEF(1536) \
+  SZ_DEF(1620) \
+  SZ_DEF(1728) \
+  SZ_DEF(1800) \
+  SZ_DEF(1920) \
+  SZ_DEF(1944) \
+  SZ_DEF(2048) \
+  SZ_DEF(2160) \
+  SZ_DEF(2304) \
+  SZ_DEF(2400) \
+  SZ_DEF(2592) \
+  SZ_DEF(2700) \
+  SZ_DEF(2880) \
+  SZ_DEF(2916) \
+  SZ_DEF(3000) \
+  SZ_DEF(3072) \
+  SZ_DEF(3240) \
+  SZ_DEF(4096) \
+  SZ_DEF(6144) \
+  SZ_DEF(8192) \
+  SZ_DEF(9216) \
+  SZ_DEF(12288) \
+  SZ_DEF(18432) \
+  SZ_DEF(24576) \
+  SZ_DEF(36864) \
+  SZ_DEF(49152) \
+  SZ_DEF(73728) \
+  SZ_DEF(98304)
+
+#define FOREACH_IDFTSZ(SZ_DEF)\
+  SZ_DEF(64) \
+  SZ_DEF(128) \
+  SZ_DEF(256) \
+  SZ_DEF(512) \
+  SZ_DEF(1024) \
+  SZ_DEF(1536) \
+  SZ_DEF(2048) \
+  SZ_DEF(3072) \
+  SZ_DEF(4096) \
+  SZ_DEF(6144) \
+  SZ_DEF(8192) \
+  SZ_DEF(9216) \
+  SZ_DEF(12288) \
+  SZ_DEF(18432) \
+  SZ_DEF(24576) \
+  SZ_DEF(36864) \
+  SZ_DEF(49152) \
+  SZ_DEF(73728) \
+  SZ_DEF(98304)
 
 #ifdef OAIDFTS_MAIN
-typedef  void(*adftfunc_t)(int16_t *sigF,int16_t *sig,unsigned char scale_flag);  
-typedef  void(*aidftfunc_t)(int16_t *sigF,int16_t *sig,unsigned char scale_flag);     
-
-void dft12(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft24(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft36(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft48(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft60(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft64(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft72(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft96(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft108(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft120(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft128(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft144(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft180(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft192(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft216(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft240(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft256(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft288(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft300(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft324(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft360(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft384(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft432(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft480(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft512(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft540(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft576(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft600(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft648(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft720(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft768(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft864(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft900(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft960(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft972(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft1024(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft1080(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft1152(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft1200(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft1296(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft1440(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft1500(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft1536(int16_t *sigF,int16_t *sig,uint8_t scale_flag);
-void dft1620(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft1728(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft1800(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft1920(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft1944(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft2048(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft2160(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft2304(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft2400(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft2592(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft2700(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft2880(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft2916(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft3000(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft3072(int16_t *sigF,int16_t *sig,uint8_t scale_flag);
-void dft3240(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft4096(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft6144(int16_t *sigF,int16_t *sig,uint8_t scale_flag);
-void dft8192(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft9216(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft12288(int16_t *x,int16_t *y,uint8_t scale_flag);  
-void dft18432(int16_t *x,int16_t *y,uint8_t scale_flag); 
-void dft24576(int16_t *x,int16_t *y,uint8_t scale_flag); 
-void dft36864(int16_t *x,int16_t *y,uint8_t scale_flag); 
-void dft49152(int16_t *x,int16_t *y,uint8_t scale_flag); 
-void dft73728(int16_t *x,int16_t *y,uint8_t scale_flag); 
-void dft98304(int16_t *x,int16_t *y,uint8_t scale_flag);
-
-
-void idft64(int16_t *x,int16_t *y,uint8_t scale_flag);
-void idft128(int16_t *x,int16_t *y,uint8_t scale_flag);
-void idft256(int16_t *x,int16_t *y,uint8_t scale_flag);
-void idft512(int16_t *x,int16_t *y,uint8_t scale_flag);
-void idft1024(int16_t *x,int16_t *y,uint8_t scale_flag);
-void idft1536(int16_t *sigF,int16_t *sig,uint8_t scale_flag);
-void idft2048(int16_t *x,int16_t *y,uint8_t scale_flag);
-void idft3072(int16_t *sigF,int16_t *sig,uint8_t scale_flag);
-void idft4096(int16_t *x,int16_t *y,uint8_t scale_flag);
-void idft6144(int16_t *sigF,int16_t *sig,uint8_t scale_flag);
-void idft8192(int16_t *x,int16_t *y,uint8_t scale_flag);
-void idft9216(int16_t *x,int16_t *y,uint8_t scale_flag);
-void idft12288(int16_t *sigF,int16_t *sig,uint8_t scale_flag);
-void idft18432(int16_t *sigF,int16_t *sig,uint8_t scale_flag);
-void idft24576(int16_t *sigF,int16_t *sig,uint8_t scale_flag);
-void idft36864(int16_t *sigF,int16_t *sig,uint8_t scale_flag);
-void idft49152(int16_t *sigF,int16_t *sig,uint8_t scale_flag); 
-void idft73728(int16_t *sigF,int16_t *sig,uint8_t scale_flag);
-void idft98304(int16_t *sigF,int16_t *sig,uint8_t scale_flag);
+typedef  void(*adftfunc_t)(int16_t *sigF,int16_t *sig,unsigned char scale_flag);
+typedef  void(*aidftfunc_t)(int16_t *sigF,int16_t *sig,unsigned char scale_flag);
+
+#define SZ_FUNC(Sz) void dft ## Sz(int16_t *x,int16_t *y,uint8_t scale_flag);
 
+FOREACH_DFTSZ(SZ_FUNC)
 
+#define SZ_iFUNC(Sz) void idft ## Sz(int16_t *x,int16_t *y,uint8_t scale_flag);
 
+FOREACH_IDFTSZ(SZ_iFUNC)
 
 #else
-  typedef  void(*dftfunc_t)(uint8_t sizeidx,int16_t *sigF,int16_t *sig,unsigned char scale_flag);  
-  typedef  void(*idftfunc_t)(uint8_t sizeidx,int16_t *sigF,int16_t *sig,unsigned char scale_flag);  
+typedef  void(*dftfunc_t)(uint8_t sizeidx,int16_t *sigF,int16_t *sig,unsigned char scale_flag);
+typedef  void(*idftfunc_t)(uint8_t sizeidx,int16_t *sigF,int16_t *sig,unsigned char scale_flag);
 #  ifdef OAIDFTS_LOADER
-  dftfunc_t dft;
-  idftfunc_t idft;
+dftfunc_t dft;
+idftfunc_t idft;
 #  else
-  extern dftfunc_t dft;
-  extern idftfunc_t idft;
-  extern int load_dftslib(void);
+extern dftfunc_t dft;
+extern idftfunc_t idft;
+extern int load_dftslib(void);
 #  endif
 #endif
 
-typedef enum DFT_size_idx {
-	DFT_12,    DFT_24,    DFT_36,   DFT_48,     DFT_60,   DFT_72,   DFT_96,
-	DFT_108,   DFT_120,   DFT_128,  DFT_144,    DFT_180,  DFT_192,  DFT_216,   DFT_240,
-	DFT_256,   DFT_288,   DFT_300,  DFT_324,    DFT_360,  DFT_384,  DFT_432,   DFT_480,
-	DFT_512,   DFT_540,   DFT_576,  DFT_600,    DFT_648,  DFT_720,  DFT_768,   DFT_864,
-	DFT_900,   DFT_960,   DFT_972,  DFT_1024,   DFT_1080, DFT_1152, DFT_1200,  DFT_1296,
-	DFT_1440,  DFT_1500,  DFT_1536, DFT_1620,   DFT_1728, DFT_1800, DFT_1920,  DFT_1944,
-	DFT_2048,  DFT_2160,  DFT_2304, DFT_2400,   DFT_2592, DFT_2700, DFT_2880,  DFT_2916,
-	DFT_3000,  DFT_3072,  DFT_3240, DFT_4096,   DFT_6144, DFT_8192, DFT_9216,  DFT_12288,
-	DFT_18432, DFT_24576, DFT_36864, DFT_49152, DFT_73728, DFT_98304,
-	DFT_SIZE_IDXTABLESIZE
-} dft_size_idx_t;
+#define SZ_ENUM(Sz) DFT_ ## Sz,
 
-#ifdef OAIDFTS_MAIN
-adftfunc_t dft_ftab[]={
-	dft12,    dft24,    dft36,    dft48,    dft60,   dft72,   dft96,
-	dft108,   dft120,   dft128,   dft144,   dft180,  dft192,  dft216,   dft240,
-	dft256,   dft288,   dft300,   dft324,   dft360,  dft384,  dft432,   dft480,
-	dft512,   dft540,   dft576,   dft600,   dft648,  dft720,  dft768,   dft864,
-	dft900,   dft960,   dft972,   dft1024,  dft1080, dft1152, dft1200,  dft1296,
-	dft1440,  dft1500,  dft1536,  dft1620,  dft1728, dft1800, dft1920,  dft1944,
-	dft2048,  dft2160,  dft2304,  dft2400,  dft2592, dft2700, dft2880,  dft2916,
-	dft3000,  dft3072,  dft3240,  dft4096,  dft6144, dft8192, dft9216,  dft12288,
-	dft18432, dft24576, dft36864, dft49152, dft73728, dft98304
-};
-#endif
+typedef enum dft_size_idx {
+  FOREACH_DFTSZ(SZ_ENUM)
+  DFT_SIZE_IDXTABLESIZE
+}  dft_size_idx_t;
+
+#define SZ_iENUM(Sz) IDFT_ ## Sz,
 
 typedef enum idft_size_idx {
-	IDFT_128,   IDFT_256,  IDFT_512,   IDFT_1024,  IDFT_1536,  IDFT_2048,  IDFT_3072,  IDFT_4096,
-	IDFT_6144,  IDFT_8192, IDFT_9216,  IDFT_12288, IDFT_18432, IDFT_24576, IDFT_36864, IDFT_49152, 
-	IDFT_73728, IDFT_98304, 
-	IDFT_SIZE_IDXTABLESIZE
-} idft_size_idx_t;
+  FOREACH_IDFTSZ(SZ_iENUM)
+  IDFT_SIZE_IDXTABLESIZE
+}  idft_size_idx_t;
+
 #ifdef OAIDFTS_MAIN
-aidftfunc_t idft_ftab[]={
-	idft128,   idft256,  idft512,   idft1024,  idft1536,  idft2048,  idft3072,  idft4096,
-	idft6144,  idft8192, idft9216,  idft12288, idft18432, idft24576, idft36864, idft49152,
-	idft73728, idft98304
+
+#define SZ_PTR(Sz) {dft ## Sz,Sz},
+struct {
+  adftfunc_t func;
+  int size;
+} dft_ftab[]= {
+  FOREACH_DFTSZ(SZ_PTR)
 };
+
+#define SZ_iPTR(Sz)  {idft ## Sz,Sz},
+struct {
+  adftfunc_t func;
+  int size;
+} idft_ftab[]= {
+  FOREACH_IDFTSZ(SZ_iPTR)
+};
+
 #endif
 
 
@@ -387,7 +391,7 @@ int32_t add_real_vector64(int16_t *x,
                           uint32_t N);
 
 int32_t sub_real_vector64(int16_t *x,
-                          int16_t* y,
+                          int16_t *y,
                           int16_t *z,
                           uint32_t N);
 
@@ -444,7 +448,7 @@ int32_t signal_energy_amp_shift(int32_t *input, uint32_t length);
 /*!\fn int32_t signal_energy(int *,uint32_t);
 \brief Computes the signal energy per subcarrier
 */
-int32_t subcarrier_energy(int32_t *,uint32_t, int32_t* subcarrier_energy, uint16_t rx_power_correction);
+int32_t subcarrier_energy(int32_t *,uint32_t, int32_t *subcarrier_energy, uint16_t rx_power_correction);
 #endif
 
 /*!\fn int32_t signal_energy_nodc(int32_t *,uint32_t);
diff --git a/openair1/PHY/defs_RU.h b/openair1/PHY/defs_RU.h
index 0b20aa409ba69edc3f49b734f91248dc73c43e44..243e76f851823a384c0fe676f0ccc32016fde48d 100644
--- a/openair1/PHY/defs_RU.h
+++ b/openair1/PHY/defs_RU.h
@@ -54,7 +54,6 @@ typedef enum {
   no_L2_connect=5,
   calib_prach_tx=6,
   rx_dump_frame=7,
-  loop_through_memory=8
 } runmode_t;
 
 /*! \brief Extension Type */
diff --git a/openair1/PHY/defs_UE.h b/openair1/PHY/defs_UE.h
index 7f4d07ddae8c5b58251ca3a50ae0ae4ba913105d..4f9bc076ffd004b7371a46fbfc6326e7b77089f6 100644
--- a/openair1/PHY/defs_UE.h
+++ b/openair1/PHY/defs_UE.h
@@ -833,7 +833,6 @@ typedef struct {
   pthread_mutex_t timer_mutex;
   pthread_cond_t timer_cond;
   int instance_cnt_timer;
-
   /// RF and Interface devices per CC
 
   openair0_device rfdevice;
diff --git a/openair1/PHY/defs_common.h b/openair1/PHY/defs_common.h
index 86df85db5c5ed1c076444ec5c07e2930b202ad22..d13fe260deba559e3b0dcbf3077192289cfa16a5 100644
--- a/openair1/PHY/defs_common.h
+++ b/openair1/PHY/defs_common.h
@@ -99,7 +99,7 @@
 #define NB_RX_ANTENNAS_MAX 64
 
 
-typedef enum {TDD=1,FDD=0} lte_frame_type_t;
+typedef enum {TDD=1,FDD=0} frame_type_t;
 
 typedef enum {EXTENDED=1,NORMAL=0} lte_prefix_type_t;
 
@@ -597,7 +597,7 @@ typedef struct LTE_DL_FRAME_PARMS {
   /// shift of pilot position in one RB
   uint8_t nushift;
   /// Frame type (0 FDD, 1 TDD)
-  lte_frame_type_t frame_type;
+  frame_type_t frame_type;
   /// TDD subframe assignment (0-7) (default = 3) (254=RX only, 255=TX only)
   uint8_t tdd_config;
   /// TDD S-subframe configuration (0-9)
diff --git a/openair1/PHY/defs_gNB.h b/openair1/PHY/defs_gNB.h
index 9be2d0208d5c4e4e2e21cb8de525561db2238c5b..1ff17f9a39458fcfe651168fc27451919e475bb1 100644
--- a/openair1/PHY/defs_gNB.h
+++ b/openair1/PHY/defs_gNB.h
@@ -280,8 +280,6 @@ typedef struct {
   uint32_t C;
   /// Pointers to code blocks after LDPC coding (38.212 V15.4.0 section 5.3.2)
   int16_t *d[MAX_NUM_NR_ULSCH_SEGMENTS];
-  /// LDPC processing buffer
-  t_nrLDPC_procBuf* p_nrLDPC_procBuf[MAX_NUM_NR_ULSCH_SEGMENTS];
   /// LDPC lifting size (38.212 V15.4.0 table 5.3.2-1)
   uint32_t Z;
   /// code blocks after bit selection in rate matching for LDPC code (38.212 V15.4.0 section 5.4.2.1)
@@ -589,9 +587,6 @@ typedef struct gNB_L1_proc_t_s {
   int instance_cnt_te;
   /// \internal This variable is protected by \ref mutex_prach.
   int instance_cnt_prach;
-
-  // instance count for over-the-air gNB synchronization
-  int instance_cnt_synch;
   /// \internal This variable is protected by \ref mutex_asynch_rxtx.
   int instance_cnt_asynch_rxtx;
   /// pthread structure for eNB single processing thread
@@ -663,8 +658,6 @@ typedef struct {
   unsigned int   n0_power_tot;
   //! estimated avg noise power (dB)
   unsigned int n0_power_tot_dB;
-  //! estimated avg noise power (dB)
-  int n0_power_tot_dBm;
   //! estimated avg noise power per RB per RX ant (lin)
   unsigned int n0_subband_power[MAX_NUM_RU_PER_gNB][275];
   //! estimated avg noise power per RB per RX ant (dB)
@@ -852,9 +845,15 @@ typedef struct PHY_VARS_gNB_s {
   /// counter to average prach energh over first 100 prach opportunities
   int prach_energy_counter;
 
+  int csi_gold_init;
+  int pdcch_gold_init;
+  int pdsch_gold_init[2];
+  int pusch_gold_init[2];
+
   int ap_N1;
   int ap_N2;
   int ap_XP;
+
   int pucch0_thres;
   int pusch_thres;
   int prach_thres;
diff --git a/openair1/PHY/defs_nr_UE.h b/openair1/PHY/defs_nr_UE.h
index 8a533be5eb1ab9a11a88bcc80f32f5a46f0897e5..82de7ed96ea014d117fc68f37d2c0129f575775a 100644
--- a/openair1/PHY/defs_nr_UE.h
+++ b/openair1/PHY/defs_nr_UE.h
@@ -550,60 +550,20 @@ typedef struct {
 } NR_UE_PDCCH_SEARCHSPACE;
 #endif
 typedef struct {
-  /// \brief Pointers to extracted PDCCH symbols in frequency-domain.
-  /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx
-  /// - second index: ? [0..168*N_RB_DL[
-  int32_t **rxdataF_ext;
-  /// \brief Pointers to extracted and compensated PDCCH symbols in frequency-domain.
-  /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx
-  /// - second index: ? [0..168*N_RB_DL[
-  int32_t **rxdataF_comp;
-  /// \brief Hold the channel estimates in frequency domain.
-  /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx
-  /// - second index: samples? [0..symbols_per_tti*(ofdm_symbol_size+LTE_CE_FILTER_LENGTH)[
-  int32_t **dl_ch_estimates;
-  /// \brief Hold the channel estimates in time domain (used for tracking).
-  /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx
-  /// - second index: samples? [0..2*ofdm_symbol_size[
-  int32_t **dl_ch_estimates_time;
-  /// \brief Pointers to extracted channel estimates of PDCCH symbols.
-  /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx
-  /// - second index: ? [0..168*N_RB_DL[
-  int32_t **dl_ch_estimates_ext;
-  /// \brief Pointers to channel cross-correlation vectors for multi-gNB detection.
-  /// - first index: rx antenna [0..nb_antennas_rx[
-  /// - second index: ? [0..]
-  int32_t **rho;
-  /// \brief Pointer to llrs, 4-bit resolution.
-  /// - first index: ? [0..48*N_RB_DL[
-  int16_t *llr;
-  /// \brief Pointer to llrs, 16-bit resolution.
-  /// - first index: ? [0..96*N_RB_DL[
-  int16_t *llr16;
-  /// \brief \f$\overline{w}\f$ from 36-211.
-  /// - first index: ? [0..48*N_RB_DL[
-  int16_t *wbar;
-  /// \brief PDCCH/DCI e-sequence (input to rate matching).
-  /// - first index: ? [0..96*N_RB_DL[
-  int16_t *e_rx;
-  /// Total number of PDU errors (diagnostic mode)
-  uint32_t dci_errors;
+  int nb_search_space;
+  uint16_t sfn;
+  uint16_t slot;
+  fapi_nr_dl_config_dci_dl_pdu_rel15_t pdcch_config[FAPI_NR_MAX_SS];
+} NR_UE_PDCCH_CONFIG;
+
+typedef struct {
   /// Total number of PDU received
   uint32_t dci_received;
   /// Total number of DCI False detection (diagnostic mode)
   uint32_t dci_false;
   /// Total number of DCI missed (diagnostic mode)
   uint32_t dci_missed;
-  /// nCCE for PDCCH per subframe
-  uint8_t nCCE[10];
-  //Check for specific DCIFormat and AgregationLevel
-  uint8_t dciFormat;
-  uint8_t agregationLevel;
-  int nb_search_space;
-  fapi_nr_dl_config_dci_dl_pdu_rel15_t pdcch_config[FAPI_NR_MAX_SS];
-  // frame and slot for sib1 in initial sync
-  uint16_t sfn;
-  uint16_t slot;
+
   /*
 #ifdef NR_PDCCH_DEFS_NR_UE
   int nb_searchSpaces;
@@ -789,7 +749,10 @@ typedef struct {
   uint32_t ****nr_gold_pdsch[NUMBER_OF_CONNECTED_eNB_MAX];
 
   // Scrambling IDs used in PDSCH DMRS
-  uint16_t scramblingID[2];
+  uint16_t scramblingID_dlsch[2];
+
+  // Scrambling IDs used in PUSCH DMRS
+  uint16_t scramblingID_ulsch[2];
 
   /// PDCCH DMRS
   uint32_t ***nr_gold_pdcch[NUMBER_OF_CONNECTED_eNB_MAX];
@@ -798,7 +761,7 @@ typedef struct {
   uint16_t scramblingID_pdcch;
 
   /// PUSCH DMRS sequence
-  uint32_t ***nr_gold_pusch_dmrs;
+  uint32_t ****nr_gold_pusch_dmrs;
 
   uint32_t X_u[64][839];
 
diff --git a/openair1/PHY/defs_nr_common.h b/openair1/PHY/defs_nr_common.h
index 561e2f3d93f65a9789f6844a6eafe5a26b97df8d..b24abd7de39e20bfdf9c626619b0946e218c4321 100644
--- a/openair1/PHY/defs_nr_common.h
+++ b/openair1/PHY/defs_nr_common.h
@@ -67,6 +67,7 @@
 
 /*used for the resource mapping*/
 #define NR_MAX_PDCCH_DMRS_LENGTH 576 // 16(L)*2(QPSK)*3(3 DMRS symbs per REG)*6(REG per CCE)
+#define  NR_MAX_PDCCH_SIZE 8192 // It seems it is the max polar coded block size
 
 #define NR_MAX_DCI_PAYLOAD_SIZE 64
 #define NR_MAX_DCI_SIZE 1728 //16(L)*2(QPSK)*9(12 RE per REG - 3(DMRS))*6(REG per CCE)
@@ -94,6 +95,8 @@
 #define NR_RX_NB_TH 1
 #define NR_NB_TH_SLOT 2
 
+#define NR_NB_NSCID 2
+
 extern const uint8_t nr_rv_round_map[4]; 
 
 static inline
@@ -278,7 +281,7 @@ struct NR_DL_FRAME_PARMS {
   uint32_t att_rx;
   ///  total Number of Resource Block Groups: this is ceil(N_PRB/P)
   /// Frame type (0 FDD, 1 TDD)
-  lte_frame_type_t frame_type;
+  frame_type_t frame_type;
   uint8_t tdd_config;
   /// Cell ID
   uint16_t Nid_cell;
diff --git a/openair1/SCHED/phy_procedures_lte_common.c b/openair1/SCHED/phy_procedures_lte_common.c
index 7033c5270138ee50f5527987b59c185d37e0738b..9de453da948e7594356319d2d6cc8dad94171ac0 100644
--- a/openair1/SCHED/phy_procedures_lte_common.c
+++ b/openair1/SCHED/phy_procedures_lte_common.c
@@ -994,7 +994,7 @@ int is_srs_occasion_common(LTE_DL_FRAME_PARMS *frame_parms,int frame_tx,int subf
   return(isSubframeSRS);
 }
 
-void compute_srs_pos(lte_frame_type_t frameType,uint16_t isrs,uint16_t *psrsPeriodicity,uint16_t *psrsOffset)
+void compute_srs_pos(frame_type_t frameType,uint16_t isrs,uint16_t *psrsPeriodicity,uint16_t *psrsOffset)
 {
     if(TDD == frameType)
     {
diff --git a/openair1/SCHED/sched_common.h b/openair1/SCHED/sched_common.h
index c9fc3386865b6931fc7fdbb98f694f61d078806f..9f3e6695b6ccf650dde15eaba9f178bca176874d 100644
--- a/openair1/SCHED/sched_common.h
+++ b/openair1/SCHED/sched_common.h
@@ -339,7 +339,7 @@ void dump_dlsch2(PHY_VARS_UE *phy_vars_ue,uint8_t eNB_id,uint8_t subframe, unsig
 
 int is_srs_occasion_common(LTE_DL_FRAME_PARMS *frame_parms,int frame_tx,int subframe_tx);
 
-void compute_srs_pos(lte_frame_type_t frameType,uint16_t isrs,uint16_t *psrsPeriodicity,uint16_t *psrsOffset);
+void compute_srs_pos(frame_type_t frameType,uint16_t isrs,uint16_t *psrsPeriodicity,uint16_t *psrsOffset);
 
 
 /* from here: prototype added to remove compilation warnings, doc to be written by the author of the function */
diff --git a/openair1/SCHED/sched_common_vars.h b/openair1/SCHED/sched_common_vars.h
index 2cae2aa96f21bc49bc32dc156ac688b8c22f72eb..8886e0d576bae75c8e088e9131d9dea4b00e2d19 100644
--- a/openair1/SCHED/sched_common_vars.h
+++ b/openair1/SCHED/sched_common_vars.h
@@ -20,6 +20,7 @@
  */
 
 #include <stdint.h>
+#include <openair1/SCHED/sched_common_extern.h>
 
 
 // This is the formula from Section 5.1.1.1 in 36.213 100*10*log10((2^(MPR*Ks)-1)), where MPR is in the range [0,6] and Ks=1.25
diff --git a/openair1/SCHED/sched_eNB.h b/openair1/SCHED/sched_eNB.h
index de987b0ac7eece4820e24f208798954a658d7572..efdb1bd199ffb544a8df92b1ed424564b1a91e42 100644
--- a/openair1/SCHED/sched_eNB.h
+++ b/openair1/SCHED/sched_eNB.h
@@ -215,7 +215,7 @@ int16_t get_target_pucch_rx_power(module_id_t module_idP, uint8_t CC_id);
 
 int is_srs_occasion_common(LTE_DL_FRAME_PARMS *frame_parms,int frame_tx,int subframe_tx);
 
-void compute_srs_pos(lte_frame_type_t frameType,uint16_t isrs,uint16_t *psrsPeriodicity,uint16_t *psrsOffset);
+void compute_srs_pos(frame_type_t frameType,uint16_t isrs,uint16_t *psrsPeriodicity,uint16_t *psrsOffset);
 
 void release_rnti_of_phy(module_id_t mod_id);
 /*@}*/
diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c
index ee7f734ae2c8d35664fae8442cf36fd7e678ac07..46816d0373c118c4ecbb7d536441012ccbfea4fc 100644
--- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c
+++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c
@@ -158,8 +158,7 @@ void phy_procedures_gNB_TX(processingData_L1tx_t *msgTx,
   
     VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_gNB_PDCCH_TX,1);
 
-    nr_generate_dci_top(msgTx,
-			gNB->nr_gold_pdcch_dmrs[slot],
+    nr_generate_dci_top(msgTx, slot,
 			&gNB->common_vars.txdataF[0][txdataF_offset],
 			AMP, fp);
 
@@ -178,7 +177,7 @@ void phy_procedures_gNB_TX(processingData_L1tx_t *msgTx,
     if (csirs->active == 1) {
       LOG_D(PHY, "CSI-RS generation started in frame %d.%d\n",frame,slot);
       nfapi_nr_dl_tti_csi_rs_pdu_rel15_t csi_params = csirs->csirs_pdu.csi_rs_pdu_rel15;
-      nr_generate_csi_rs(gNB, AMP, csi_params, gNB->gNB_config.cell_config.phy_cell_id.value, slot);
+      nr_generate_csi_rs(gNB, AMP, csi_params, slot);
       csirs->active = 0;
     }
   }
diff --git a/openair1/SCHED_NR_UE/defs.h b/openair1/SCHED_NR_UE/defs.h
index eeea57ffc6125ddfd9af36ba9cb83a770f041d31..9bcf659eac83b4a279521acdc6cbeece4e980109 100644
--- a/openair1/SCHED_NR_UE/defs.h
+++ b/openair1/SCHED_NR_UE/defs.h
@@ -116,16 +116,18 @@ int phy_procedures_RN_UE_RX(unsigned char last_slot, unsigned char next_slot, re
 void phy_procedures_nrUE_TX(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t eNB_id);
 
 /*! \brief Scheduling for UE RX procedures in normal subframes.
-  @param ue             Pointer to UE variables on which to act
-  @param proc           Pointer to proc information
-  @param gNB_id         Local id of eNB on which to act
-  @param dlsch_parallel use multithreaded dlsch processing
-  @param txFifo         Result fifo if PDSCH is run in parallel
+  @param ue                     Pointer to UE variables on which to act
+  @param proc                   Pointer to proc information
+  @param gNB_id                 Local id of eNB on which to act
+  @param dlsch_parallel         use multithreaded dlsch processing
+  @param phy_pdcch_config       PDCCH Config for this slot
+  @param txFifo                 Result fifo if PDSCH is run in parallel
 */
 int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,
                            UE_nr_rxtx_proc_t *proc,
                            uint8_t gNB_id,
                            uint8_t dlsch_parallel,
+                           NR_UE_PDCCH_CONFIG *phy_pdcch_config,
                            notifiedFIFO_t *txFifo);
 
 int phy_procedures_slot_parallelization_nrUE_RX(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t eNB_id, uint8_t abstraction_flag, uint8_t do_pdcch_flag, relaying_type_t r_type);
@@ -383,7 +385,8 @@ void nr_fill_dl_indication(nr_downlink_indication_t *dl_ind,
                            fapi_nr_rx_indication_t *rx_ind,
                            UE_nr_rxtx_proc_t *proc,
                            PHY_VARS_NR_UE *ue,
-                           uint8_t gNB_id);
+                           uint8_t gNB_id,
+                           void *phy_data);
 
 /*@}*/
 
@@ -417,8 +420,11 @@ int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue,
                            NR_UE_DLSCH_t *dlsch0, NR_UE_DLSCH_t *dlsch1);
 
 int nr_ue_pdcch_procedures(uint8_t gNB_id,
-			   PHY_VARS_NR_UE *ue,
-			   UE_nr_rxtx_proc_t *proc,
+                           PHY_VARS_NR_UE *ue,
+                           UE_nr_rxtx_proc_t *proc,
+                           int32_t pdcch_est_size,
+                           int32_t pdcch_dl_ch_estimates[][pdcch_est_size],
+                           NR_UE_PDCCH_CONFIG *phy_pdcch_config,
                            int n_ss);
 
 
diff --git a/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c b/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c
index a206d1c6143229ffcd47c5d7d8dac1cf922cea8d..51b34fb9baa9d2014129041190a74a2fe5d37759 100644
--- a/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c
+++ b/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c
@@ -36,10 +36,11 @@
 #include "fapi_nr_ue_l1.h"
 #include "harq_nr.h"
 //#include "PHY/phy_vars_nr_ue.h"
-
+#include "openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.h"
 #include "PHY/defs_nr_UE.h"
 #include "PHY/impl_defs_nr.h"
 #include "utils.h"
+#include "openair2/PHY_INTERFACE/queue_t.h"
 
 extern PHY_VARS_NR_UE ***PHY_vars_UE_g;
 
@@ -49,8 +50,64 @@ queue_t nr_rx_ind_queue;
 queue_t nr_crc_ind_queue;
 queue_t nr_uci_ind_queue;
 
-int8_t nr_ue_scheduled_response_stub(nr_scheduled_response_t *scheduled_response) {
+static void fill_uci_2_3_4(nfapi_nr_uci_pucch_pdu_format_2_3_4_t *pdu_2_3_4,
+                           fapi_nr_ul_config_pucch_pdu *pucch_pdu)
+{
+  memset(pdu_2_3_4, 0, sizeof(*pdu_2_3_4));
+  pdu_2_3_4->handle = 0;
+  pdu_2_3_4->rnti = pucch_pdu->rnti;
+  pdu_2_3_4->pucch_format = 2;
+  pdu_2_3_4->ul_cqi = 255;
+  pdu_2_3_4->timing_advance = 0;
+  pdu_2_3_4->rssi = 0;
+  // TODO: Eventually check 38.212:Sect.631 to know when to use csi_part2, for now only using csi_part1
+  pdu_2_3_4->pduBitmap = 4;
+  pdu_2_3_4->csi_part1.csi_part1_bit_len = pucch_pdu->nr_of_symbols;
+  int csi_part1_byte_len = (int)((pdu_2_3_4->csi_part1.csi_part1_bit_len / 8) + 1);
+  AssertFatal(!pdu_2_3_4->csi_part1.csi_part1_payload, "pdu_2_3_4->csi_part1.csi_part1_payload != NULL\n");
+  pdu_2_3_4->csi_part1.csi_part1_payload = CALLOC(csi_part1_byte_len,
+                                                  sizeof(pdu_2_3_4->csi_part1.csi_part1_payload));
+  for (int k = 0; k < csi_part1_byte_len; k++)
+  {
+    pdu_2_3_4->csi_part1.csi_part1_payload[k] = (pucch_pdu->payload >> (k * 8)) & 0xff;
+  }
+  pdu_2_3_4->csi_part1.csi_part1_crc = 0;
+}
+
+static void free_uci_inds(nfapi_nr_uci_indication_t *uci_ind)
+{
+    for (int k = 0; k < uci_ind->num_ucis; k++)
+    {
+        if (uci_ind->uci_list[k].pdu_type == NFAPI_NR_UCI_FORMAT_0_1_PDU_TYPE)
+        {
+            nfapi_nr_uci_pucch_pdu_format_0_1_t *pdu_0_1 = &uci_ind->uci_list[k].pucch_pdu_format_0_1;
+            free(pdu_0_1->sr);
+            pdu_0_1->sr = NULL;
+            if (pdu_0_1->harq)
+            {
+                free(pdu_0_1->harq->harq_list);
+                pdu_0_1->harq->harq_list = NULL;
+            }
+            free(pdu_0_1->harq);
+            pdu_0_1->harq = NULL;
+        }
+        if (uci_ind->uci_list[k].pdu_type == NFAPI_NR_UCI_FORMAT_2_3_4_PDU_TYPE)
+        {
+            nfapi_nr_uci_pucch_pdu_format_2_3_4_t *pdu_2_3_4 = &uci_ind->uci_list[k].pucch_pdu_format_2_3_4;
+            free(pdu_2_3_4->sr.sr_payload);
+            pdu_2_3_4->sr.sr_payload = NULL;
+            free(pdu_2_3_4->harq.harq_payload);
+            pdu_2_3_4->harq.harq_payload = NULL;
+        }
+    }
+    free(uci_ind->uci_list);
+    uci_ind->uci_list = NULL;
+    free(uci_ind);
+    uci_ind = NULL;
+}
 
+int8_t nr_ue_scheduled_response_stub(nr_scheduled_response_t *scheduled_response) {
+  NR_UE_MAC_INST_t *mac = get_mac_inst(0);
   if(scheduled_response != NULL)
   {
     if (scheduled_response->ul_config != NULL)
@@ -60,7 +117,7 @@ int8_t nr_ue_scheduled_response_stub(nr_scheduled_response_t *scheduled_response
                   "Too many ul_config pdus %d", ul_config->number_pdus);
       for (int i = 0; i < ul_config->number_pdus; ++i)
       {
-        LOG_I(PHY, "In %s: processing type %d PDU of %d total UL PDUs (ul_config %p) \n",
+        LOG_D(NR_PHY, "In %s: processing type %d PDU of %d total UL PDUs (ul_config %p) \n",
               __FUNCTION__, ul_config->ul_config_list[i].pdu_type, ul_config->number_pdus, ul_config);
 
         uint8_t pdu_type = ul_config->ul_config_list[i].pdu_type;
@@ -95,10 +152,6 @@ int8_t nr_ue_scheduled_response_stub(nr_scheduled_response_t *scheduled_response
                    abstracting L1. */
                 rx_ind->pdu_list[j].timing_advance = 31;
                 rx_ind->pdu_list[j].ul_cqi = 255;
-                char buffer[1024];
-                hexdump(rx_ind->pdu_list[j].pdu, rx_ind->pdu_list[j].pdu_length, buffer, sizeof(buffer));
-                LOG_D(NR_MAC, "Hexdump of pdu %s before queuing rx_ind\n",
-                      buffer);
               }
 
               crc_ind->header.message_id = NFAPI_NR_PHY_MSG_TYPE_CRC_INDICATION;
@@ -118,6 +171,11 @@ int8_t nr_ue_scheduled_response_stub(nr_scheduled_response_t *scheduled_response
                 crc_ind->crc_list[j].tb_crc_status = 0;
                 crc_ind->crc_list[j].timing_advance = 31;
                 crc_ind->crc_list[j].ul_cqi = 255;
+                AssertFatal(mac->nr_ue_emul_l1.harq[crc_ind->crc_list[j].harq_id].active_ul_harq_sfn_slot == -1,
+                            "We did not send an active CRC when we should have!\n");
+                mac->nr_ue_emul_l1.harq[crc_ind->crc_list[j].harq_id].active_ul_harq_sfn_slot = NFAPI_SFNSLOT2HEX(crc_ind->sfn, crc_ind->slot);
+                LOG_D(NR_MAC, "This is sched sfn/sl [%d %d] and crc sfn/sl [%d %d] with mcs_index in ul_cqi -> %d\n",
+                      scheduled_response->frame, scheduled_response->slot, crc_ind->sfn, crc_ind->slot,pusch_config_pdu->mcs_index);
               }
 
               if (!put_queue(&nr_rx_ind_queue, rx_ind))
@@ -150,28 +208,7 @@ int8_t nr_ue_scheduled_response_stub(nr_scheduled_response_t *scheduled_response
             break;
           }
 
-          default:
-            LOG_I(NR_MAC, "Unknown ul_config->pdu_type %d\n", pdu_type);
-          break;
-        }
-      }
-      scheduled_response->ul_config->number_pdus = 0;
-    }
-
-    if (scheduled_response->dl_config != NULL)
-    {
-      fapi_nr_dl_config_request_t *dl_config = scheduled_response->dl_config;
-      AssertFatal(dl_config->number_pdus < sizeof(dl_config->dl_config_list) / sizeof(dl_config->dl_config_list[0]),
-                  "Too many dl_config pdus %d", dl_config->number_pdus);
-      for (int i = 0; i < dl_config->number_pdus; ++i)
-      {
-        LOG_D(PHY, "In %s: processing %s PDU of %d total DL PDUs (dl_config %p) \n",
-              __FUNCTION__, dl_pdu_type[dl_config->dl_config_list[i].pdu_type - 1], dl_config->number_pdus, dl_config);
-
-        uint8_t pdu_type = dl_config->dl_config_list[i].pdu_type;
-        switch (pdu_type)
-        {
-          case (FAPI_NR_DL_CONFIG_TYPE_DLSCH):
+          case FAPI_NR_UL_CONFIG_TYPE_PUCCH:
           {
             nfapi_nr_uci_indication_t *uci_ind = CALLOC(1, sizeof(*uci_ind));
             uci_ind->header.message_id = NFAPI_NR_PHY_MSG_TYPE_UCI_INDICATION;
@@ -181,35 +218,70 @@ int8_t nr_ue_scheduled_response_stub(nr_scheduled_response_t *scheduled_response
             uci_ind->uci_list = CALLOC(uci_ind->num_ucis, sizeof(*uci_ind->uci_list));
             for (int j = 0; j < uci_ind->num_ucis; j++)
             {
-              nfapi_nr_uci_pucch_pdu_format_0_1_t *pdu_0_1 = &uci_ind->uci_list[j].pucch_pdu_format_0_1;
-              uci_ind->uci_list[j].pdu_type = NFAPI_NR_UCI_FORMAT_0_1_PDU_TYPE;
-              uci_ind->uci_list[j].pdu_size = sizeof(nfapi_nr_uci_pucch_pdu_format_0_1_t);
-              memset(pdu_0_1, 0, sizeof(*pdu_0_1));
-              pdu_0_1->handle = 0;
-              pdu_0_1->rnti = dl_config->dl_config_list[i].dlsch_config_pdu.rnti;
-              pdu_0_1->pucch_format = 1;
-              pdu_0_1->ul_cqi = 255;
-              pdu_0_1->timing_advance = 0;
-              pdu_0_1->rssi = 0;
+              LOG_D(NR_MAC, "ul_config->ul_config_list[%d].pucch_config_pdu.n_bit = %d\n", i, ul_config->ul_config_list[i].pucch_config_pdu.n_bit);
+              if (ul_config->ul_config_list[i].pucch_config_pdu.n_bit > 3 && mac->nr_ue_emul_l1.num_csi_reports > 0)
+              {
+                uci_ind->uci_list[j].pdu_type = NFAPI_NR_UCI_FORMAT_2_3_4_PDU_TYPE;
+                uci_ind->uci_list[j].pdu_size = sizeof(nfapi_nr_uci_pucch_pdu_format_2_3_4_t);
+                nfapi_nr_uci_pucch_pdu_format_2_3_4_t *pdu_2_3_4 = &uci_ind->uci_list[j].pucch_pdu_format_2_3_4;
+                fill_uci_2_3_4(pdu_2_3_4, &ul_config->ul_config_list[i].pucch_config_pdu);
+              }
+              else
+              {
+                nfapi_nr_uci_pucch_pdu_format_0_1_t *pdu_0_1 = &uci_ind->uci_list[j].pucch_pdu_format_0_1;
+                uci_ind->uci_list[j].pdu_type = NFAPI_NR_UCI_FORMAT_0_1_PDU_TYPE;
+                uci_ind->uci_list[j].pdu_size = sizeof(nfapi_nr_uci_pucch_pdu_format_0_1_t);
+                memset(pdu_0_1, 0, sizeof(*pdu_0_1));
+                pdu_0_1->handle = 0;
+                pdu_0_1->rnti = ul_config->ul_config_list[i].pucch_config_pdu.rnti;
+                pdu_0_1->pucch_format = 1;
+                pdu_0_1->ul_cqi = 255;
+                pdu_0_1->timing_advance = 0;
+                pdu_0_1->rssi = 0;
+
+                if (mac->nr_ue_emul_l1.num_harqs > 0) {
+                  int harq_index = 0;
+                  pdu_0_1->pduBitmap = 2; // (value->pduBitmap >> 1) & 0x01) == HARQ and (value->pduBitmap) & 0x01) == SR
+                  pdu_0_1->harq = CALLOC(1, sizeof(*pdu_0_1->harq));
+                  pdu_0_1->harq->num_harq = mac->nr_ue_emul_l1.num_harqs;
+                  pdu_0_1->harq->harq_confidence_level = 0;
+                  pdu_0_1->harq->harq_list = CALLOC(pdu_0_1->harq->num_harq, sizeof(*pdu_0_1->harq->harq_list));
+                  int harq_pid = -1;
+                  for (int k = 0; k < NR_MAX_HARQ_PROCESSES; k++)
+                  {
+                    if (mac->nr_ue_emul_l1.harq[k].active &&
+                        mac->nr_ue_emul_l1.harq[k].active_dl_harq_sfn == uci_ind->sfn &&
+                        mac->nr_ue_emul_l1.harq[k].active_dl_harq_slot == uci_ind->slot)
+                    {
+                      mac->nr_ue_emul_l1.harq[k].active = false;
+                      harq_pid = k;
+                      AssertFatal(harq_index < pdu_0_1->harq->num_harq, "Invalid harq_index %d\n", harq_index);
+                      pdu_0_1->harq->harq_list[harq_index].harq_value = !mac->dl_harq_info[k].ack;
+                      harq_index++;
+                    }
+                  }
+                  AssertFatal(harq_pid != -1, "No active harq_pid, sfn_slot = %u.%u", uci_ind->sfn, uci_ind->slot);
+                }
+              }
             }
 
-            LOG_I(NR_PHY, "In %s: Filled queue uci_ind which was filled by dlconfig.\n"
-                       "uci_num %d, SFN/SLOT: [%d, %d]\n",
-                          __FUNCTION__, uci_ind->num_ucis, uci_ind->sfn, uci_ind->slot);
-
-            if (!put_queue(&nr_uci_ind_queue, uci_ind))
-            {
-              LOG_E(NR_MAC, "Put_queue failed for uci_ind\n");
-              free(uci_ind->uci_list);
-              free(uci_ind);
-            }
+            LOG_D(NR_PHY, "Sending UCI with %d PDUs in sfn.slot %d/%d\n",
+                  uci_ind->num_ucis, uci_ind->sfn, uci_ind->slot);
+            NR_UL_IND_t ul_info = {
+                .uci_ind = *uci_ind,
+            };
+            send_nsa_standalone_msg(&ul_info, uci_ind->header.message_id);
+            free_uci_inds(uci_ind);
             break;
           }
+
+          default:
+            LOG_W(NR_MAC, "Unknown ul_config->pdu_type %d\n", pdu_type);
+          break;
         }
       }
-      dl_config->number_pdus = 0;
+      scheduled_response->ul_config->number_pdus = 0;
     }
-
   }
   return 0;
 }
@@ -243,6 +315,8 @@ void configure_dlsch(NR_UE_DLSCH_t *dlsch0,
   dlsch0_harq->mcs = dlsch_config_pdu->mcs;
   dlsch0_harq->rvidx = dlsch_config_pdu->rv;
   dlsch0->g_pucch = dlsch_config_pdu->accumulated_delta_PUCCH;
+  dlsch0_harq->nscid = dlsch_config_pdu->nscid;
+  dlsch0_harq->dlDmrsScramblingId = dlsch_config_pdu->dlDmrsScramblingId;
   //get nrOfLayers from DCI info
   uint8_t Nl = 0;
   for (int i = 0; i < 12; i++) { // max 12 ports
@@ -279,15 +353,14 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response){
     // Note: we have to handle the thread IDs for this. To be revisited completely.
     thread_id = scheduled_response->thread_id;
     NR_UE_DLSCH_t *dlsch0 = NULL;
-    NR_UE_PDCCH *pdcch_vars = PHY_vars_UE_g[module_id][cc_id]->pdcch_vars[thread_id][0];
     NR_UE_ULSCH_t *ulsch = PHY_vars_UE_g[module_id][cc_id]->ulsch[thread_id][0];
     NR_UE_PUCCH *pucch_vars = PHY_vars_UE_g[module_id][cc_id]->pucch_vars[thread_id][0];
+    NR_UE_PDCCH_CONFIG *phy_pdcch_config = NULL;
 
     if(scheduled_response->dl_config != NULL){
       fapi_nr_dl_config_request_t *dl_config = scheduled_response->dl_config;
       fapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_config_pdu;
       fapi_nr_dl_config_dci_dl_pdu_rel15_t *pdcch_config;
-      pdcch_vars->nb_search_space = 0;
 
       for (int i = 0; i < dl_config->number_pdus; ++i){
         AssertFatal(dl_config->number_pdus < FAPI_NR_DL_CONFIG_LIST_NUM,"dl_config->number_pdus %d out of bounds\n",dl_config->number_pdus);
@@ -297,12 +370,16 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response){
 
         switch(dl_config->dl_config_list[i].pdu_type) {
           case FAPI_NR_DL_CONFIG_TYPE_DCI:
+            if (NULL == phy_pdcch_config) {
+              phy_pdcch_config = (NR_UE_PDCCH_CONFIG *)scheduled_response->phy_data;
+              phy_pdcch_config->nb_search_space = 0;
+            }
             pdcch_config = &dl_config->dl_config_list[i].dci_config_pdu.dci_config_rel15;
-            memcpy(&pdcch_vars->pdcch_config[pdcch_vars->nb_search_space],pdcch_config,sizeof(*pdcch_config));
-            pdcch_vars->nb_search_space = pdcch_vars->nb_search_space + 1;
-            pdcch_vars->sfn = scheduled_response->frame;
-            pdcch_vars->slot = slot;
-            LOG_D(PHY,"Number of DCI SearchSpaces %d\n",pdcch_vars->nb_search_space);
+            memcpy((void*)&phy_pdcch_config->pdcch_config[phy_pdcch_config->nb_search_space],(void*)pdcch_config,sizeof(*pdcch_config));
+            phy_pdcch_config->nb_search_space = phy_pdcch_config->nb_search_space + 1;
+            phy_pdcch_config->sfn = scheduled_response->frame;
+            phy_pdcch_config->slot = slot;
+            LOG_D(PHY,"Number of DCI SearchSpaces %d\n",phy_pdcch_config->nb_search_space);
             break;
           case FAPI_NR_DL_CONFIG_TYPE_CSI_IM:
             LOG_I(PHY,"Received CSI-IM PDU at FAPI\n");
diff --git a/openair1/SCHED_NR_UE/harq_nr.c b/openair1/SCHED_NR_UE/harq_nr.c
index 4afe5f41d3b50a9611c2ffb9246ba59a39377038..a9ff01d78a471cb5dc51016a3cbfd04f476c575e 100644
--- a/openair1/SCHED_NR_UE/harq_nr.c
+++ b/openair1/SCHED_NR_UE/harq_nr.c
@@ -307,7 +307,7 @@ void init_downlink_harq_status(NR_DL_UE_HARQ_t *dl_harq)
 {
   dl_harq->status = SCH_IDLE;
   dl_harq->first_rx = 1;
-  dl_harq->round  = 0;
+  dl_harq->DLround  = 0;
   dl_harq->DCINdi = 1;
   dl_harq->ack = DL_ACKNACK_NO_SET;
 }
@@ -334,60 +334,38 @@ void downlink_harq_process(NR_DL_UE_HARQ_t *dl_harq, int harq_pid, int ndi, int
   if (rnti_type == _SI_RNTI_ ||
       rnti_type == _P_RNTI_ ||
       rnti_type == _RA_RNTI_) {
-    dl_harq->round = 0;
+    dl_harq->DLround = 0;
     dl_harq->status = ACTIVE;
     dl_harq->first_rx = 1;
-  }
-  else{
-    switch(rv){
-      case 0:
-        dl_harq->round = 0;
-        dl_harq->status = ACTIVE;
-        dl_harq->first_rx = 1;
-        if (dl_harq->DCINdi == ndi)
-          LOG_E(PHY,"Warning! rv %d indicates new transmission but new ndi %d is the same as old ndi %d\n",rv,ndi,dl_harq->DCINdi);
-        dl_harq->DCINdi = ndi;
-        break;
-      case 1:
-        dl_harq->round = 3;
-        dl_harq->status = ACTIVE;
-        dl_harq->first_rx = 0;
-        if (dl_harq->DCINdi != ndi) {
-          LOG_E(PHY,"Missed previous DCI detections. NDI toggled but rv %d does not correspond to first reception\n",rv);
-          dl_harq->first_rx = 1;
-          dl_harq->DCINdi = ndi;
-        }
-        else if (dl_harq->ack == 1)
-          dl_harq->status = SCH_IDLE;
-        break;
-      case 2:
-        dl_harq->round = 1;
-        dl_harq->status = ACTIVE;
-        dl_harq->first_rx = 0;
-        if (dl_harq->DCINdi != ndi) {
-          LOG_E(PHY,"Missed previous DCI detections. NDI toggled but rv %d does not correspond to first reception\n",rv);
-          dl_harq->first_rx = 1;
-          dl_harq->DCINdi = ndi;
-        }
-        else if (dl_harq->ack == 1)
-          dl_harq->status = SCH_IDLE;
-        break;
-      case 3:
-        dl_harq->round = 2;
-        dl_harq->status = ACTIVE;
-        dl_harq->first_rx = 0;
-        if (dl_harq->DCINdi != ndi) {
-          LOG_E(PHY,"Missed previous DCI detections. NDI toggled but rv %d does not correspond to first reception\n",rv);
-          dl_harq->first_rx = 1;
-          dl_harq->DCINdi = ndi;
-        }
-        else if (dl_harq->ack == 1)
-          dl_harq->status = SCH_IDLE;
-        break;
-      default:
-        AssertFatal(1==0,"Invalid value for rv %d\n",rv);
+  }  else {
+    LOG_D(PHY,"receive harq process: %p harqPid=%d, rv=%d, ndi=%d, rntiType=%d new transmission= %s\n",
+	  dl_harq, harq_pid, rv, ndi, rnti_type, dl_harq->DCINdi != ndi ? "yes":"no");
+    AssertFatal(rv<4 && rv>=0, "invalid redondancy version %d\n", rv);
+    
+    if (ndi!=dl_harq->DCINdi) {
+      if (dl_harq->ack == DL_NACK)
+        LOG_D(PHY,"New transmission on a harq pid (%d) never acknowledged\n", harq_pid);
+      else
+         LOG_D(PHY,"Starting new transmission on a harq pid (%d)\n", harq_pid);
+    } else {
+      if (dl_harq->ack != DL_NACK)
+        LOG_D(PHY,"gNB asked for retransmission even if we sent ACK\n");
+      else
+        LOG_D(PHY,"Starting retransmission on a harq pid (%d), rv (%d)\n", harq_pid, rv);
     }
-  }
 
+    if (ndi!=dl_harq->DCINdi) {
+      dl_harq->first_rx = true;
+      dl_harq->DLround = 0;
+    } else {
+      dl_harq->first_rx = false;
+      dl_harq->DLround++;
+    }
+    
+    dl_harq->status = ACTIVE;
+
+    dl_harq->DCINdi = ndi;
+    //dl_harq->status = SCH_IDLE;
+   }
 }
 
diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c
index ddddcd09e26c529149ecd4b71bbdfed21ad24af1..974e112990be5b84877a6e3a4eef08bec2168f9c 100644
--- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c
+++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c
@@ -87,7 +87,8 @@ void nr_fill_dl_indication(nr_downlink_indication_t *dl_ind,
                            fapi_nr_rx_indication_t *rx_ind,
                            UE_nr_rxtx_proc_t *proc,
                            PHY_VARS_NR_UE *ue,
-                           uint8_t gNB_id){
+                           uint8_t gNB_id,
+                           void *phy_data){
 
   memset((void*)dl_ind, 0, sizeof(nr_downlink_indication_t));
 
@@ -97,6 +98,7 @@ void nr_fill_dl_indication(nr_downlink_indication_t *dl_ind,
   dl_ind->frame     = proc->frame_rx;
   dl_ind->slot      = proc->nr_slot_rx;
   dl_ind->thread_id = proc->thread_id;
+  dl_ind->phy_data  = phy_data;
 
   if (dci_ind) {
 
@@ -360,7 +362,7 @@ void nr_ue_measurement_procedures(uint16_t l,
 
 static void nr_ue_pbch_procedures(uint8_t gNB_id,
 			   PHY_VARS_NR_UE *ue,
-				  UE_nr_rxtx_proc_t *proc,int estimateSz, struct complex16 dl_ch_estimates[][estimateSz])
+				  UE_nr_rxtx_proc_t *proc,int estimateSz, struct complex16 dl_ch_estimates[][estimateSz], NR_UE_PDCCH_CONFIG *phy_pdcch_config)
 {
   int ret = 0;
 
@@ -380,7 +382,8 @@ static void nr_ue_pbch_procedures(uint8_t gNB_id,
                    gNB_id,
                    (ue->frame_parms.ssb_index)&7,
                    SISO,
-		   &result);
+                   phy_pdcch_config,
+                   &result);
 
   if (ret==0) {
 
@@ -486,6 +489,9 @@ unsigned int nr_get_tx_amp(int power_dBm, int power_max_dBm, int N_RB_UL, int nb
 int nr_ue_pdcch_procedures(uint8_t gNB_id,
                            PHY_VARS_NR_UE *ue,
                            UE_nr_rxtx_proc_t *proc,
+                           int32_t pdcch_est_size,
+                           int32_t pdcch_dl_ch_estimates[][pdcch_est_size],
+                           NR_UE_PDCCH_CONFIG *phy_pdcch_config,
                            int n_ss)
 {
   int frame_rx = proc->frame_rx;
@@ -494,13 +500,16 @@ int nr_ue_pdcch_procedures(uint8_t gNB_id,
   fapi_nr_dci_indication_t *dci_ind = calloc(1, sizeof(*dci_ind));
   nr_downlink_indication_t dl_indication;
 
-  NR_UE_PDCCH *pdcch_vars = ue->pdcch_vars[proc->thread_id][gNB_id];
-  fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15 = &pdcch_vars->pdcch_config[n_ss];
+  fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15 = &phy_pdcch_config->pdcch_config[n_ss];
 
   start_meas(&ue->dlsch_rx_pdcch_stats);
 
+  /// PDCCH/DCI e-sequence (input to rate matching).
+  int32_t pdcch_e_rx_size = NR_MAX_PDCCH_SIZE;
+  int16_t pdcch_e_rx[pdcch_e_rx_size];
+
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RX_PDCCH, VCD_FUNCTION_IN);
-  nr_rx_pdcch(ue, proc, rel15);
+  nr_rx_pdcch(ue, proc, pdcch_est_size, pdcch_dl_ch_estimates, pdcch_e_rx, rel15);
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RX_PDCCH, VCD_FUNCTION_OUT);
   
 
@@ -511,7 +520,7 @@ int nr_ue_pdcch_procedures(uint8_t gNB_id,
 	 n_ss);
 #endif
 
-  dci_cnt = nr_dci_decoding_procedure(ue, proc, dci_ind, rel15);
+  dci_cnt = nr_dci_decoding_procedure(ue, proc, pdcch_e_rx, dci_ind, rel15, phy_pdcch_config);
 
 #ifdef NR_PDCCH_SCHED_DEBUG
   LOG_I(PHY,"<-NR_PDCCH_PHY_PROCEDURES_LTE_UE (nr_ue_pdcch_procedures)-> Ending function nr_dci_decoding_procedure() -> dci_cnt=%u\n",dci_cnt);
@@ -531,11 +540,13 @@ int nr_ue_pdcch_procedures(uint8_t gNB_id,
   ue->pdcch_vars[proc->thread_id][gNB_id]->dci_received += dci_cnt;
 
   dci_ind->number_of_dcis = dci_cnt;
+
   // fill dl_indication message
-  nr_fill_dl_indication(&dl_indication, dci_ind, NULL, proc, ue, gNB_id);
+  nr_fill_dl_indication(&dl_indication, dci_ind, NULL, proc, ue, gNB_id, phy_pdcch_config);
   //  send to mac
   ue->if_inst->dl_indication(&dl_indication, NULL);
 
+
   stop_meas(&ue->dlsch_rx_pdcch_stats);
     
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_PDCCH_PROCEDURES, VCD_FUNCTION_OUT);
@@ -580,6 +591,8 @@ int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int gNB_
                                       nr_slot_rx,
                                       get_dmrs_port(aatx,dlsch0_harq->dmrs_ports),
                                       m,
+                                      dlsch0_harq->nscid,
+                                      dlsch0_harq->dlDmrsScramblingId,
                                       BWPStart,
                                       dlsch0_harq->dmrsConfigType,
                                       ue->frame_parms.first_carrier_offset+(BWPStart + pdsch_start_rb)*12,
@@ -799,16 +812,16 @@ bool nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue,
 
     switch (pdsch) {
       case RA_PDSCH:
-        nr_fill_dl_indication(&dl_indication, NULL, rx_ind, proc, ue, gNB_id);
+        nr_fill_dl_indication(&dl_indication, NULL, rx_ind, proc, ue, gNB_id, NULL);
         nr_fill_rx_indication(rx_ind, FAPI_NR_RX_PDU_TYPE_RAR, gNB_id, ue, dlsch0, NULL, number_pdus, proc, NULL);
         ue->UE_mode[gNB_id] = RA_RESPONSE;
         break;
       case PDSCH:
-        nr_fill_dl_indication(&dl_indication, NULL, rx_ind, proc, ue, gNB_id);
+        nr_fill_dl_indication(&dl_indication, NULL, rx_ind, proc, ue, gNB_id, NULL);
         nr_fill_rx_indication(rx_ind, FAPI_NR_RX_PDU_TYPE_DLSCH, gNB_id, ue, dlsch0, NULL, number_pdus, proc, NULL);
         break;
       case SI_PDSCH:
-        nr_fill_dl_indication(&dl_indication, NULL, rx_ind, proc, ue, gNB_id);
+        nr_fill_dl_indication(&dl_indication, NULL, rx_ind, proc, ue, gNB_id, NULL);
         nr_fill_rx_indication(rx_ind, FAPI_NR_RX_PDU_TYPE_SIB, gNB_id, ue, dlsch0, NULL, number_pdus, proc, NULL);
         break;
       default:
@@ -1366,6 +1379,7 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,
                            UE_nr_rxtx_proc_t *proc,
                            uint8_t gNB_id,
                            uint8_t dlsch_parallel,
+                           NR_UE_PDCCH_CONFIG *phy_pdcch_config,
                            notifiedFIFO_t *txFifo
                            )
 {                                         
@@ -1373,10 +1387,9 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,
   int nr_slot_rx = proc->nr_slot_rx;
   int slot_pbch;
   int slot_ssb;
-  NR_UE_PDCCH *pdcch_vars  = ue->pdcch_vars[proc->thread_id][0];
   fapi_nr_config_request_t *cfg = &ue->nrUE_config;
 
-  uint8_t nb_symb_pdcch = pdcch_vars->nb_search_space > 0 ? pdcch_vars->pdcch_config[0].coreset.duration : 0;
+  uint8_t nb_symb_pdcch = phy_pdcch_config->nb_search_space > 0 ? phy_pdcch_config->pdcch_config[0].coreset.duration : 0;
   uint8_t dci_cnt = 0;
   NR_DL_FRAME_PARMS *fp = &ue->frame_parms;
   
@@ -1395,8 +1408,8 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,
   int coreset_nb_rb=0;
   int coreset_start_rb=0;
 
-  if (pdcch_vars->nb_search_space > 0)
-    get_coreset_rballoc(pdcch_vars->pdcch_config[0].coreset.frequency_domain_resource,&coreset_nb_rb,&coreset_start_rb);
+  if (phy_pdcch_config->nb_search_space > 0)
+    get_coreset_rballoc(phy_pdcch_config->pdcch_config[0].coreset.frequency_domain_resource,&coreset_nb_rb,&coreset_start_rb);
 
   slot_pbch = is_pbch_in_slot(cfg, frame_rx, nr_slot_rx, fp);
   slot_ssb  = is_ssb_in_slot(cfg, frame_rx, nr_slot_rx, fp);
@@ -1405,9 +1418,11 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,
   if (slot_ssb) {
     VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP_PBCH, VCD_FUNCTION_IN);
     LOG_D(PHY," ------  PBCH ChannelComp/LLR: frame.slot %d.%d ------  \n", frame_rx%1024, nr_slot_rx);
-    const int estimateSz=7*2*sizeof(int)*fp->ofdm_symbol_size;
+
+    const int estimateSz = fp->symbols_per_slot * fp->ofdm_symbol_size;
     __attribute__ ((aligned(32))) struct complex16 dl_ch_estimates[fp->nb_antennas_rx][estimateSz];
-    __attribute__ ((aligned(32))) struct complex16 dl_ch_estimates_time[fp->nb_antennas_rx][estimateSz];
+    __attribute__ ((aligned(32))) struct complex16 dl_ch_estimates_time[fp->nb_antennas_rx][fp->ofdm_symbol_size];
+
     for (int i=1; i<4; i++) {
 
       nr_slot_fep(ue,
@@ -1415,7 +1430,6 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,
                   (ue->symbol_offset+i)%(fp->symbols_per_slot),
                   nr_slot_rx);
 
-
       start_meas(&ue->dlsch_channel_estimation_stats);
       nr_pbch_channel_estimation(ue, estimateSz, dl_ch_estimates, dl_ch_estimates_time,proc,gNB_id,nr_slot_rx,(ue->symbol_offset+i)%(fp->symbols_per_slot),i-1,(fp->ssb_index)&7,fp->half_frame_bit);
       stop_meas(&ue->dlsch_channel_estimation_stats);
@@ -1426,14 +1440,15 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,
     if ((ue->decode_MIB == 1) && slot_pbch) {
 
       LOG_D(PHY," ------  Decode MIB: frame.slot %d.%d ------  \n", frame_rx%1024, nr_slot_rx);
-      nr_ue_pbch_procedures(gNB_id, ue, proc, estimateSz, dl_ch_estimates);
+      nr_ue_pbch_procedures(gNB_id, ue, proc, estimateSz, dl_ch_estimates, phy_pdcch_config);
 
       if (ue->no_timing_correction==0) {
         LOG_D(PHY,"start adjust sync slot = %d no timing %d\n", nr_slot_rx, ue->no_timing_correction);
         nr_adjust_synch_ue(fp,
                            ue,
                            gNB_id,
-			   estimateSz, dl_ch_estimates_time,
+                           fp->ofdm_symbol_size,
+                           dl_ch_estimates_time,
                            frame_rx,
                            nr_slot_rx,
                            0,
@@ -1466,13 +1481,17 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,
                 nr_slot_rx);
   }
 
+    // Hold the channel estimates in frequency domain.
+  int32_t pdcch_est_size = ((((fp->symbols_per_slot*(fp->ofdm_symbol_size+LTE_CE_FILTER_LENGTH))+15)/16)*16);
+  __attribute__ ((aligned(16))) int32_t pdcch_dl_ch_estimates[4*fp->nb_antennas_rx][pdcch_est_size];
+
   dci_cnt = 0;
-  for(int n_ss = 0; n_ss<pdcch_vars->nb_search_space; n_ss++) {
+  for(int n_ss = 0; n_ss<phy_pdcch_config->nb_search_space; n_ss++) {
     for (uint16_t l=0; l<nb_symb_pdcch; l++) {
 
       // note: this only works if RBs for PDCCH are contigous!
       LOG_D(PHY, "pdcch_channel_estimation: first_carrier_offset %d, BWPStart %d, coreset_start_rb %d, coreset_nb_rb %d\n",
-            fp->first_carrier_offset, pdcch_vars->pdcch_config[n_ss].BWPStart, coreset_start_rb, coreset_nb_rb);
+            fp->first_carrier_offset, phy_pdcch_config->pdcch_config[n_ss].BWPStart, coreset_start_rb, coreset_nb_rb);
 
       if (coreset_nb_rb > 0)
         nr_pdcch_channel_estimation(ue,
@@ -1480,13 +1499,16 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,
                                     gNB_id,
                                     nr_slot_rx,
                                     l,
-                                    fp->first_carrier_offset+(pdcch_vars->pdcch_config[n_ss].BWPStart + coreset_start_rb)*12,
-                                    coreset_nb_rb);
+                                    phy_pdcch_config->pdcch_config[n_ss].coreset.pdcch_dmrs_scrambling_id,
+                                    fp->first_carrier_offset+(phy_pdcch_config->pdcch_config[n_ss].BWPStart + coreset_start_rb)*12,
+                                    coreset_nb_rb,
+                                    pdcch_est_size,
+                                    pdcch_dl_ch_estimates);
 
       stop_meas(&ue->ofdm_demod_stats);
 
     }
-    dci_cnt = dci_cnt + nr_ue_pdcch_procedures(gNB_id, ue, proc, n_ss);
+    dci_cnt = dci_cnt + nr_ue_pdcch_procedures(gNB_id, ue, proc, pdcch_est_size, pdcch_dl_ch_estimates, phy_pdcch_config, n_ss);
   }
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP_PDCCH, VCD_FUNCTION_OUT);
 
diff --git a/openair1/SCHED_UE/phy_procedures_lte_ue.c b/openair1/SCHED_UE/phy_procedures_lte_ue.c
index b02f24e04eafcd5e77e64fd3e38f1433dfc060cf..aa0ff0db80fe9506d796f9f927464e11add22a38 100644
--- a/openair1/SCHED_UE/phy_procedures_lte_ue.c
+++ b/openair1/SCHED_UE/phy_procedures_lte_ue.c
@@ -574,7 +574,7 @@ void get_cqipmiri_params(PHY_VARS_UE *ue,
   }
 }
 
-PUCCH_FMT_t get_pucch_format(lte_frame_type_t frame_type,
+PUCCH_FMT_t get_pucch_format(frame_type_t frame_type,
                              lte_prefix_type_t cyclic_prefix_type,
                              uint8_t SR_payload,
                              uint8_t nb_cw,
@@ -4870,109 +4870,3 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,
   LOG_D(PHY," ****** end RX-Chain  for AbsSubframe %d.%d ******  \n", frame_rx%1024, subframe_rx);
   return (0);
 }
-
-
-void phy_procedures_UE_lte(PHY_VARS_UE *ue,
-                           UE_rxtx_proc_t *proc,
-                           uint8_t eNB_id,
-                           uint8_t abstraction_flag,
-                           uint8_t do_pdcch_flag,
-                           runmode_t mode) {
-  MessageDef   *msg_p;
-  int           result;
-  int           frame_rx = proc->frame_rx;
-  int           frame_tx = proc->frame_tx;
-  int           subframe_rx = proc->subframe_rx;
-  int           subframe_tx = proc->subframe_tx;
-  UE_L2_STATE_t ret;
-  int slot;
-
-  if (ue->mac_enabled == 0) {
-    ue->UE_mode[eNB_id]=PUSCH;
-  }
-
-  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_LTE,1);
-
-  if ( LOG_DEBUGFLAG(UE_TIMING)) {
-    start_meas(&ue->phy_proc[ue->current_thread_id[subframe_rx]]);
-  }
-  do {
-    // Checks if a message has been sent to PHY sub-task
-    itti_poll_msg (TASK_PHY_UE, &msg_p);
-
-    if (msg_p != NULL) {
-      switch (ITTI_MSG_ID(msg_p)) {
-        case PHY_FIND_CELL_REQ:
-          LOG_I(PHY, "[UE ] Received %s\n", ITTI_MSG_NAME (msg_p));
-          /* TODO process the message */
-          break;
-
-        default:
-          LOG_E(PHY, "[UE %ld] Received unexpected message %s\n", ITTI_MSG_DESTINATION_INSTANCE (msg_p), ITTI_MSG_NAME (msg_p));
-          break;
-      }
-
-      result = itti_free (ITTI_MSG_ORIGIN_ID(msg_p), msg_p);
-      AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
-    }
-  } while(msg_p != NULL);
-
-  for (slot=0; slot<2; slot++) {
-    if ((subframe_select(&ue->frame_parms,subframe_tx)==SF_UL)||
-        (ue->frame_parms.frame_type == FDD)) {
-      phy_procedures_UE_TX(ue,proc,eNB_id,abstraction_flag,mode);
-    }
-
-    if ((subframe_select(&ue->frame_parms,subframe_rx)==SF_DL) ||
-        (ue->frame_parms.frame_type == FDD)) {
-      phy_procedures_UE_RX(ue,proc,eNB_id,abstraction_flag,do_pdcch_flag,mode);
-    }
-
-    if ((subframe_select(&ue->frame_parms,subframe_tx)==SF_S) &&
-        (slot==1)) {
-      phy_procedures_UE_S_TX(ue,eNB_id,abstraction_flag);
-    }
-
-    if ((subframe_select(&ue->frame_parms,subframe_rx)==SF_S) &&
-        (slot==0)) {
-      phy_procedures_UE_RX(ue,proc,eNB_id,abstraction_flag,do_pdcch_flag,mode);
-    }
-
-    if (ue->mac_enabled==1) {
-      if (slot==0) {
-        //LOG_I(PHY,"[UE %d] Frame %d, subframe %d, star ue_scheduler\n", ue->Mod_id,frame_rx,subframe_tx);
-        ret = ue_scheduler(ue->Mod_id,
-                           frame_rx,
-                           subframe_rx,
-                           frame_tx,
-                           subframe_tx,
-                           subframe_select(&ue->frame_parms,subframe_tx),
-                           eNB_id,
-                           0/*FIXME CC_id*/);
-
-        if (ret == CONNECTION_LOST) {
-          LOG_E(PHY,"[UE %d] Frame %d, subframe %d RRC Connection lost, returning to PRACH\n",ue->Mod_id,
-                frame_rx,subframe_tx);
-          ue->UE_mode[eNB_id] = PRACH;
-          //      mac_xface->macphy_exit("Connection lost");
-        } else if (ret == PHY_RESYNCH) {
-          LOG_E(PHY,"[UE %d] Frame %d, subframe %d RRC Connection lost, trying to resynch\n",
-                ue->Mod_id,
-                frame_rx,subframe_tx);
-          ue->UE_mode[eNB_id] = RESYNCH;
-          //     mac_xface->macphy_exit("Connection lost");
-        } else if (ret == PHY_HO_PRACH) {
-          LOG_I(PHY,"[UE %d] Frame %d, subframe %d, return to PRACH and perform a contention-free access\n",
-                ue->Mod_id,frame_rx,subframe_tx);
-          ue->UE_mode[eNB_id] = PRACH;
-        }
-      }
-    }
-
-    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_LTE,0);
-
-    if (LOG_DEBUGFLAG(UE_TIMING)) {
-      stop_meas(&ue->phy_proc[ue->current_thread_id[subframe_rx]]);
-    }
-  } // slot
-}
diff --git a/openair1/SCHED_UE/sched_UE.h b/openair1/SCHED_UE/sched_UE.h
index 32702b114893329bf0db88291e2df50be8661a34..0dbb77963026ed905922d2568b4dfbc448ca05c0 100644
--- a/openair1/SCHED_UE/sched_UE.h
+++ b/openair1/SCHED_UE/sched_UE.h
@@ -278,7 +278,7 @@ void dump_dlsch2(PHY_VARS_UE *phy_vars_ue,uint8_t eNB_id,uint8_t subframe, unsig
 
 int is_srs_occasion_common(LTE_DL_FRAME_PARMS *frame_parms,int frame_tx,int subframe_tx);
 
-void compute_srs_pos(lte_frame_type_t frameType,uint16_t isrs,uint16_t *psrsPeriodicity,uint16_t *psrsOffset);
+void compute_srs_pos(frame_type_t frameType,uint16_t isrs,uint16_t *psrsPeriodicity,uint16_t *psrsOffset);
 
 /*@}*/
 
diff --git a/openair1/SIMULATION/LTE_PHY/BLER_SIMULATIONS/AWGN/AWGN_results/bler_tx1_chan18_nrx1_mcs28.csv b/openair1/SIMULATION/LTE_PHY/BLER_SIMULATIONS/AWGN/AWGN_results/bler_tx1_chan18_nrx1_mcs28.csv
new file mode 100644
index 0000000000000000000000000000000000000000..11771acc8719db9304be2e119793bb764a9adec2
--- /dev/null
+++ b/openair1/SIMULATION/LTE_PHY/BLER_SIMULATIONS/AWGN/AWGN_results/bler_tx1_chan18_nrx1_mcs28.csv
@@ -0,0 +1,21 @@
+SNR; MCS; TBS; rate; err0; trials0; err1; trials1; err2; trials2; err3; trials3; dci_err
+16.000000;27;15840;0.704000;5002;5002;0;0;0;0;0;0;0
+16.100000;27;15840;0.704000;5002;5002;0;0;0;0;0;0;0
+16.200000;27;15840;0.704000;5002;5002;0;0;0;0;0;0;0
+16.300000;27;15840;0.704000;5002;5002;0;0;0;0;0;0;0
+16.400000;27;15840;0.704000;4999;5002;0;0;0;0;0;0;0
+16.500000;27;15840;0.704000;4981;5002;0;0;0;0;0;0;0
+16.600000;27;15840;0.704000;4887;5002;0;0;0;0;0;0;0
+16.700000;27;15840;0.704000;4688;5002;0;0;0;0;0;0;0
+16.800000;27;15840;0.704000;4176;5002;0;0;0;0;0;0;0
+16.900000;27;15840;0.704000;3340;5002;0;0;0;0;0;0;0
+17.000000;27;15840;0.704000;2386;5002;0;0;0;0;0;0;0
+17.100000;27;15840;0.704000;1510;5002;0;0;0;0;0;0;0
+17.200000;27;15840;0.704000;1000;5552;0;0;0;0;0;0;0
+17.300000;27;15840;0.704000;926;10000;0;0;0;0;0;0;0
+17.400000;27;15840;0.704000;516;10000;0;0;0;0;0;0;0
+17.500000;27;15840;0.704000;287;10000;0;0;0;0;0;0;0
+17.600000;27;15840;0.704000;198;10000;0;0;0;0;0;0;0
+17.700000;27;15840;0.704000;135;10000;0;0;0;0;0;0;0
+17.800000;27;15840;0.704000;102;10000;0;0;0;0;0;0;0
+17.900000;27;15840;0.704000;94;10000;0;0;0;0;0;0;0
diff --git a/openair1/SIMULATION/LTE_PHY/pdcchsim.c b/openair1/SIMULATION/LTE_PHY/pdcchsim.c
index bd2c2d66b9653f7daa9f71985df875c5f7cd0dc4..50910290c391fb979c193d3989dc95240331fa67 100644
--- a/openair1/SIMULATION/LTE_PHY/pdcchsim.c
+++ b/openair1/SIMULATION/LTE_PHY/pdcchsim.c
@@ -415,7 +415,7 @@ int main(int argc, char **argv) {
   uint8_t harq_pid;
   uint8_t phich_ACK;
   uint8_t num_phich_interf = 0;
-  lte_frame_type_t frame_type=TDD;
+  frame_type_t frame_type=TDD;
   //  int re_offset;
   //  uint32_t *txptr;
   int aarx;
diff --git a/openair1/SIMULATION/NR_PHY/BLER_SIMULATIONS/AWGN/AWGN_results/mcs0_awgn_5G.csv b/openair1/SIMULATION/NR_PHY/BLER_SIMULATIONS/AWGN/AWGN_results/mcs0_awgn_5G.csv
new file mode 100644
index 0000000000000000000000000000000000000000..ae7824fe1e87e72f27f905f1e26522af02556860
--- /dev/null
+++ b/openair1/SIMULATION/NR_PHY/BLER_SIMULATIONS/AWGN/AWGN_results/mcs0_awgn_5G.csv
@@ -0,0 +1,62 @@
+SNR;MCS;TBS;rate;err0;trials0;err1;trials1;err2;trials2;err3;trials3;dci_err
+-4;0;1864;0.2344;1500;1500;0;0;0;0;0;0;0
+-3.9;0;1864;0.2344;1500;1500;0;0;0;0;0;0;0
+-3.8;0;1864;0.2344;1500;1500;0;0;0;0;0;0;0
+-3.7;0;1864;0.2344;1500;1500;0;0;0;0;0;0;0
+-3.6;0;1864;0.2344;1500;1500;0;0;0;0;0;0;0
+-3.5;0;1864;0.2344;1500;1500;0;0;0;0;0;0;0
+-3.4;0;1864;0.2344;1500;1500;0;0;0;0;0;0;0
+-3.3;0;1864;0.2344;1500;1500;0;0;0;0;0;0;0
+-3.2;0;1864;0.2344;1500;1500;0;0;0;0;0;0;0
+-3.1;0;1864;0.2344;1500;1500;0;0;0;0;0;0;0
+-3;0;1864;0.2344;1500;1500;0;0;0;0;0;0;0
+-2.9;0;1864;0.2344;1500;1500;0;0;0;0;0;0;0
+-2.8;0;1864;0.2344;1500;1500;0;0;0;0;0;0;0
+-2.7;0;1864;0.2344;1500;1500;0;0;0;0;0;0;0
+-2.6;0;1864;0.2344;1500;1500;0;0;0;0;0;0;0
+-2.5;0;1864;0.2344;1500;1500;0;0;0;0;0;0;0
+-2.4;0;1864;0.2344;1500;1500;0;0;0;0;0;0;0
+-2.3;0;1864;0.2344;1500;1500;0;0;0;0;0;0;0
+-2.2;0;1864;0.2344;1500;1500;0;0;0;0;0;0;0
+-2.1;0;1864;0.2344;1500;1500;0;0;0;0;0;0;0
+-2;0;1864;0.2344;1500;1500;0;0;0;0;0;0;0
+-1.9;0;1864;0.2344;1499;1500;0;0;0;0;0;0;0
+-1.8;0;1864;0.2344;1499;1500;0;0;0;0;0;0;0
+-1.7;0;1864;0.2344;1498;1500;0;0;0;0;0;0;0
+-1.6;0;1864;0.2344;1498;1500;0;0;0;0;0;0;0
+-1.5;0;1864;0.2344;1497;1500;0;0;0;0;0;0;0
+-1.4;0;1864;0.2344;1445;1500;0;0;0;0;0;0;0
+-1.3;0;1864;0.2344;1394;1500;0;0;0;0;0;0;0
+-1.2;0;1864;0.2344;1346;1500;0;0;0;0;0;0;0
+-1.1;0;1864;0.2344;1299;1500;0;0;0;0;0;0;0
+-1;0;1864;0.2344;1253;1500;0;0;0;0;0;0;0
+-0.9;0;1864;0.2344;980;1500;0;0;0;0;0;0;0
+-0.8;0;1864;0.2344;767;1500;0;0;0;0;0;0;0
+-0.7;0;1864;0.2344;600;1500;0;0;0;0;0;0;0
+-0.6;0;1864;0.2344;469;1500;0;0;0;0;0;0;0
+-0.5;0;1864;0.2344;367;1500;0;0;0;0;0;0;0
+-0.4;0;1864;0.2344;215;1500;0;0;0;0;0;0;0
+-0.3;0;1864;0.2344;126;1500;0;0;0;0;0;0;0
+-0.2;0;1864;0.2344;74;1500;0;0;0;0;0;0;0
+-0.1;0;1864;0.2344;43;1500;0;0;0;0;0;0;0
+0;0;1864;0.2344;26;1500;0;0;0;0;0;0;0
+0.1;0;1864;0.2344;12;1500;0;0;0;0;0;0;0
+0.2;0;1864;0.2344;5;1500;0;0;0;0;0;0;0
+0.3;0;1864;0.2344;2;1500;0;0;0;0;0;0;0
+0.4;0;1864;0.2344;1;1500;0;0;0;0;0;0;0
+0.5;0;1864;0.2344;1;1500;0;0;0;0;0;0;0
+0.6;0;1864;0.2344;0;1500;0;0;0;0;0;0;0
+0.7;0;1864;0.2344;0;1500;0;0;0;0;0;0;0
+0.8;0;1864;0.2344;0;1500;0;0;0;0;0;0;0
+0.9;0;1864;0.2344;0;1500;0;0;0;0;0;0;0
+1;0;1864;0.2344;0;1500;0;0;0;0;0;0;0
+1.1;0;1864;0.2344;0;1500;0;0;0;0;0;0;0
+1.2;0;1864;0.2344;0;1500;0;0;0;0;0;0;0
+1.3;0;1864;0.2344;0;1500;0;0;0;0;0;0;0
+1.4;0;1864;0.2344;0;1500;0;0;0;0;0;0;0
+1.5;0;1864;0.2344;0;1500;0;0;0;0;0;0;0
+1.6;0;1864;0.2344;0;1500;0;0;0;0;0;0;0
+1.7;0;1864;0.2344;0;1500;0;0;0;0;0;0;0
+1.8;0;1864;0.2344;0;1500;0;0;0;0;0;0;0
+1.9;0;1864;0.2344;0;1500;0;0;0;0;0;0;0
+2;0;1864;0.2344;0;1500;0;0;0;0;0;0;0
diff --git a/openair1/SIMULATION/NR_PHY/BLER_SIMULATIONS/AWGN/AWGN_results/mcs10_awgn_5G.csv b/openair1/SIMULATION/NR_PHY/BLER_SIMULATIONS/AWGN/AWGN_results/mcs10_awgn_5G.csv
new file mode 100644
index 0000000000000000000000000000000000000000..8d1ff3ebb68575f37ece9529246fd548540b3d99
--- /dev/null
+++ b/openair1/SIMULATION/NR_PHY/BLER_SIMULATIONS/AWGN/AWGN_results/mcs10_awgn_5G.csv
@@ -0,0 +1,92 @@
+SNR;MCS;TBS;rate;err0;trials0;err1;trials1;err2;trials2;err3;trials3;dci_err
+3;10;10504;1.3281;1500;1500;0;0;0;0;0;0;0
+3.1;10;10504;1.3281;1500;1500;0;0;0;0;0;0;0
+3.2;10;10504;1.3281;1500;1500;0;0;0;0;0;0;0
+3.3;10;10504;1.3281;1500;1500;0;0;0;0;0;0;0
+3.4;10;10504;1.3281;1500;1500;0;0;0;0;0;0;0
+3.5;10;10504;1.3281;1500;1500;0;0;0;0;0;0;0
+3.6;10;10504;1.3281;1500;1500;0;0;0;0;0;0;0
+3.7;10;10504;1.3281;1500;1500;0;0;0;0;0;0;0
+3.8;10;10504;1.3281;1500;1500;0;0;0;0;0;0;0
+3.9;10;10504;1.3281;1500;1500;0;0;0;0;0;0;0
+4;10;10504;1.3281;1500;1500;0;0;0;0;0;0;0
+4.1;10;10504;1.3281;1500;1500;0;0;0;0;0;0;0
+4.2;10;10504;1.3281;1500;1500;0;0;0;0;0;0;0
+4.3;10;10504;1.3281;1500;1500;0;0;0;0;0;0;0
+4.4;10;10504;1.3281;1500;1500;0;0;0;0;0;0;0
+4.5;10;10504;1.3281;1500;1500;0;0;0;0;0;0;0
+4.6;10;10504;1.3281;1500;1500;0;0;0;0;0;0;0
+4.7;10;10504;1.3281;1500;1500;0;0;0;0;0;0;0
+4.8;10;10504;1.3281;1500;1500;0;0;0;0;0;0;0
+4.9;10;10504;1.3281;1500;1500;0;0;0;0;0;0;0
+5;10;10504;1.3281;1500;1500;0;0;0;0;0;0;0
+5.1;10;10504;1.3281;1454;1500;0;0;0;0;0;0;0
+5.2;10;10504;1.3281;1410;1500;0;0;0;0;0;0;0
+5.3;10;10504;1.3281;1367;1500;0;0;0;0;0;0;0
+5.4;10;10504;1.3281;1325;1500;0;0;0;0;0;0;0
+5.5;10;10504;1.3281;1285;1500;0;0;0;0;0;0;0
+5.6;10;10504;1.3281;1026;1500;0;0;0;0;0;0;0
+5.7;10;10504;1.3281;819;1500;0;0;0;0;0;0;0
+5.8;10;10504;1.3281;654;1500;0;0;0;0;0;0;0
+5.9;10;10504;1.3281;522;1500;0;0;0;0;0;0;0
+6;10;10504;1.3281;417;1500;0;0;0;0;0;0;0
+6.1;10;10504;1.3281;309;1500;0;0;0;0;0;0;0
+6.2;10;10504;1.3281;229;1500;0;0;0;0;0;0;0
+6.3;10;10504;1.3281;169;1500;0;0;0;0;0;0;0
+6.4;10;10504;1.3281;125;1500;0;0;0;0;0;0;0
+6.5;10;10504;1.3281;93;1500;0;0;0;0;0;0;0
+6.6;10;10504;1.3281;64;1500;0;0;0;0;0;0;0
+6.7;10;10504;1.3281;44;1500;0;0;0;0;0;0;0
+6.8;10;10504;1.3281;31;1500;0;0;0;0;0;0;0
+6.9;10;10504;1.3281;21;1500;0;0;0;0;0;0;0
+7;10;10504;1.3281;15;1500;0;0;0;0;0;0;0
+7.1;10;10504;1.3281;7;1500;0;0;0;0;0;0;0
+7.2;10;10504;1.3281;3;1500;0;0;0;0;0;0;0
+7.3;10;10504;1.3281;1;1500;0;0;0;0;0;0;0
+7.4;10;10504;1.3281;1;1500;0;0;0;0;0;0;0
+7.5;10;10504;1.3281;0;1500;0;0;0;0;0;0;0
+7.6;10;10504;1.3281;0;1500;0;0;0;0;0;0;0
+7.7;10;10504;1.3281;0;1500;0;0;0;0;0;0;0
+7.8;10;10504;1.3281;0;1500;0;0;0;0;0;0;0
+7.9;10;10504;1.3281;0;1500;0;0;0;0;0;0;0
+8;10;10504;1.3281;0;1500;0;0;0;0;0;0;0
+8.1;10;10504;1.3281;0;1500;0;0;0;0;0;0;0
+8.2;10;10504;1.3281;0;1500;0;0;0;0;0;0;0
+8.3;10;10504;1.3281;0;1500;0;0;0;0;0;0;0
+8.4;10;10504;1.3281;0;1500;0;0;0;0;0;0;0
+8.5;10;10504;1.3281;0;1500;0;0;0;0;0;0;0
+8.6;10;10504;1.3281;0;1500;0;0;0;0;0;0;0
+8.7;10;10504;1.3281;0;1500;0;0;0;0;0;0;0
+8.8;10;10504;1.3281;0;1500;0;0;0;0;0;0;0
+8.9;10;10504;1.3281;0;1500;0;0;0;0;0;0;0
+9;10;10504;1.3281;0;1500;0;0;0;0;0;0;0
+9.1;10;10504;1.3281;0;1500;0;0;0;0;0;0;0
+9.2;10;10504;1.3281;0;1500;0;0;0;0;0;0;0
+9.3;10;10504;1.3281;0;1500;0;0;0;0;0;0;0
+9.4;10;10504;1.3281;0;1500;0;0;0;0;0;0;0
+9.5;10;10504;1.3281;0;1500;0;0;0;0;0;0;0
+9.6;10;10504;1.3281;0;1500;0;0;0;0;0;0;0
+9.7;10;10504;1.3281;0;1500;0;0;0;0;0;0;0
+9.8;10;10504;1.3281;0;1500;0;0;0;0;0;0;0
+9.9;10;10504;1.3281;0;1500;0;0;0;0;0;0;0
+10;10;10504;1.3281;0;1500;0;0;0;0;0;0;0
+10.1;10;10504;1.3281;0;1500;0;0;0;0;0;0;0
+10.2;10;10504;1.3281;0;1500;0;0;0;0;0;0;0
+10.3;10;10504;1.3281;0;1500;0;0;0;0;0;0;0
+10.4;10;10504;1.3281;0;1500;0;0;0;0;0;0;0
+10.5;10;10504;1.3281;0;1500;0;0;0;0;0;0;0
+10.6;10;10504;1.3281;0;1500;0;0;0;0;0;0;0
+10.7;10;10504;1.3281;0;1500;0;0;0;0;0;0;0
+10.8;10;10504;1.3281;0;1500;0;0;0;0;0;0;0
+10.9;10;10504;1.3281;0;1500;0;0;0;0;0;0;0
+11;10;10504;1.3281;0;1500;0;0;0;0;0;0;0
+11.1;10;10504;1.3281;0;1500;0;0;0;0;0;0;0
+11.2;10;10504;1.3281;0;1500;0;0;0;0;0;0;0
+11.3;10;10504;1.3281;0;1500;0;0;0;0;0;0;0
+11.4;10;10504;1.3281;0;1500;0;0;0;0;0;0;0
+11.5;10;10504;1.3281;0;1500;0;0;0;0;0;0;0
+11.6;10;10504;1.3281;0;1500;0;0;0;0;0;0;0
+11.7;10;10504;1.3281;0;1500;0;0;0;0;0;0;0
+11.8;10;10504;1.3281;0;1500;0;0;0;0;0;0;0
+11.9;10;10504;1.3281;0;1500;0;0;0;0;0;0;0
+12;10;10504;1.3281;0;1500;0;0;0;0;0;0;0
diff --git a/openair1/SIMULATION/NR_PHY/BLER_SIMULATIONS/AWGN/AWGN_results/mcs11_awgn_5G.csv b/openair1/SIMULATION/NR_PHY/BLER_SIMULATIONS/AWGN/AWGN_results/mcs11_awgn_5G.csv
new file mode 100644
index 0000000000000000000000000000000000000000..e581ab2ff169116050eabc4fbcaa5d0f5e695f6b
--- /dev/null
+++ b/openair1/SIMULATION/NR_PHY/BLER_SIMULATIONS/AWGN/AWGN_results/mcs11_awgn_5G.csv
@@ -0,0 +1,92 @@
+SNR;MCS;TBS;rate;err0;trials0;err1;trials1;err2;trials2;err3;trials3;dci_err
+3;11;11784;1.4766;1500;1500;0;0;0;0;0;0;0
+3.1;11;11784;1.4766;1500;1500;0;0;0;0;0;0;0
+3.2;11;11784;1.4766;1500;1500;0;0;0;0;0;0;0
+3.3;11;11784;1.4766;1500;1500;0;0;0;0;0;0;0
+3.4;11;11784;1.4766;1500;1500;0;0;0;0;0;0;0
+3.5;11;11784;1.4766;1500;1500;0;0;0;0;0;0;0
+3.6;11;11784;1.4766;1500;1500;0;0;0;0;0;0;0
+3.7;11;11784;1.4766;1500;1500;0;0;0;0;0;0;0
+3.8;11;11784;1.4766;1500;1500;0;0;0;0;0;0;0
+3.9;11;11784;1.4766;1500;1500;0;0;0;0;0;0;0
+4;11;11784;1.4766;1500;1500;0;0;0;0;0;0;0
+4.1;11;11784;1.4766;1500;1500;0;0;0;0;0;0;0
+4.2;11;11784;1.4766;1500;1500;0;0;0;0;0;0;0
+4.3;11;11784;1.4766;1500;1500;0;0;0;0;0;0;0
+4.4;11;11784;1.4766;1500;1500;0;0;0;0;0;0;0
+4.5;11;11784;1.4766;1500;1500;0;0;0;0;0;0;0
+4.6;11;11784;1.4766;1500;1500;0;0;0;0;0;0;0
+4.7;11;11784;1.4766;1500;1500;0;0;0;0;0;0;0
+4.8;11;11784;1.4766;1500;1500;0;0;0;0;0;0;0
+4.9;11;11784;1.4766;1500;1500;0;0;0;0;0;0;0
+5;11;11784;1.4766;1500;1500;0;0;0;0;0;0;0
+5.1;11;11784;1.4766;1500;1500;0;0;0;0;0;0;0
+5.2;11;11784;1.4766;1500;1500;0;0;0;0;0;0;0
+5.3;11;11784;1.4766;1500;1500;0;0;0;0;0;0;0
+5.4;11;11784;1.4766;1500;1500;0;0;0;0;0;0;0
+5.5;11;11784;1.4766;1500;1500;0;0;0;0;0;0;0
+5.6;11;11784;1.4766;1494;1500;0;0;0;0;0;0;0
+5.7;11;11784;1.4766;1489;1500;0;0;0;0;0;0;0
+5.8;11;11784;1.4766;1483;1500;0;0;0;0;0;0;0
+5.9;11;11784;1.4766;1477;1500;0;0;0;0;0;0;0
+6;11;11784;1.4766;1472;1500;0;0;0;0;0;0;0
+6.1;11;11784;1.4766;1367;1500;0;0;0;0;0;0;0
+6.2;11;11784;1.4766;1269;1500;0;0;0;0;0;0;0
+6.3;11;11784;1.4766;1179;1500;0;0;0;0;0;0;0
+6.4;11;11784;1.4766;1095;1500;0;0;0;0;0;0;0
+6.5;11;11784;1.4766;1016;1500;0;0;0;0;0;0;0
+6.6;11;11784;1.4766;762;1500;0;0;0;0;0;0;0
+6.7;11;11784;1.4766;571;1500;0;0;0;0;0;0;0
+6.8;11;11784;1.4766;428;1500;0;0;0;0;0;0;0
+6.9;11;11784;1.4766;320;1500;0;0;0;0;0;0;0
+7;11;11784;1.4766;240;1500;0;0;0;0;0;0;0
+7.1;11;11784;1.4766;169;1500;0;0;0;0;0;0;0
+7.2;11;11784;1.4766;119;1500;0;0;0;0;0;0;0
+7.3;11;11784;1.4766;83;1500;0;0;0;0;0;0;0
+7.4;11;11784;1.4766;59;1500;0;0;0;0;0;0;0
+7.5;11;11784;1.4766;41;1500;0;0;0;0;0;0;0
+7.6;11;11784;1.4766;24;1500;0;0;0;0;0;0;0
+7.7;11;11784;1.4766;14;1500;0;0;0;0;0;0;0
+7.8;11;11784;1.4766;8;1500;0;0;0;0;0;0;0
+7.9;11;11784;1.4766;5;1500;0;0;0;0;0;0;0
+8;11;11784;1.4766;3;1500;0;0;0;0;0;0;0
+8.1;11;11784;1.4766;1;1500;0;0;0;0;0;0;0
+8.2;11;11784;1.4766;1;1500;0;0;0;0;0;0;0
+8.3;11;11784;1.4766;0;1500;0;0;0;0;0;0;0
+8.4;11;11784;1.4766;0;1500;0;0;0;0;0;0;0
+8.5;11;11784;1.4766;0;1500;0;0;0;0;0;0;0
+8.6;11;11784;1.4766;0;1500;0;0;0;0;0;0;0
+8.7;11;11784;1.4766;0;1500;0;0;0;0;0;0;0
+8.8;11;11784;1.4766;0;1500;0;0;0;0;0;0;0
+8.9;11;11784;1.4766;0;1500;0;0;0;0;0;0;0
+9;11;11784;1.4766;0;1500;0;0;0;0;0;0;0
+9.1;11;11784;1.4766;0;1500;0;0;0;0;0;0;0
+9.2;11;11784;1.4766;0;1500;0;0;0;0;0;0;0
+9.3;11;11784;1.4766;0;1500;0;0;0;0;0;0;0
+9.4;11;11784;1.4766;0;1500;0;0;0;0;0;0;0
+9.5;11;11784;1.4766;0;1500;0;0;0;0;0;0;0
+9.6;11;11784;1.4766;0;1500;0;0;0;0;0;0;0
+9.7;11;11784;1.4766;0;1500;0;0;0;0;0;0;0
+9.8;11;11784;1.4766;0;1500;0;0;0;0;0;0;0
+9.9;11;11784;1.4766;0;1500;0;0;0;0;0;0;0
+10;11;11784;1.4766;0;1500;0;0;0;0;0;0;0
+10.1;11;11784;1.4766;0;1500;0;0;0;0;0;0;0
+10.2;11;11784;1.4766;0;1500;0;0;0;0;0;0;0
+10.3;11;11784;1.4766;0;1500;0;0;0;0;0;0;0
+10.4;11;11784;1.4766;0;1500;0;0;0;0;0;0;0
+10.5;11;11784;1.4766;0;1500;0;0;0;0;0;0;0
+10.6;11;11784;1.4766;0;1500;0;0;0;0;0;0;0
+10.7;11;11784;1.4766;0;1500;0;0;0;0;0;0;0
+10.8;11;11784;1.4766;0;1500;0;0;0;0;0;0;0
+10.9;11;11784;1.4766;0;1500;0;0;0;0;0;0;0
+11;11;11784;1.4766;0;1500;0;0;0;0;0;0;0
+11.1;11;11784;1.4766;0;1500;0;0;0;0;0;0;0
+11.2;11;11784;1.4766;0;1500;0;0;0;0;0;0;0
+11.3;11;11784;1.4766;0;1500;0;0;0;0;0;0;0
+11.4;11;11784;1.4766;0;1500;0;0;0;0;0;0;0
+11.5;11;11784;1.4766;0;1500;0;0;0;0;0;0;0
+11.6;11;11784;1.4766;0;1500;0;0;0;0;0;0;0
+11.7;11;11784;1.4766;0;1500;0;0;0;0;0;0;0
+11.8;11;11784;1.4766;0;1500;0;0;0;0;0;0;0
+11.9;11;11784;1.4766;0;1500;0;0;0;0;0;0;0
+12;11;11784;1.4766;0;1500;0;0;0;0;0;0;0
diff --git a/openair1/SIMULATION/NR_PHY/BLER_SIMULATIONS/AWGN/AWGN_results/mcs12_awgn_5G.csv b/openair1/SIMULATION/NR_PHY/BLER_SIMULATIONS/AWGN/AWGN_results/mcs12_awgn_5G.csv
new file mode 100644
index 0000000000000000000000000000000000000000..08825dec27894823859364fb91e9b1f9cc563f22
--- /dev/null
+++ b/openair1/SIMULATION/NR_PHY/BLER_SIMULATIONS/AWGN/AWGN_results/mcs12_awgn_5G.csv
@@ -0,0 +1,92 @@
+SNR;MCS;TBS;rate;err0;trials0;err1;trials1;err2;trials2;err3;trials3;dci_err
+3;12;13576;1.6953;1500;1500;0;0;0;0;0;0;0
+3.1;12;13576;1.6953;1500;1500;0;0;0;0;0;0;0
+3.2;12;13576;1.6953;1500;1500;0;0;0;0;0;0;0
+3.3;12;13576;1.6953;1500;1500;0;0;0;0;0;0;0
+3.4;12;13576;1.6953;1500;1500;0;0;0;0;0;0;0
+3.5;12;13576;1.6953;1500;1500;0;0;0;0;0;0;0
+3.6;12;13576;1.6953;1500;1500;0;0;0;0;0;0;0
+3.7;12;13576;1.6953;1500;1500;0;0;0;0;0;0;0
+3.8;12;13576;1.6953;1500;1500;0;0;0;0;0;0;0
+3.9;12;13576;1.6953;1500;1500;0;0;0;0;0;0;0
+4;12;13576;1.6953;1500;1500;0;0;0;0;0;0;0
+4.1;12;13576;1.6953;1500;1500;0;0;0;0;0;0;0
+4.2;12;13576;1.6953;1500;1500;0;0;0;0;0;0;0
+4.3;12;13576;1.6953;1500;1500;0;0;0;0;0;0;0
+4.4;12;13576;1.6953;1500;1500;0;0;0;0;0;0;0
+4.5;12;13576;1.6953;1500;1500;0;0;0;0;0;0;0
+4.6;12;13576;1.6953;1500;1500;0;0;0;0;0;0;0
+4.7;12;13576;1.6953;1500;1500;0;0;0;0;0;0;0
+4.8;12;13576;1.6953;1500;1500;0;0;0;0;0;0;0
+4.9;12;13576;1.6953;1500;1500;0;0;0;0;0;0;0
+5;12;13576;1.6953;1500;1500;0;0;0;0;0;0;0
+5.1;12;13576;1.6953;1500;1500;0;0;0;0;0;0;0
+5.2;12;13576;1.6953;1500;1500;0;0;0;0;0;0;0
+5.3;12;13576;1.6953;1500;1500;0;0;0;0;0;0;0
+5.4;12;13576;1.6953;1500;1500;0;0;0;0;0;0;0
+5.5;12;13576;1.6953;1500;1500;0;0;0;0;0;0;0
+5.6;12;13576;1.6953;1500;1500;0;0;0;0;0;0;0
+5.7;12;13576;1.6953;1500;1500;0;0;0;0;0;0;0
+5.8;12;13576;1.6953;1500;1500;0;0;0;0;0;0;0
+5.9;12;13576;1.6953;1500;1500;0;0;0;0;0;0;0
+6;12;13576;1.6953;1500;1500;0;0;0;0;0;0;0
+6.1;12;13576;1.6953;1500;1500;0;0;0;0;0;0;0
+6.2;12;13576;1.6953;1500;1500;0;0;0;0;0;0;0
+6.3;12;13576;1.6953;1500;1500;0;0;0;0;0;0;0
+6.4;12;13576;1.6953;1500;1500;0;0;0;0;0;0;0
+6.5;12;13576;1.6953;1500;1500;0;0;0;0;0;0;0
+6.6;12;13576;1.6953;1498;1500;0;0;0;0;0;0;0
+6.7;12;13576;1.6953;1495;1500;0;0;0;0;0;0;0
+6.8;12;13576;1.6953;1493;1500;0;0;0;0;0;0;0
+6.9;12;13576;1.6953;1491;1500;0;0;0;0;0;0;0
+7;12;13576;1.6953;1488;1500;0;0;0;0;0;0;0
+7.1;12;13576;1.6953;1357;1500;0;0;0;0;0;0;0
+7.2;12;13576;1.6953;1238;1500;0;0;0;0;0;0;0
+7.3;12;13576;1.6953;1129;1500;0;0;0;0;0;0;0
+7.4;12;13576;1.6953;1029;1500;0;0;0;0;0;0;0
+7.5;12;13576;1.6953;939;1500;0;0;0;0;0;0;0
+7.6;12;13576;1.6953;632;1500;0;0;0;0;0;0;0
+7.7;12;13576;1.6953;425;1500;0;0;0;0;0;0;0
+7.8;12;13576;1.6953;286;1500;0;0;0;0;0;0;0
+7.9;12;13576;1.6953;193;1500;0;0;0;0;0;0;0
+8;12;13576;1.6953;130;1500;0;0;0;0;0;0;0
+8.1;12;13576;1.6953;91;1500;0;0;0;0;0;0;0
+8.2;12;13576;1.6953;64;1500;0;0;0;0;0;0;0
+8.3;12;13576;1.6953;45;1500;0;0;0;0;0;0;0
+8.4;12;13576;1.6953;32;1500;0;0;0;0;0;0;0
+8.5;12;13576;1.6953;23;1500;0;0;0;0;0;0;0
+8.6;12;13576;1.6953;12;1500;0;0;0;0;0;0;0
+8.7;12;13576;1.6953;6;1500;0;0;0;0;0;0;0
+8.8;12;13576;1.6953;3;1500;0;0;0;0;0;0;0
+8.9;12;13576;1.6953;2;1500;0;0;0;0;0;0;0
+9;12;13576;1.6953;1;1500;0;0;0;0;0;0;0
+9.1;12;13576;1.6953;0;1500;0;0;0;0;0;0;0
+9.2;12;13576;1.6953;0;1500;0;0;0;0;0;0;0
+9.3;12;13576;1.6953;0;1500;0;0;0;0;0;0;0
+9.4;12;13576;1.6953;0;1500;0;0;0;0;0;0;0
+9.5;12;13576;1.6953;0;1500;0;0;0;0;0;0;0
+9.6;12;13576;1.6953;0;1500;0;0;0;0;0;0;0
+9.7;12;13576;1.6953;0;1500;0;0;0;0;0;0;0
+9.8;12;13576;1.6953;0;1500;0;0;0;0;0;0;0
+9.9;12;13576;1.6953;0;1500;0;0;0;0;0;0;0
+10;12;13576;1.6953;0;1500;0;0;0;0;0;0;0
+10.1;12;13576;1.6953;0;1500;0;0;0;0;0;0;0
+10.2;12;13576;1.6953;0;1500;0;0;0;0;0;0;0
+10.3;12;13576;1.6953;0;1500;0;0;0;0;0;0;0
+10.4;12;13576;1.6953;0;1500;0;0;0;0;0;0;0
+10.5;12;13576;1.6953;0;1500;0;0;0;0;0;0;0
+10.6;12;13576;1.6953;0;1500;0;0;0;0;0;0;0
+10.7;12;13576;1.6953;0;1500;0;0;0;0;0;0;0
+10.8;12;13576;1.6953;0;1500;0;0;0;0;0;0;0
+10.9;12;13576;1.6953;0;1500;0;0;0;0;0;0;0
+11;12;13576;1.6953;0;1500;0;0;0;0;0;0;0
+11.1;12;13576;1.6953;0;1500;0;0;0;0;0;0;0
+11.2;12;13576;1.6953;0;1500;0;0;0;0;0;0;0
+11.3;12;13576;1.6953;0;1500;0;0;0;0;0;0;0
+11.4;12;13576;1.6953;0;1500;0;0;0;0;0;0;0
+11.5;12;13576;1.6953;0;1500;0;0;0;0;0;0;0
+11.6;12;13576;1.6953;0;1500;0;0;0;0;0;0;0
+11.7;12;13576;1.6953;0;1500;0;0;0;0;0;0;0
+11.8;12;13576;1.6953;0;1500;0;0;0;0;0;0;0
+11.9;12;13576;1.6953;0;1500;0;0;0;0;0;0;0
+12;12;13576;1.6953;0;1500;0;0;0;0;0;0;0
diff --git a/openair1/SIMULATION/NR_PHY/BLER_SIMULATIONS/AWGN/AWGN_results/mcs13_awgn_5G.csv b/openair1/SIMULATION/NR_PHY/BLER_SIMULATIONS/AWGN/AWGN_results/mcs13_awgn_5G.csv
new file mode 100644
index 0000000000000000000000000000000000000000..ef85933aafabe53c3cc20a2052f35259ec8923de
--- /dev/null
+++ b/openair1/SIMULATION/NR_PHY/BLER_SIMULATIONS/AWGN/AWGN_results/mcs13_awgn_5G.csv
@@ -0,0 +1,72 @@
+SNR;MCS;TBS;rate;err0;trials0;err1;trials1;err2;trials2;err3;trials3;dci_err
+7;13;15112;1.9141;1500;1500;0;0;0;0;0;0;0
+7.1;13;15112;1.9141;1500;1500;0;0;0;0;0;0;0
+7.2;13;15112;1.9141;1500;1500;0;0;0;0;0;0;0
+7.3;13;15112;1.9141;1500;1500;0;0;0;0;0;0;0
+7.4;13;15112;1.9141;1500;1500;0;0;0;0;0;0;0
+7.5;13;15112;1.9141;1500;1500;0;0;0;0;0;0;0
+7.6;13;15112;1.9141;1444;1500;0;0;0;0;0;0;0
+7.7;13;15112;1.9141;1391;1500;0;0;0;0;0;0;0
+7.8;13;15112;1.9141;1340;1500;0;0;0;0;0;0;0
+7.9;13;15112;1.9141;1290;1500;0;0;0;0;0;0;0
+8;13;15112;1.9141;1243;1500;0;0;0;0;0;0;0
+8.1;13;15112;1.9141;878;1500;0;0;0;0;0;0;0
+8.2;13;15112;1.9141;620;1500;0;0;0;0;0;0;0
+8.3;13;15112;1.9141;438;1500;0;0;0;0;0;0;0
+8.4;13;15112;1.9141;309;1500;0;0;0;0;0;0;0
+8.5;13;15112;1.9141;219;1500;0;0;0;0;0;0;0
+8.6;13;15112;1.9141;173;1500;0;0;0;0;0;0;0
+8.7;13;15112;1.9141;137;1500;0;0;0;0;0;0;0
+8.8;13;15112;1.9141;109;1500;0;0;0;0;0;0;0
+8.9;13;15112;1.9141;86;1500;0;0;0;0;0;0;0
+9;13;15112;1.9141;68;1500;0;0;0;0;0;0;0
+9.1;13;15112;1.9141;47;1500;0;0;0;0;0;0;0
+9.2;13;15112;1.9141;33;1500;0;0;0;0;0;0;0
+9.3;13;15112;1.9141;23;1500;0;0;0;0;0;0;0
+9.4;13;15112;1.9141;16;1500;0;0;0;0;0;0;0
+9.5;13;15112;1.9141;11;1500;0;0;0;0;0;0;0
+9.6;13;15112;1.9141;5;1500;0;0;0;0;0;0;0
+9.7;13;15112;1.9141;2;1500;0;0;0;0;0;0;0
+9.8;13;15112;1.9141;1;1500;0;0;0;0;0;0;0
+9.9;13;15112;1.9141;0;1500;0;0;0;0;0;0;0
+10;13;15112;1.9141;0;1500;0;0;0;0;0;0;0
+10.1;13;15112;1.9141;0;1500;0;0;0;0;0;0;0
+10.2;13;15112;1.9141;0;1500;0;0;0;0;0;0;0
+10.3;13;15112;1.9141;0;1500;0;0;0;0;0;0;0
+10.4;13;15112;1.9141;0;1500;0;0;0;0;0;0;0
+10.5;13;15112;1.9141;0;1500;0;0;0;0;0;0;0
+10.6;13;15112;1.9141;0;1500;0;0;0;0;0;0;0
+10.7;13;15112;1.9141;0;1500;0;0;0;0;0;0;0
+10.8;13;15112;1.9141;0;1500;0;0;0;0;0;0;0
+10.9;13;15112;1.9141;0;1500;0;0;0;0;0;0;0
+11;13;15112;1.9141;0;1500;0;0;0;0;0;0;0
+11.1;13;15112;1.9141;0;1500;0;0;0;0;0;0;0
+11.2;13;15112;1.9141;0;1500;0;0;0;0;0;0;0
+11.3;13;15112;1.9141;0;1500;0;0;0;0;0;0;0
+11.4;13;15112;1.9141;0;1500;0;0;0;0;0;0;0
+11.5;13;15112;1.9141;0;1500;0;0;0;0;0;0;0
+11.6;13;15112;1.9141;0;1500;0;0;0;0;0;0;0
+11.7;13;15112;1.9141;0;1500;0;0;0;0;0;0;0
+11.8;13;15112;1.9141;0;1500;0;0;0;0;0;0;0
+11.9;13;15112;1.9141;0;1500;0;0;0;0;0;0;0
+12;13;15112;1.9141;0;1500;0;0;0;0;0;0;0
+12.1;13;15112;1.9141;0;1500;0;0;0;0;0;0;0
+12.2;13;15112;1.9141;0;1500;0;0;0;0;0;0;0
+12.3;13;15112;1.9141;0;1500;0;0;0;0;0;0;0
+12.4;13;15112;1.9141;0;1500;0;0;0;0;0;0;0
+12.5;13;15112;1.9141;0;1500;0;0;0;0;0;0;0
+12.6;13;15112;1.9141;0;1500;0;0;0;0;0;0;0
+12.7;13;15112;1.9141;0;1500;0;0;0;0;0;0;0
+12.8;13;15112;1.9141;0;1500;0;0;0;0;0;0;0
+12.9;13;15112;1.9141;0;1500;0;0;0;0;0;0;0
+13;13;15112;1.9141;0;1500;0;0;0;0;0;0;0
+13.1;13;15112;1.9141;0;1500;0;0;0;0;0;0;0
+13.2;13;15112;1.9141;0;1500;0;0;0;0;0;0;0
+13.3;13;15112;1.9141;0;1500;0;0;0;0;0;0;0
+13.4;13;15112;1.9141;0;1500;0;0;0;0;0;0;0
+13.5;13;15112;1.9141;0;1500;0;0;0;0;0;0;0
+13.6;13;15112;1.9141;0;1500;0;0;0;0;0;0;0
+13.7;13;15112;1.9141;0;1500;0;0;0;0;0;0;0
+13.8;13;15112;1.9141;0;1500;0;0;0;0;0;0;0
+13.9;13;15112;1.9141;0;1500;0;0;0;0;0;0;0
+14;13;15112;1.9141;0;1500;0;0;0;0;0;0;0
diff --git a/openair1/SIMULATION/NR_PHY/BLER_SIMULATIONS/AWGN/AWGN_results/mcs14_awgn_5G.csv b/openair1/SIMULATION/NR_PHY/BLER_SIMULATIONS/AWGN/AWGN_results/mcs14_awgn_5G.csv
new file mode 100644
index 0000000000000000000000000000000000000000..06671050112212775aecb3d894ae92345036e94e
--- /dev/null
+++ b/openair1/SIMULATION/NR_PHY/BLER_SIMULATIONS/AWGN/AWGN_results/mcs14_awgn_5G.csv
@@ -0,0 +1,72 @@
+SNR;MCS;TBS;rate;err0;trials0;err1;trials1;err2;trials2;err3;trials3;dci_err
+7;14;17424;2.1602;1500;1500;0;0;0;0;0;0;0
+7.1;14;17424;2.1602;1500;1500;0;0;0;0;0;0;0
+7.2;14;17424;2.1602;1500;1500;0;0;0;0;0;0;0
+7.3;14;17424;2.1602;1500;1500;0;0;0;0;0;0;0
+7.4;14;17424;2.1602;1500;1500;0;0;0;0;0;0;0
+7.5;14;17424;2.1602;1500;1500;0;0;0;0;0;0;0
+7.6;14;17424;2.1602;1500;1500;0;0;0;0;0;0;0
+7.7;14;17424;2.1602;1500;1500;0;0;0;0;0;0;0
+7.8;14;17424;2.1602;1500;1500;0;0;0;0;0;0;0
+7.9;14;17424;2.1602;1500;1500;0;0;0;0;0;0;0
+8;14;17424;2.1602;1500;1500;0;0;0;0;0;0;0
+8.1;14;17424;2.1602;1500;1500;0;0;0;0;0;0;0
+8.2;14;17424;2.1602;1500;1500;0;0;0;0;0;0;0
+8.3;14;17424;2.1602;1500;1500;0;0;0;0;0;0;0
+8.4;14;17424;2.1602;1500;1500;0;0;0;0;0;0;0
+8.5;14;17424;2.1602;1500;1500;0;0;0;0;0;0;0
+8.6;14;17424;2.1602;1497;1500;0;0;0;0;0;0;0
+8.7;14;17424;2.1602;1493;1500;0;0;0;0;0;0;0
+8.8;14;17424;2.1602;1490;1500;0;0;0;0;0;0;0
+8.9;14;17424;2.1602;1487;1500;0;0;0;0;0;0;0
+9;14;17424;2.1602;1484;1500;0;0;0;0;0;0;0
+9.1;14;17424;2.1602;1291;1500;0;0;0;0;0;0;0
+9.2;14;17424;2.1602;1123;1500;0;0;0;0;0;0;0
+9.3;14;17424;2.1602;977;1500;0;0;0;0;0;0;0
+9.4;14;17424;2.1602;850;1500;0;0;0;0;0;0;0
+9.5;14;17424;2.1602;739;1500;0;0;0;0;0;0;0
+9.6;14;17424;2.1602;508;1500;0;0;0;0;0;0;0
+9.7;14;17424;2.1602;349;1500;0;0;0;0;0;0;0
+9.8;14;17424;2.1602;239;1500;0;0;0;0;0;0;0
+9.9;14;17424;2.1602;164;1500;0;0;0;0;0;0;0
+10;14;17424;2.1602;113;1500;0;0;0;0;0;0;0
+10.1;14;17424;2.1602;85;1500;0;0;0;0;0;0;0
+10.2;14;17424;2.1602;63;1500;0;0;0;0;0;0;0
+10.3;14;17424;2.1602;47;1500;0;0;0;0;0;0;0
+10.4;14;17424;2.1602;35;1500;0;0;0;0;0;0;0
+10.5;14;17424;2.1602;27;1500;0;0;0;0;0;0;0
+10.6;14;17424;2.1602;12;1500;0;0;0;0;0;0;0
+10.7;14;17424;2.1602;6;1500;0;0;0;0;0;0;0
+10.8;14;17424;2.1602;3;1500;0;0;0;0;0;0;0
+10.9;14;17424;2.1602;1;1500;0;0;0;0;0;0;0
+11;14;17424;2.1602;1;1500;0;0;0;0;0;0;0
+11.1;14;17424;2.1602;0;1500;0;0;0;0;0;0;0
+11.2;14;17424;2.1602;0;1500;0;0;0;0;0;0;0
+11.3;14;17424;2.1602;0;1500;0;0;0;0;0;0;0
+11.4;14;17424;2.1602;0;1500;0;0;0;0;0;0;0
+11.5;14;17424;2.1602;0;1500;0;0;0;0;0;0;0
+11.6;14;17424;2.1602;0;1500;0;0;0;0;0;0;0
+11.7;14;17424;2.1602;0;1500;0;0;0;0;0;0;0
+11.8;14;17424;2.1602;0;1500;0;0;0;0;0;0;0
+11.9;14;17424;2.1602;0;1500;0;0;0;0;0;0;0
+12;14;17424;2.1602;0;1500;0;0;0;0;0;0;0
+12.1;14;17424;2.1602;0;1500;0;0;0;0;0;0;0
+12.2;14;17424;2.1602;0;1500;0;0;0;0;0;0;0
+12.3;14;17424;2.1602;0;1500;0;0;0;0;0;0;0
+12.4;14;17424;2.1602;0;1500;0;0;0;0;0;0;0
+12.5;14;17424;2.1602;0;1500;0;0;0;0;0;0;0
+12.6;14;17424;2.1602;0;1500;0;0;0;0;0;0;0
+12.7;14;17424;2.1602;0;1500;0;0;0;0;0;0;0
+12.8;14;17424;2.1602;0;1500;0;0;0;0;0;0;0
+12.9;14;17424;2.1602;0;1500;0;0;0;0;0;0;0
+13;14;17424;2.1602;0;1500;0;0;0;0;0;0;0
+13.1;14;17424;2.1602;0;1500;0;0;0;0;0;0;0
+13.2;14;17424;2.1602;0;1500;0;0;0;0;0;0;0
+13.3;14;17424;2.1602;0;1500;0;0;0;0;0;0;0
+13.4;14;17424;2.1602;0;1500;0;0;0;0;0;0;0
+13.5;14;17424;2.1602;0;1500;0;0;0;0;0;0;0
+13.6;14;17424;2.1602;0;1500;0;0;0;0;0;0;0
+13.7;14;17424;2.1602;0;1500;0;0;0;0;0;0;0
+13.8;14;17424;2.1602;0;1500;0;0;0;0;0;0;0
+13.9;14;17424;2.1602;0;1500;0;0;0;0;0;0;0
+14;14;17424;2.1602;0;1500;0;0;0;0;0;0;0
diff --git a/openair1/SIMULATION/NR_PHY/BLER_SIMULATIONS/AWGN/AWGN_results/mcs15_awgn_5G.csv b/openair1/SIMULATION/NR_PHY/BLER_SIMULATIONS/AWGN/AWGN_results/mcs15_awgn_5G.csv
new file mode 100644
index 0000000000000000000000000000000000000000..460d156d78de9765bfb8f320513b36d7113bc7b0
--- /dev/null
+++ b/openair1/SIMULATION/NR_PHY/BLER_SIMULATIONS/AWGN/AWGN_results/mcs15_awgn_5G.csv
@@ -0,0 +1,72 @@
+SNR;MCS;TBS;rate;err0;trials0;err1;trials1;err2;trials2;err3;trials3;dci_err
+7;15;18960;2.4063;1500;1500;0;0;0;0;0;0;0
+7.1;15;18960;2.4063;1500;1500;0;0;0;0;0;0;0
+7.2;15;18960;2.4063;1500;1500;0;0;0;0;0;0;0
+7.3;15;18960;2.4063;1500;1500;0;0;0;0;0;0;0
+7.4;15;18960;2.4063;1500;1500;0;0;0;0;0;0;0
+7.5;15;18960;2.4063;1500;1500;0;0;0;0;0;0;0
+7.6;15;18960;2.4063;1500;1500;0;0;0;0;0;0;0
+7.7;15;18960;2.4063;1500;1500;0;0;0;0;0;0;0
+7.8;15;18960;2.4063;1500;1500;0;0;0;0;0;0;0
+7.9;15;18960;2.4063;1500;1500;0;0;0;0;0;0;0
+8;15;18960;2.4063;1500;1500;0;0;0;0;0;0;0
+8.1;15;18960;2.4063;1500;1500;0;0;0;0;0;0;0
+8.2;15;18960;2.4063;1500;1500;0;0;0;0;0;0;0
+8.3;15;18960;2.4063;1500;1500;0;0;0;0;0;0;0
+8.4;15;18960;2.4063;1500;1500;0;0;0;0;0;0;0
+8.5;15;18960;2.4063;1500;1500;0;0;0;0;0;0;0
+8.6;15;18960;2.4063;1500;1500;0;0;0;0;0;0;0
+8.7;15;18960;2.4063;1500;1500;0;0;0;0;0;0;0
+8.8;15;18960;2.4063;1500;1500;0;0;0;0;0;0;0
+8.9;15;18960;2.4063;1500;1500;0;0;0;0;0;0;0
+9;15;18960;2.4063;1500;1500;0;0;0;0;0;0;0
+9.1;15;18960;2.4063;1500;1500;0;0;0;0;0;0;0
+9.2;15;18960;2.4063;1499;1500;0;0;0;0;0;0;0
+9.3;15;18960;2.4063;1499;1500;0;0;0;0;0;0;0
+9.4;15;18960;2.4063;1499;1500;0;0;0;0;0;0;0
+9.5;15;18960;2.4063;1498;1500;0;0;0;0;0;0;0
+9.6;15;18960;2.4063;1377;1500;0;0;0;0;0;0;0
+9.7;15;18960;2.4063;1265;1500;0;0;0;0;0;0;0
+9.8;15;18960;2.4063;1163;1500;0;0;0;0;0;0;0
+9.9;15;18960;2.4063;1069;1500;0;0;0;0;0;0;0
+10;15;18960;2.4063;982;1500;0;0;0;0;0;0;0
+10.1;15;18960;2.4063;664;1500;0;0;0;0;0;0;0
+10.2;15;18960;2.4063;450;1500;0;0;0;0;0;0;0
+10.3;15;18960;2.4063;304;1500;0;0;0;0;0;0;0
+10.4;15;18960;2.4063;206;1500;0;0;0;0;0;0;0
+10.5;15;18960;2.4063;139;1500;0;0;0;0;0;0;0
+10.6;15;18960;2.4063;113;1500;0;0;0;0;0;0;0
+10.7;15;18960;2.4063;92;1500;0;0;0;0;0;0;0
+10.8;15;18960;2.4063;75;1500;0;0;0;0;0;0;0
+10.9;15;18960;2.4063;61;1500;0;0;0;0;0;0;0
+11;15;18960;2.4063;50;1500;0;0;0;0;0;0;0
+11.1;15;18960;2.4063;29;1500;0;0;0;0;0;0;0
+11.2;15;18960;2.4063;17;1500;0;0;0;0;0;0;0
+11.3;15;18960;2.4063;10;1500;0;0;0;0;0;0;0
+11.4;15;18960;2.4063;6;1500;0;0;0;0;0;0;0
+11.5;15;18960;2.4063;3;1500;0;0;0;0;0;0;0
+11.6;15;18960;2.4063;0;1500;0;0;0;0;0;0;0
+11.7;15;18960;2.4063;0;1500;0;0;0;0;0;0;0
+11.8;15;18960;2.4063;0;1500;0;0;0;0;0;0;0
+11.9;15;18960;2.4063;0;1500;0;0;0;0;0;0;0
+12;15;18960;2.4063;0;1500;0;0;0;0;0;0;0
+12.1;15;18960;2.4063;0;1500;0;0;0;0;0;0;0
+12.2;15;18960;2.4063;0;1500;0;0;0;0;0;0;0
+12.3;15;18960;2.4063;0;1500;0;0;0;0;0;0;0
+12.4;15;18960;2.4063;0;1500;0;0;0;0;0;0;0
+12.5;15;18960;2.4063;0;1500;0;0;0;0;0;0;0
+12.6;15;18960;2.4063;0;1500;0;0;0;0;0;0;0
+12.7;15;18960;2.4063;0;1500;0;0;0;0;0;0;0
+12.8;15;18960;2.4063;0;1500;0;0;0;0;0;0;0
+12.9;15;18960;2.4063;0;1500;0;0;0;0;0;0;0
+13;15;18960;2.4063;0;1500;0;0;0;0;0;0;0
+13.1;15;18960;2.4063;0;1500;0;0;0;0;0;0;0
+13.2;15;18960;2.4063;0;1500;0;0;0;0;0;0;0
+13.3;15;18960;2.4063;0;1500;0;0;0;0;0;0;0
+13.4;15;18960;2.4063;0;1500;0;0;0;0;0;0;0
+13.5;15;18960;2.4063;0;1500;0;0;0;0;0;0;0
+13.6;15;18960;2.4063;0;1500;0;0;0;0;0;0;0
+13.7;15;18960;2.4063;0;1500;0;0;0;0;0;0;0
+13.8;15;18960;2.4063;0;1500;0;0;0;0;0;0;0
+13.9;15;18960;2.4063;0;1500;0;0;0;0;0;0;0
+14;15;18960;2.4063;0;1500;0;0;0;0;0;0;0
diff --git a/openair1/SIMULATION/NR_PHY/BLER_SIMULATIONS/AWGN/AWGN_results/mcs16_awgn_5G.csv b/openair1/SIMULATION/NR_PHY/BLER_SIMULATIONS/AWGN/AWGN_results/mcs16_awgn_5G.csv
new file mode 100644
index 0000000000000000000000000000000000000000..4f122de8c104c9cfede7d72fffa0b9402a66a7a3
--- /dev/null
+++ b/openair1/SIMULATION/NR_PHY/BLER_SIMULATIONS/AWGN/AWGN_results/mcs16_awgn_5G.csv
@@ -0,0 +1,72 @@
+SNR;MCS;TBS;rate;err0;trials0;err1;trials1;err2;trials2;err3;trials3;dci_err
+7;16;20496;2.5703;1500;1500;0;0;0;0;0;0;0
+7.1;16;20496;2.5703;1500;1500;0;0;0;0;0;0;0
+7.2;16;20496;2.5703;1500;1500;0;0;0;0;0;0;0
+7.3;16;20496;2.5703;1500;1500;0;0;0;0;0;0;0
+7.4;16;20496;2.5703;1500;1500;0;0;0;0;0;0;0
+7.5;16;20496;2.5703;1500;1500;0;0;0;0;0;0;0
+7.6;16;20496;2.5703;1500;1500;0;0;0;0;0;0;0
+7.7;16;20496;2.5703;1500;1500;0;0;0;0;0;0;0
+7.8;16;20496;2.5703;1500;1500;0;0;0;0;0;0;0
+7.9;16;20496;2.5703;1500;1500;0;0;0;0;0;0;0
+8;16;20496;2.5703;1500;1500;0;0;0;0;0;0;0
+8.1;16;20496;2.5703;1500;1500;0;0;0;0;0;0;0
+8.2;16;20496;2.5703;1500;1500;0;0;0;0;0;0;0
+8.3;16;20496;2.5703;1500;1500;0;0;0;0;0;0;0
+8.4;16;20496;2.5703;1500;1500;0;0;0;0;0;0;0
+8.5;16;20496;2.5703;1500;1500;0;0;0;0;0;0;0
+8.6;16;20496;2.5703;1500;1500;0;0;0;0;0;0;0
+8.7;16;20496;2.5703;1500;1500;0;0;0;0;0;0;0
+8.8;16;20496;2.5703;1500;1500;0;0;0;0;0;0;0
+8.9;16;20496;2.5703;1500;1500;0;0;0;0;0;0;0
+9;16;20496;2.5703;1500;1500;0;0;0;0;0;0;0
+9.1;16;20496;2.5703;1500;1500;0;0;0;0;0;0;0
+9.2;16;20496;2.5703;1500;1500;0;0;0;0;0;0;0
+9.3;16;20496;2.5703;1500;1500;0;0;0;0;0;0;0
+9.4;16;20496;2.5703;1500;1500;0;0;0;0;0;0;0
+9.5;16;20496;2.5703;1500;1500;0;0;0;0;0;0;0
+9.6;16;20496;2.5703;1500;1500;0;0;0;0;0;0;0
+9.7;16;20496;2.5703;1500;1500;0;0;0;0;0;0;0
+9.8;16;20496;2.5703;1500;1500;0;0;0;0;0;0;0
+9.9;16;20496;2.5703;1500;1500;0;0;0;0;0;0;0
+10;16;20496;2.5703;1500;1500;0;0;0;0;0;0;0
+10.1;16;20496;2.5703;1424;1500;0;0;0;0;0;0;0
+10.2;16;20496;2.5703;1352;1500;0;0;0;0;0;0;0
+10.3;16;20496;2.5703;1283;1500;0;0;0;0;0;0;0
+10.4;16;20496;2.5703;1218;1500;0;0;0;0;0;0;0
+10.5;16;20496;2.5703;1157;1500;0;0;0;0;0;0;0
+10.6;16;20496;2.5703;775;1500;0;0;0;0;0;0;0
+10.7;16;20496;2.5703;519;1500;0;0;0;0;0;0;0
+10.8;16;20496;2.5703;348;1500;0;0;0;0;0;0;0
+10.9;16;20496;2.5703;233;1500;0;0;0;0;0;0;0
+11;16;20496;2.5703;156;1500;0;0;0;0;0;0;0
+11.1;16;20496;2.5703;132;1500;0;0;0;0;0;0;0
+11.2;16;20496;2.5703;111;1500;0;0;0;0;0;0;0
+11.3;16;20496;2.5703;94;1500;0;0;0;0;0;0;0
+11.4;16;20496;2.5703;79;1500;0;0;0;0;0;0;0
+11.5;16;20496;2.5703;67;1500;0;0;0;0;0;0;0
+11.6;16;20496;2.5703;44;1500;0;0;0;0;0;0;0
+11.7;16;20496;2.5703;29;1500;0;0;0;0;0;0;0
+11.8;16;20496;2.5703;19;1500;0;0;0;0;0;0;0
+11.9;16;20496;2.5703;12;1500;0;0;0;0;0;0;0
+12;16;20496;2.5703;8;1500;0;0;0;0;0;0;0
+12.1;16;20496;2.5703;4;1500;0;0;0;0;0;0;0
+12.2;16;20496;2.5703;2;1500;0;0;0;0;0;0;0
+12.3;16;20496;2.5703;1;1500;0;0;0;0;0;0;0
+12.4;16;20496;2.5703;1;1500;0;0;0;0;0;0;0
+12.5;16;20496;2.5703;0;1500;0;0;0;0;0;0;0
+12.6;16;20496;2.5703;0;1500;0;0;0;0;0;0;0
+12.7;16;20496;2.5703;0;1500;0;0;0;0;0;0;0
+12.8;16;20496;2.5703;0;1500;0;0;0;0;0;0;0
+12.9;16;20496;2.5703;0;1500;0;0;0;0;0;0;0
+13;16;20496;2.5703;0;1500;0;0;0;0;0;0;0
+13.1;16;20496;2.5703;0;1500;0;0;0;0;0;0;0
+13.2;16;20496;2.5703;0;1500;0;0;0;0;0;0;0
+13.3;16;20496;2.5703;0;1500;0;0;0;0;0;0;0
+13.4;16;20496;2.5703;0;1500;0;0;0;0;0;0;0
+13.5;16;20496;2.5703;0;1500;0;0;0;0;0;0;0
+13.6;16;20496;2.5703;0;1500;0;0;0;0;0;0;0
+13.7;16;20496;2.5703;0;1500;0;0;0;0;0;0;0
+13.8;16;20496;2.5703;0;1500;0;0;0;0;0;0;0
+13.9;16;20496;2.5703;0;1500;0;0;0;0;0;0;0
+14;16;20496;2.5703;0;1500;0;0;0;0;0;0;0
diff --git a/openair1/SIMULATION/NR_PHY/BLER_SIMULATIONS/AWGN/AWGN_results/mcs17_awgn_5G.csv b/openair1/SIMULATION/NR_PHY/BLER_SIMULATIONS/AWGN/AWGN_results/mcs17_awgn_5G.csv
new file mode 100644
index 0000000000000000000000000000000000000000..3254f76eb9e98a98067b61444732deb4de7482b3
--- /dev/null
+++ b/openair1/SIMULATION/NR_PHY/BLER_SIMULATIONS/AWGN/AWGN_results/mcs17_awgn_5G.csv
@@ -0,0 +1,72 @@
+SNR;MCS;TBS;rate;err0;trials0;err1;trials1;err2;trials2;err3;trials3;dci_err
+10;17;20496;2.5664;1500;1500;0;0;0;0;0;0;0
+10.1;17;20496;2.5664;1500;1500;0;0;0;0;0;0;0
+10.2;17;20496;2.5664;1500;1500;0;0;0;0;0;0;0
+10.3;17;20496;2.5664;1500;1500;0;0;0;0;0;0;0
+10.4;17;20496;2.5664;1500;1500;0;0;0;0;0;0;0
+10.5;17;20496;2.5664;1500;1500;0;0;0;0;0;0;0
+10.6;17;20496;2.5664;1498;1500;0;0;0;0;0;0;0
+10.7;17;20496;2.5664;1496;1500;0;0;0;0;0;0;0
+10.8;17;20496;2.5664;1494;1500;0;0;0;0;0;0;0
+10.9;17;20496;2.5664;1493;1500;0;0;0;0;0;0;0
+11;17;20496;2.5664;1491;1500;0;0;0;0;0;0;0
+11.1;17;20496;2.5664;1336;1500;0;0;0;0;0;0;0
+11.2;17;20496;2.5664;1197;1500;0;0;0;0;0;0;0
+11.3;17;20496;2.5664;1072;1500;0;0;0;0;0;0;0
+11.4;17;20496;2.5664;961;1500;0;0;0;0;0;0;0
+11.5;17;20496;2.5664;861;1500;0;0;0;0;0;0;0
+11.6;17;20496;2.5664;603;1500;0;0;0;0;0;0;0
+11.7;17;20496;2.5664;423;1500;0;0;0;0;0;0;0
+11.8;17;20496;2.5664;296;1500;0;0;0;0;0;0;0
+11.9;17;20496;2.5664;208;1500;0;0;0;0;0;0;0
+12;17;20496;2.5664;146;1500;0;0;0;0;0;0;0
+12.1;17;20496;2.5664;125;1500;0;0;0;0;0;0;0
+12.2;17;20496;2.5664;107;1500;0;0;0;0;0;0;0
+12.3;17;20496;2.5664;92;1500;0;0;0;0;0;0;0
+12.4;17;20496;2.5664;79;1500;0;0;0;0;0;0;0
+12.5;17;20496;2.5664;68;1500;0;0;0;0;0;0;0
+12.6;17;20496;2.5664;50;1500;0;0;0;0;0;0;0
+12.7;17;20496;2.5664;37;1500;0;0;0;0;0;0;0
+12.8;17;20496;2.5664;28;1500;0;0;0;0;0;0;0
+12.9;17;20496;2.5664;20;1500;0;0;0;0;0;0;0
+13;17;20496;2.5664;15;1500;0;0;0;0;0;0;0
+13.1;17;20496;2.5664;9;1500;0;0;0;0;0;0;0
+13.2;17;20496;2.5664;5;1500;0;0;0;0;0;0;0
+13.3;17;20496;2.5664;3;1500;0;0;0;0;0;0;0
+13.4;17;20496;2.5664;2;1500;0;0;0;0;0;0;0
+13.5;17;20496;2.5664;1;1500;0;0;0;0;0;0;0
+13.6;17;20496;2.5664;0;1500;0;0;0;0;0;0;0
+13.7;17;20496;2.5664;0;1500;0;0;0;0;0;0;0
+13.8;17;20496;2.5664;0;1500;0;0;0;0;0;0;0
+13.9;17;20496;2.5664;0;1500;0;0;0;0;0;0;0
+14;17;20496;2.5664;0;1500;0;0;0;0;0;0;0
+14.1;17;20496;2.5664;0;1500;0;0;0;0;0;0;0
+14.2;17;20496;2.5664;0;1500;0;0;0;0;0;0;0
+14.3;17;20496;2.5664;0;1500;0;0;0;0;0;0;0
+14.4;17;20496;2.5664;0;1500;0;0;0;0;0;0;0
+14.5;17;20496;2.5664;0;1500;0;0;0;0;0;0;0
+14.6;17;20496;2.5664;0;1500;0;0;0;0;0;0;0
+14.7;17;20496;2.5664;0;1500;0;0;0;0;0;0;0
+14.8;17;20496;2.5664;0;1500;0;0;0;0;0;0;0
+14.9;17;20496;2.5664;0;1500;0;0;0;0;0;0;0
+15;17;20496;2.5664;0;1500;0;0;0;0;0;0;0
+15.1;17;20496;2.5664;0;1500;0;0;0;0;0;0;0
+15.2;17;20496;2.5664;0;1500;0;0;0;0;0;0;0
+15.3;17;20496;2.5664;0;1500;0;0;0;0;0;0;0
+15.4;17;20496;2.5664;0;1500;0;0;0;0;0;0;0
+15.5;17;20496;2.5664;0;1500;0;0;0;0;0;0;0
+15.6;17;20496;2.5664;0;1500;0;0;0;0;0;0;0
+15.7;17;20496;2.5664;0;1500;0;0;0;0;0;0;0
+15.8;17;20496;2.5664;0;1500;0;0;0;0;0;0;0
+15.9;17;20496;2.5664;0;1500;0;0;0;0;0;0;0
+16;17;20496;2.5664;0;1500;0;0;0;0;0;0;0
+16.1;17;20496;2.5664;0;1500;0;0;0;0;0;0;0
+16.2;17;20496;2.5664;0;1500;0;0;0;0;0;0;0
+16.3;17;20496;2.5664;0;1500;0;0;0;0;0;0;0
+16.4;17;20496;2.5664;0;1500;0;0;0;0;0;0;0
+16.5;17;20496;2.5664;0;1500;0;0;0;0;0;0;0
+16.6;17;20496;2.5664;0;1500;0;0;0;0;0;0;0
+16.7;17;20496;2.5664;0;1500;0;0;0;0;0;0;0
+16.8;17;20496;2.5664;0;1500;0;0;0;0;0;0;0
+16.9;17;20496;2.5664;0;1500;0;0;0;0;0;0;0
+17;17;20496;2.5664;0;1500;0;0;0;0;0;0;0
diff --git a/openair1/SIMULATION/NR_PHY/BLER_SIMULATIONS/AWGN/AWGN_results/mcs18_awgn_5G.csv b/openair1/SIMULATION/NR_PHY/BLER_SIMULATIONS/AWGN/AWGN_results/mcs18_awgn_5G.csv
new file mode 100644
index 0000000000000000000000000000000000000000..67ede60066ac44966f2541149d09bb664844ab54
--- /dev/null
+++ b/openair1/SIMULATION/NR_PHY/BLER_SIMULATIONS/AWGN/AWGN_results/mcs18_awgn_5G.csv
@@ -0,0 +1,72 @@
+SNR;MCS;TBS;rate;err0;trials0;err1;trials1;err2;trials2;err3;trials3;dci_err
+10;18;21504;2.7305;1500;1500;0;0;0;0;0;0;0
+10.1;18;21504;2.7305;1500;1500;0;0;0;0;0;0;0
+10.2;18;21504;2.7305;1500;1500;0;0;0;0;0;0;0
+10.3;18;21504;2.7305;1500;1500;0;0;0;0;0;0;0
+10.4;18;21504;2.7305;1500;1500;0;0;0;0;0;0;0
+10.5;18;21504;2.7305;1500;1500;0;0;0;0;0;0;0
+10.6;18;21504;2.7305;1500;1500;0;0;0;0;0;0;0
+10.7;18;21504;2.7305;1500;1500;0;0;0;0;0;0;0
+10.8;18;21504;2.7305;1500;1500;0;0;0;0;0;0;0
+10.9;18;21504;2.7305;1500;1500;0;0;0;0;0;0;0
+11;18;21504;2.7305;1500;1500;0;0;0;0;0;0;0
+11.1;18;21504;2.7305;1499;1500;0;0;0;0;0;0;0
+11.2;18;21504;2.7305;1499;1500;0;0;0;0;0;0;0
+11.3;18;21504;2.7305;1498;1500;0;0;0;0;0;0;0
+11.4;18;21504;2.7305;1498;1500;0;0;0;0;0;0;0
+11.5;18;21504;2.7305;1497;1500;0;0;0;0;0;0;0
+11.6;18;21504;2.7305;1399;1500;0;0;0;0;0;0;0
+11.7;18;21504;2.7305;1307;1500;0;0;0;0;0;0;0
+11.8;18;21504;2.7305;1221;1500;0;0;0;0;0;0;0
+11.9;18;21504;2.7305;1141;1500;0;0;0;0;0;0;0
+12;18;21504;2.7305;1066;1500;0;0;0;0;0;0;0
+12.1;18;21504;2.7305;788;1500;0;0;0;0;0;0;0
+12.2;18;21504;2.7305;582;1500;0;0;0;0;0;0;0
+12.3;18;21504;2.7305;431;1500;0;0;0;0;0;0;0
+12.4;18;21504;2.7305;318;1500;0;0;0;0;0;0;0
+12.5;18;21504;2.7305;235;1500;0;0;0;0;0;0;0
+12.6;18;21504;2.7305;185;1500;0;0;0;0;0;0;0
+12.7;18;21504;2.7305;146;1500;0;0;0;0;0;0;0
+12.8;18;21504;2.7305;115;1500;0;0;0;0;0;0;0
+12.9;18;21504;2.7305;90;1500;0;0;0;0;0;0;0
+13;18;21504;2.7305;71;1500;0;0;0;0;0;0;0
+13.1;18;21504;2.7305;50;1500;0;0;0;0;0;0;0
+13.2;18;21504;2.7305;35;1500;0;0;0;0;0;0;0
+13.3;18;21504;2.7305;25;1500;0;0;0;0;0;0;0
+13.4;18;21504;2.7305;18;1500;0;0;0;0;0;0;0
+13.5;18;21504;2.7305;12;1500;0;0;0;0;0;0;0
+13.6;18;21504;2.7305;7;1500;0;0;0;0;0;0;0
+13.7;18;21504;2.7305;3;1500;0;0;0;0;0;0;0
+13.8;18;21504;2.7305;2;1500;0;0;0;0;0;0;0
+13.9;18;21504;2.7305;1;1500;0;0;0;0;0;0;0
+14;18;21504;2.7305;1;1500;0;0;0;0;0;0;0
+14.1;18;21504;2.7305;0;1500;0;0;0;0;0;0;0
+14.2;18;21504;2.7305;0;1500;0;0;0;0;0;0;0
+14.3;18;21504;2.7305;0;1500;0;0;0;0;0;0;0
+14.4;18;21504;2.7305;0;1500;0;0;0;0;0;0;0
+14.5;18;21504;2.7305;0;1500;0;0;0;0;0;0;0
+14.6;18;21504;2.7305;0;1500;0;0;0;0;0;0;0
+14.7;18;21504;2.7305;0;1500;0;0;0;0;0;0;0
+14.8;18;21504;2.7305;0;1500;0;0;0;0;0;0;0
+14.9;18;21504;2.7305;0;1500;0;0;0;0;0;0;0
+15;18;21504;2.7305;0;1500;0;0;0;0;0;0;0
+15.1;18;21504;2.7305;0;1500;0;0;0;0;0;0;0
+15.2;18;21504;2.7305;0;1500;0;0;0;0;0;0;0
+15.3;18;21504;2.7305;0;1500;0;0;0;0;0;0;0
+15.4;18;21504;2.7305;0;1500;0;0;0;0;0;0;0
+15.5;18;21504;2.7305;0;1500;0;0;0;0;0;0;0
+15.6;18;21504;2.7305;0;1500;0;0;0;0;0;0;0
+15.7;18;21504;2.7305;0;1500;0;0;0;0;0;0;0
+15.8;18;21504;2.7305;0;1500;0;0;0;0;0;0;0
+15.9;18;21504;2.7305;0;1500;0;0;0;0;0;0;0
+16;18;21504;2.7305;0;1500;0;0;0;0;0;0;0
+16.1;18;21504;2.7305;0;1500;0;0;0;0;0;0;0
+16.2;18;21504;2.7305;0;1500;0;0;0;0;0;0;0
+16.3;18;21504;2.7305;0;1500;0;0;0;0;0;0;0
+16.4;18;21504;2.7305;0;1500;0;0;0;0;0;0;0
+16.5;18;21504;2.7305;0;1500;0;0;0;0;0;0;0
+16.6;18;21504;2.7305;0;1500;0;0;0;0;0;0;0
+16.7;18;21504;2.7305;0;1500;0;0;0;0;0;0;0
+16.8;18;21504;2.7305;0;1500;0;0;0;0;0;0;0
+16.9;18;21504;2.7305;0;1500;0;0;0;0;0;0;0
+17;18;21504;2.7305;0;1500;0;0;0;0;0;0;0
diff --git a/openair1/SIMULATION/NR_PHY/BLER_SIMULATIONS/AWGN/AWGN_results/mcs19_awgn_5G.csv b/openair1/SIMULATION/NR_PHY/BLER_SIMULATIONS/AWGN/AWGN_results/mcs19_awgn_5G.csv
new file mode 100644
index 0000000000000000000000000000000000000000..3d18bd7987e8994bad6993cf6e27053dbbdcd4b3
--- /dev/null
+++ b/openair1/SIMULATION/NR_PHY/BLER_SIMULATIONS/AWGN/AWGN_results/mcs19_awgn_5G.csv
@@ -0,0 +1,72 @@
+SNR;MCS;TBS;rate;err0;trials0;err1;trials1;err2;trials2;err3;trials3;dci_err
+10;19;24072;3.0293;1500;1500;0;0;0;0;0;0;0
+10.1;19;24072;3.0293;1500;1500;0;0;0;0;0;0;0
+10.2;19;24072;3.0293;1500;1500;0;0;0;0;0;0;0
+10.3;19;24072;3.0293;1500;1500;0;0;0;0;0;0;0
+10.4;19;24072;3.0293;1500;1500;0;0;0;0;0;0;0
+10.5;19;24072;3.0293;1500;1500;0;0;0;0;0;0;0
+10.6;19;24072;3.0293;1500;1500;0;0;0;0;0;0;0
+10.7;19;24072;3.0293;1500;1500;0;0;0;0;0;0;0
+10.8;19;24072;3.0293;1500;1500;0;0;0;0;0;0;0
+10.9;19;24072;3.0293;1500;1500;0;0;0;0;0;0;0
+11;19;24072;3.0293;1500;1500;0;0;0;0;0;0;0
+11.1;19;24072;3.0293;1500;1500;0;0;0;0;0;0;0
+11.2;19;24072;3.0293;1500;1500;0;0;0;0;0;0;0
+11.3;19;24072;3.0293;1500;1500;0;0;0;0;0;0;0
+11.4;19;24072;3.0293;1500;1500;0;0;0;0;0;0;0
+11.5;19;24072;3.0293;1500;1500;0;0;0;0;0;0;0
+11.6;19;24072;3.0293;1500;1500;0;0;0;0;0;0;0
+11.7;19;24072;3.0293;1500;1500;0;0;0;0;0;0;0
+11.8;19;24072;3.0293;1500;1500;0;0;0;0;0;0;0
+11.9;19;24072;3.0293;1500;1500;0;0;0;0;0;0;0
+12;19;24072;3.0293;1500;1500;0;0;0;0;0;0;0
+12.1;19;24072;3.0293;1499;1500;0;0;0;0;0;0;0
+12.2;19;24072;3.0293;1499;1500;0;0;0;0;0;0;0
+12.3;19;24072;3.0293;1498;1500;0;0;0;0;0;0;0
+12.4;19;24072;3.0293;1497;1500;0;0;0;0;0;0;0
+12.5;19;24072;3.0293;1497;1500;0;0;0;0;0;0;0
+12.6;19;24072;3.0293;1389;1500;0;0;0;0;0;0;0
+12.7;19;24072;3.0293;1290;1500;0;0;0;0;0;0;0
+12.8;19;24072;3.0293;1197;1500;0;0;0;0;0;0;0
+12.9;19;24072;3.0293;1111;1500;0;0;0;0;0;0;0
+13;19;24072;3.0293;1032;1500;0;0;0;0;0;0;0
+13.1;19;24072;3.0293;746;1500;0;0;0;0;0;0;0
+13.2;19;24072;3.0293;539;1500;0;0;0;0;0;0;0
+13.3;19;24072;3.0293;390;1500;0;0;0;0;0;0;0
+13.4;19;24072;3.0293;282;1500;0;0;0;0;0;0;0
+13.5;19;24072;3.0293;204;1500;0;0;0;0;0;0;0
+13.6;19;24072;3.0293;166;1500;0;0;0;0;0;0;0
+13.7;19;24072;3.0293;135;1500;0;0;0;0;0;0;0
+13.8;19;24072;3.0293;110;1500;0;0;0;0;0;0;0
+13.9;19;24072;3.0293;89;1500;0;0;0;0;0;0;0
+14;19;24072;3.0293;73;1500;0;0;0;0;0;0;0
+14.1;19;24072;3.0293;54;1500;0;0;0;0;0;0;0
+14.2;19;24072;3.0293;41;1500;0;0;0;0;0;0;0
+14.3;19;24072;3.0293;30;1500;0;0;0;0;0;0;0
+14.4;19;24072;3.0293;23;1500;0;0;0;0;0;0;0
+14.5;19;24072;3.0293;17;1500;0;0;0;0;0;0;0
+14.6;19;24072;3.0293;9;1500;0;0;0;0;0;0;0
+14.7;19;24072;3.0293;5;1500;0;0;0;0;0;0;0
+14.8;19;24072;3.0293;3;1500;0;0;0;0;0;0;0
+14.9;19;24072;3.0293;2;1500;0;0;0;0;0;0;0
+15;19;24072;3.0293;1;1500;0;0;0;0;0;0;0
+15.1;19;24072;3.0293;0;1500;0;0;0;0;0;0;0
+15.2;19;24072;3.0293;0;1500;0;0;0;0;0;0;0
+15.3;19;24072;3.0293;0;1500;0;0;0;0;0;0;0
+15.4;19;24072;3.0293;0;1500;0;0;0;0;0;0;0
+15.5;19;24072;3.0293;0;1500;0;0;0;0;0;0;0
+15.6;19;24072;3.0293;0;1500;0;0;0;0;0;0;0
+15.7;19;24072;3.0293;0;1500;0;0;0;0;0;0;0
+15.8;19;24072;3.0293;0;1500;0;0;0;0;0;0;0
+15.9;19;24072;3.0293;0;1500;0;0;0;0;0;0;0
+16;19;24072;3.0293;0;1500;0;0;0;0;0;0;0
+16.1;19;24072;3.0293;0;1500;0;0;0;0;0;0;0
+16.2;19;24072;3.0293;0;1500;0;0;0;0;0;0;0
+16.3;19;24072;3.0293;0;1500;0;0;0;0;0;0;0
+16.4;19;24072;3.0293;0;1500;0;0;0;0;0;0;0
+16.5;19;24072;3.0293;0;1500;0;0;0;0;0;0;0
+16.6;19;24072;3.0293;0;1500;0;0;0;0;0;0;0
+16.7;19;24072;3.0293;0;1500;0;0;0;0;0;0;0
+16.8;19;24072;3.0293;0;1500;0;0;0;0;0;0;0
+16.9;19;24072;3.0293;0;1500;0;0;0;0;0;0;0
+17;19;24072;3.0293;0;1500;0;0;0;0;0;0;0
diff --git a/openair1/SIMULATION/NR_PHY/BLER_SIMULATIONS/AWGN/AWGN_results/mcs1_awgn_5G.csv b/openair1/SIMULATION/NR_PHY/BLER_SIMULATIONS/AWGN/AWGN_results/mcs1_awgn_5G.csv
new file mode 100644
index 0000000000000000000000000000000000000000..ccb17b0d1c242fff7364b3fe391be6fa93b98f9e
--- /dev/null
+++ b/openair1/SIMULATION/NR_PHY/BLER_SIMULATIONS/AWGN/AWGN_results/mcs1_awgn_5G.csv
@@ -0,0 +1,27 @@
+SNR;MCS;TBS;rate;err0;trials0;err1;trials1;err2;trials2;err3;trials3;dci_err
+-4;1;2472;0.3066;1500;1500;0;0;0;0;0;0;0
+-3.9;1;2472;0.3066;1497;1500;0;0;0;0;0;0;0
+-3.8;1;2472;0.3066;1494;1500;0;0;0;0;0;0;0
+-3.7;1;2472;0.3066;1490;1500;0;0;0;0;0;0;0
+-3.6;1;2472;0.3066;1487;1500;0;0;0;0;0;0;0
+-3.5;1;2472;0.3066;1484;1500;0;0;0;0;0;0;0
+-3.4;1;2472;0.3066;1386;1500;0;0;0;0;0;0;0
+-3.3;1;2472;0.3066;1295;1500;0;0;0;0;0;0;0
+-3.2;1;2472;0.3066;1209;1500;0;0;0;0;0;0;0
+-3.1;1;2472;0.3066;1130;1500;0;0;0;0;0;0;0
+-3;1;2472;0.3066;1055;1500;0;0;0;0;0;0;0
+-2.9;1;2472;0.3066;863;1500;0;0;0;0;0;0;0
+-2.8;1;2472;0.3066;706;1500;0;0;0;0;0;0;0
+-2.7;1;2472;0.3066;577;1500;0;0;0;0;0;0;0
+-2.6;1;2472;0.3066;472;1500;0;0;0;0;0;0;0
+-2.5;1;2472;0.3066;386;1500;0;0;0;0;0;0;0
+-2.4;1;2472;0.3066;215;1500;0;0;0;0;0;0;0
+-2.3;1;2472;0.3066;120;1500;0;0;0;0;0;0;0
+-2.2;1;2472;0.3066;67;1500;0;0;0;0;0;0;0
+-2.1;1;2472;0.3066;37;1500;0;0;0;0;0;0;0
+-2;1;2472;0.3066;21;1500;0;0;0;0;0;0;0
+-1.9;1;2472;0.3066;9;1500;0;0;0;0;0;0;0
+-1.8;1;2472;0.3066;4;1500;0;0;0;0;0;0;0
+-1.7;1;2472;0.3066;2;1500;0;0;0;0;0;0;0
+-1.6;1;2472;0.3066;1;1500;0;0;0;0;0;0;0
+-1.5;1;2472;0.3066;0;1500;0;0;0;0;0;0;0
diff --git a/openair1/SIMULATION/NR_PHY/BLER_SIMULATIONS/AWGN/AWGN_results/mcs20_awgn_5G.csv b/openair1/SIMULATION/NR_PHY/BLER_SIMULATIONS/AWGN/AWGN_results/mcs20_awgn_5G.csv
new file mode 100644
index 0000000000000000000000000000000000000000..69d005539543426c5e8b09c3b6b3a5a77f6a8b51
--- /dev/null
+++ b/openair1/SIMULATION/NR_PHY/BLER_SIMULATIONS/AWGN/AWGN_results/mcs20_awgn_5G.csv
@@ -0,0 +1,72 @@
+SNR;MCS;TBS;rate;err0;trials0;err1;trials1;err2;trials2;err3;trials3;dci_err
+10;20;26632;3.3223;1500;1500;0;0;0;0;0;0;0
+10.1;20;26632;3.3223;1500;1500;0;0;0;0;0;0;0
+10.2;20;26632;3.3223;1500;1500;0;0;0;0;0;0;0
+10.3;20;26632;3.3223;1500;1500;0;0;0;0;0;0;0
+10.4;20;26632;3.3223;1500;1500;0;0;0;0;0;0;0
+10.5;20;26632;3.3223;1500;1500;0;0;0;0;0;0;0
+10.6;20;26632;3.3223;1500;1500;0;0;0;0;0;0;0
+10.7;20;26632;3.3223;1500;1500;0;0;0;0;0;0;0
+10.8;20;26632;3.3223;1500;1500;0;0;0;0;0;0;0
+10.9;20;26632;3.3223;1500;1500;0;0;0;0;0;0;0
+11;20;26632;3.3223;1500;1500;0;0;0;0;0;0;0
+11.1;20;26632;3.3223;1500;1500;0;0;0;0;0;0;0
+11.2;20;26632;3.3223;1500;1500;0;0;0;0;0;0;0
+11.3;20;26632;3.3223;1500;1500;0;0;0;0;0;0;0
+11.4;20;26632;3.3223;1500;1500;0;0;0;0;0;0;0
+11.5;20;26632;3.3223;1500;1500;0;0;0;0;0;0;0
+11.6;20;26632;3.3223;1500;1500;0;0;0;0;0;0;0
+11.7;20;26632;3.3223;1500;1500;0;0;0;0;0;0;0
+11.8;20;26632;3.3223;1500;1500;0;0;0;0;0;0;0
+11.9;20;26632;3.3223;1500;1500;0;0;0;0;0;0;0
+12;20;26632;3.3223;1500;1500;0;0;0;0;0;0;0
+12.1;20;26632;3.3223;1500;1500;0;0;0;0;0;0;0
+12.2;20;26632;3.3223;1500;1500;0;0;0;0;0;0;0
+12.3;20;26632;3.3223;1500;1500;0;0;0;0;0;0;0
+12.4;20;26632;3.3223;1500;1500;0;0;0;0;0;0;0
+12.5;20;26632;3.3223;1500;1500;0;0;0;0;0;0;0
+12.6;20;26632;3.3223;1500;1500;0;0;0;0;0;0;0
+12.7;20;26632;3.3223;1500;1500;0;0;0;0;0;0;0
+12.8;20;26632;3.3223;1500;1500;0;0;0;0;0;0;0
+12.9;20;26632;3.3223;1500;1500;0;0;0;0;0;0;0
+13;20;26632;3.3223;1500;1500;0;0;0;0;0;0;0
+13.1;20;26632;3.3223;1499;1500;0;0;0;0;0;0;0
+13.2;20;26632;3.3223;1499;1500;0;0;0;0;0;0;0
+13.3;20;26632;3.3223;1498;1500;0;0;0;0;0;0;0
+13.4;20;26632;3.3223;1498;1500;0;0;0;0;0;0;0
+13.5;20;26632;3.3223;1497;1500;0;0;0;0;0;0;0
+13.6;20;26632;3.3223;1390;1500;0;0;0;0;0;0;0
+13.7;20;26632;3.3223;1291;1500;0;0;0;0;0;0;0
+13.8;20;26632;3.3223;1199;1500;0;0;0;0;0;0;0
+13.9;20;26632;3.3223;1113;1500;0;0;0;0;0;0;0
+14;20;26632;3.3223;1034;1500;0;0;0;0;0;0;0
+14.1;20;26632;3.3223;745;1500;0;0;0;0;0;0;0
+14.2;20;26632;3.3223;537;1500;0;0;0;0;0;0;0
+14.3;20;26632;3.3223;387;1500;0;0;0;0;0;0;0
+14.4;20;26632;3.3223;279;1500;0;0;0;0;0;0;0
+14.5;20;26632;3.3223;201;1500;0;0;0;0;0;0;0
+14.6;20;26632;3.3223;161;1500;0;0;0;0;0;0;0
+14.7;20;26632;3.3223;129;1500;0;0;0;0;0;0;0
+14.8;20;26632;3.3223;104;1500;0;0;0;0;0;0;0
+14.9;20;26632;3.3223;83;1500;0;0;0;0;0;0;0
+15;20;26632;3.3223;67;1500;0;0;0;0;0;0;0
+15.1;20;26632;3.3223;45;1500;0;0;0;0;0;0;0
+15.2;20;26632;3.3223;30;1500;0;0;0;0;0;0;0
+15.3;20;26632;3.3223;20;1500;0;0;0;0;0;0;0
+15.4;20;26632;3.3223;13;1500;0;0;0;0;0;0;0
+15.5;20;26632;3.3223;9;1500;0;0;0;0;0;0;0
+15.6;20;26632;3.3223;4;1500;0;0;0;0;0;0;0
+15.7;20;26632;3.3223;1;1500;0;0;0;0;0;0;0
+15.8;20;26632;3.3223;1;1500;0;0;0;0;0;0;0
+15.9;20;26632;3.3223;0;1500;0;0;0;0;0;0;0
+16;20;26632;3.3223;0;1500;0;0;0;0;0;0;0
+16.1;20;26632;3.3223;0;1500;0;0;0;0;0;0;0
+16.2;20;26632;3.3223;0;1500;0;0;0;0;0;0;0
+16.3;20;26632;3.3223;0;1500;0;0;0;0;0;0;0
+16.4;20;26632;3.3223;0;1500;0;0;0;0;0;0;0
+16.5;20;26632;3.3223;0;1500;0;0;0;0;0;0;0
+16.6;20;26632;3.3223;0;1500;0;0;0;0;0;0;0
+16.7;20;26632;3.3223;0;1500;0;0;0;0;0;0;0
+16.8;20;26632;3.3223;0;1500;0;0;0;0;0;0;0
+16.9;20;26632;3.3223;0;1500;0;0;0;0;0;0;0
+17;20;26632;3.3223;0;1500;0;0;0;0;0;0;0
diff --git a/openair1/SIMULATION/NR_PHY/BLER_SIMULATIONS/AWGN/AWGN_results/mcs21_awgn_5G.csv b/openair1/SIMULATION/NR_PHY/BLER_SIMULATIONS/AWGN/AWGN_results/mcs21_awgn_5G.csv
new file mode 100644
index 0000000000000000000000000000000000000000..2a5a691afb199ca80fe96c94d01bbf97682b69e4
--- /dev/null
+++ b/openair1/SIMULATION/NR_PHY/BLER_SIMULATIONS/AWGN/AWGN_results/mcs21_awgn_5G.csv
@@ -0,0 +1,72 @@
+SNR;MCS;TBS;rate;err0;trials0;err1;trials1;err2;trials2;err3;trials3;dci_err
+10;21;28680;3.6094;1500;1500;0;0;0;0;0;0;0
+10.1;21;28680;3.6094;1500;1500;0;0;0;0;0;0;0
+10.2;21;28680;3.6094;1500;1500;0;0;0;0;0;0;0
+10.3;21;28680;3.6094;1500;1500;0;0;0;0;0;0;0
+10.4;21;28680;3.6094;1500;1500;0;0;0;0;0;0;0
+10.5;21;28680;3.6094;1500;1500;0;0;0;0;0;0;0
+10.6;21;28680;3.6094;1500;1500;0;0;0;0;0;0;0
+10.7;21;28680;3.6094;1500;1500;0;0;0;0;0;0;0
+10.8;21;28680;3.6094;1500;1500;0;0;0;0;0;0;0
+10.9;21;28680;3.6094;1500;1500;0;0;0;0;0;0;0
+11;21;28680;3.6094;1500;1500;0;0;0;0;0;0;0
+11.1;21;28680;3.6094;1500;1500;0;0;0;0;0;0;0
+11.2;21;28680;3.6094;1500;1500;0;0;0;0;0;0;0
+11.3;21;28680;3.6094;1500;1500;0;0;0;0;0;0;0
+11.4;21;28680;3.6094;1500;1500;0;0;0;0;0;0;0
+11.5;21;28680;3.6094;1500;1500;0;0;0;0;0;0;0
+11.6;21;28680;3.6094;1500;1500;0;0;0;0;0;0;0
+11.7;21;28680;3.6094;1500;1500;0;0;0;0;0;0;0
+11.8;21;28680;3.6094;1500;1500;0;0;0;0;0;0;0
+11.9;21;28680;3.6094;1500;1500;0;0;0;0;0;0;0
+12;21;28680;3.6094;1500;1500;0;0;0;0;0;0;0
+12.1;21;28680;3.6094;1500;1500;0;0;0;0;0;0;0
+12.2;21;28680;3.6094;1500;1500;0;0;0;0;0;0;0
+12.3;21;28680;3.6094;1500;1500;0;0;0;0;0;0;0
+12.4;21;28680;3.6094;1500;1500;0;0;0;0;0;0;0
+12.5;21;28680;3.6094;1500;1500;0;0;0;0;0;0;0
+12.6;21;28680;3.6094;1500;1500;0;0;0;0;0;0;0
+12.7;21;28680;3.6094;1500;1500;0;0;0;0;0;0;0
+12.8;21;28680;3.6094;1500;1500;0;0;0;0;0;0;0
+12.9;21;28680;3.6094;1500;1500;0;0;0;0;0;0;0
+13;21;28680;3.6094;1500;1500;0;0;0;0;0;0;0
+13.1;21;28680;3.6094;1500;1500;0;0;0;0;0;0;0
+13.2;21;28680;3.6094;1500;1500;0;0;0;0;0;0;0
+13.3;21;28680;3.6094;1500;1500;0;0;0;0;0;0;0
+13.4;21;28680;3.6094;1500;1500;0;0;0;0;0;0;0
+13.5;21;28680;3.6094;1500;1500;0;0;0;0;0;0;0
+13.6;21;28680;3.6094;1500;1500;0;0;0;0;0;0;0
+13.7;21;28680;3.6094;1500;1500;0;0;0;0;0;0;0
+13.8;21;28680;3.6094;1500;1500;0;0;0;0;0;0;0
+13.9;21;28680;3.6094;1500;1500;0;0;0;0;0;0;0
+14;21;28680;3.6094;1500;1500;0;0;0;0;0;0;0
+14.1;21;28680;3.6094;1472;1500;0;0;0;0;0;0;0
+14.2;21;28680;3.6094;1444;1500;0;0;0;0;0;0;0
+14.3;21;28680;3.6094;1417;1500;0;0;0;0;0;0;0
+14.4;21;28680;3.6094;1390;1500;0;0;0;0;0;0;0
+14.5;21;28680;3.6094;1364;1500;0;0;0;0;0;0;0
+14.6;21;28680;3.6094;1040;1500;0;0;0;0;0;0;0
+14.7;21;28680;3.6094;793;1500;0;0;0;0;0;0;0
+14.8;21;28680;3.6094;605;1500;0;0;0;0;0;0;0
+14.9;21;28680;3.6094;461;1500;0;0;0;0;0;0;0
+15;21;28680;3.6094;351;1500;0;0;0;0;0;0;0
+15.1;21;28680;3.6094;265;1500;0;0;0;0;0;0;0
+15.2;21;28680;3.6094;199;1500;0;0;0;0;0;0;0
+15.3;21;28680;3.6094;150;1500;0;0;0;0;0;0;0
+15.4;21;28680;3.6094;113;1500;0;0;0;0;0;0;0
+15.5;21;28680;3.6094;85;1500;0;0;0;0;0;0;0
+15.6;21;28680;3.6094;79;1500;0;0;0;0;0;0;0
+15.7;21;28680;3.6094;73;1500;0;0;0;0;0;0;0
+15.8;21;28680;3.6094;67;1500;0;0;0;0;0;0;0
+15.9;21;28680;3.6094;62;1500;0;0;0;0;0;0;0
+16;21;28680;3.6094;57;1500;0;0;0;0;0;0;0
+16.1;21;28680;3.6094;37;1500;0;0;0;0;0;0;0
+16.2;21;28680;3.6094;23;1500;0;0;0;0;0;0;0
+16.3;21;28680;3.6094;15;1500;0;0;0;0;0;0;0
+16.4;21;28680;3.6094;10;1500;0;0;0;0;0;0;0
+16.5;21;28680;3.6094;6;1500;0;0;0;0;0;0;0
+16.6;21;28680;3.6094;3;1500;0;0;0;0;0;0;0
+16.7;21;28680;3.6094;1;1500;0;0;0;0;0;0;0
+16.8;21;28680;3.6094;1;1500;0;0;0;0;0;0;0
+16.9;21;28680;3.6094;0;1500;0;0;0;0;0;0;0
+17;21;28680;3.6094;0;1500;0;0;0;0;0;0;0
diff --git a/openair1/SIMULATION/NR_PHY/BLER_SIMULATIONS/AWGN/AWGN_results/mcs22_awgn_5G.csv b/openair1/SIMULATION/NR_PHY/BLER_SIMULATIONS/AWGN/AWGN_results/mcs22_awgn_5G.csv
new file mode 100644
index 0000000000000000000000000000000000000000..10a424137693f7cd28fac6ac97b2881fd6d3de50
--- /dev/null
+++ b/openair1/SIMULATION/NR_PHY/BLER_SIMULATIONS/AWGN/AWGN_results/mcs22_awgn_5G.csv
@@ -0,0 +1,52 @@
+SNR;MCS;TBS;rate;err0;trials0;err1;trials1;err2;trials2;err3;trials3;dci_err
+14;22;31240;3.9023;1500;1500;0;0;0;0;0;0;0
+14.1;22;31240;3.9023;1500;1500;0;0;0;0;0;0;0
+14.2;22;31240;3.9023;1500;1500;0;0;0;0;0;0;0
+14.3;22;31240;3.9023;1500;1500;0;0;0;0;0;0;0
+14.4;22;31240;3.9023;1500;1500;0;0;0;0;0;0;0
+14.5;22;31240;3.9023;1500;1500;0;0;0;0;0;0;0
+14.6;22;31240;3.9023;1500;1500;0;0;0;0;0;0;0
+14.7;22;31240;3.9023;1500;1500;0;0;0;0;0;0;0
+14.8;22;31240;3.9023;1500;1500;0;0;0;0;0;0;0
+14.9;22;31240;3.9023;1500;1500;0;0;0;0;0;0;0
+15;22;31240;3.9023;1500;1500;0;0;0;0;0;0;0
+15.1;22;31240;3.9023;1421;1500;0;0;0;0;0;0;0
+15.2;22;31240;3.9023;1347;1500;0;0;0;0;0;0;0
+15.3;22;31240;3.9023;1276;1500;0;0;0;0;0;0;0
+15.4;22;31240;3.9023;1209;1500;0;0;0;0;0;0;0
+15.5;22;31240;3.9023;1146;1500;0;0;0;0;0;0;0
+15.6;22;31240;3.9023;807;1500;0;0;0;0;0;0;0
+15.7;22;31240;3.9023;569;1500;0;0;0;0;0;0;0
+15.8;22;31240;3.9023;400;1500;0;0;0;0;0;0;0
+15.9;22;31240;3.9023;282;1500;0;0;0;0;0;0;0
+16;22;31240;3.9023;199;1500;0;0;0;0;0;0;0
+16.1;22;31240;3.9023;165;1500;0;0;0;0;0;0;0
+16.2;22;31240;3.9023;137;1500;0;0;0;0;0;0;0
+16.3;22;31240;3.9023;114;1500;0;0;0;0;0;0;0
+16.4;22;31240;3.9023;94;1500;0;0;0;0;0;0;0
+16.5;22;31240;3.9023;78;1500;0;0;0;0;0;0;0
+16.6;22;31240;3.9023;74;1500;0;0;0;0;0;0;0
+16.7;22;31240;3.9023;69;1500;0;0;0;0;0;0;0
+16.8;22;31240;3.9023;65;1500;0;0;0;0;0;0;0
+16.9;22;31240;3.9023;61;1500;0;0;0;0;0;0;0
+17;22;31240;3.9023;58;1500;0;0;0;0;0;0;0
+17.1;22;31240;3.9023;36;1500;0;0;0;0;0;0;0
+17.2;22;31240;3.9023;23;1500;0;0;0;0;0;0;0
+17.3;22;31240;3.9023;15;1500;0;0;0;0;0;0;0
+17.4;22;31240;3.9023;9;1500;0;0;0;0;0;0;0
+17.5;22;31240;3.9023;6;1500;0;0;0;0;0;0;0
+17.6;22;31240;3.9023;3;1500;0;0;0;0;0;0;0
+17.7;22;31240;3.9023;1;1500;0;0;0;0;0;0;0
+17.8;22;31240;3.9023;1;1500;0;0;0;0;0;0;0
+17.9;22;31240;3.9023;0;1500;0;0;0;0;0;0;0
+18;22;31240;3.9023;0;1500;0;0;0;0;0;0;0
+18.1;22;31240;3.9023;0;1500;0;0;0;0;0;0;0
+18.2;22;31240;3.9023;0;1500;0;0;0;0;0;0;0
+18.3;22;31240;3.9023;0;1500;0;0;0;0;0;0;0
+18.4;22;31240;3.9023;0;1500;0;0;0;0;0;0;0
+18.5;22;31240;3.9023;0;1500;0;0;0;0;0;0;0
+18.6;22;31240;3.9023;0;1500;0;0;0;0;0;0;0
+18.7;22;31240;3.9023;0;1500;0;0;0;0;0;0;0
+18.8;22;31240;3.9023;0;1500;0;0;0;0;0;0;0
+18.9;22;31240;3.9023;0;1500;0;0;0;0;0;0;0
+19;22;31240;3.9023;0;1500;0;0;0;0;0;0;0
diff --git a/openair1/SIMULATION/NR_PHY/BLER_SIMULATIONS/AWGN/AWGN_results/mcs23_awgn_5G.csv b/openair1/SIMULATION/NR_PHY/BLER_SIMULATIONS/AWGN/AWGN_results/mcs23_awgn_5G.csv
new file mode 100644
index 0000000000000000000000000000000000000000..07e9e257fffa20abaf6789ea858e3d006a2995de
--- /dev/null
+++ b/openair1/SIMULATION/NR_PHY/BLER_SIMULATIONS/AWGN/AWGN_results/mcs23_awgn_5G.csv
@@ -0,0 +1,92 @@
+SNR;MCS;TBS;rate;err0;trials0;err1;trials1;err2;trials2;err3;trials3;dci_err
+15;23;33816;4.2129;1500;1500;0;0;0;0;0;0;0
+15.1;23;33816;4.2129;1500;1500;0;0;0;0;0;0;0
+15.2;23;33816;4.2129;1500;1500;0;0;0;0;0;0;0
+15.3;23;33816;4.2129;1500;1500;0;0;0;0;0;0;0
+15.4;23;33816;4.2129;1500;1500;0;0;0;0;0;0;0
+15.5;23;33816;4.2129;1500;1500;0;0;0;0;0;0;0
+15.6;23;33816;4.2129;1499;1500;0;0;0;0;0;0;0
+15.7;23;33816;4.2129;1499;1500;0;0;0;0;0;0;0
+15.8;23;33816;4.2129;1498;1500;0;0;0;0;0;0;0
+15.9;23;33816;4.2129;1498;1500;0;0;0;0;0;0;0
+16;23;33816;4.2129;1497;1500;0;0;0;0;0;0;0
+16.1;23;33816;4.2129;1360;1500;0;0;0;0;0;0;0
+16.2;23;33816;4.2129;1236;1500;0;0;0;0;0;0;0
+16.3;23;33816;4.2129;1123;1500;0;0;0;0;0;0;0
+16.4;23;33816;4.2129;1020;1500;0;0;0;0;0;0;0
+16.5;23;33816;4.2129;927;1500;0;0;0;0;0;0;0
+16.6;23;33816;4.2129;630;1500;0;0;0;0;0;0;0
+16.7;23;33816;4.2129;428;1500;0;0;0;0;0;0;0
+16.8;23;33816;4.2129;291;1500;0;0;0;0;0;0;0
+16.9;23;33816;4.2129;198;1500;0;0;0;0;0;0;0
+17;23;33816;4.2129;135;1500;0;0;0;0;0;0;0
+17.1;23;33816;4.2129;120;1500;0;0;0;0;0;0;0
+17.2;23;33816;4.2129;108;1500;0;0;0;0;0;0;0
+17.3;23;33816;4.2129;96;1500;0;0;0;0;0;0;0
+17.4;23;33816;4.2129;86;1500;0;0;0;0;0;0;0
+17.5;23;33816;4.2129;77;1500;0;0;0;0;0;0;0
+17.6;23;33816;4.2129;70;1500;0;0;0;0;0;0;0
+17.7;23;33816;4.2129;63;1500;0;0;0;0;0;0;0
+17.8;23;33816;4.2129;57;1500;0;0;0;0;0;0;0
+17.9;23;33816;4.2129;52;1500;0;0;0;0;0;0;0
+18;23;33816;4.2129;47;1500;0;0;0;0;0;0;0
+18.1;23;33816;4.2129;28;1500;0;0;0;0;0;0;0
+18.2;23;33816;4.2129;16;1500;0;0;0;0;0;0;0
+18.3;23;33816;4.2129;9;1500;0;0;0;0;0;0;0
+18.4;23;33816;4.2129;6;1500;0;0;0;0;0;0;0
+18.5;23;33816;4.2129;3;1500;0;0;0;0;0;0;0
+18.6;23;33816;4.2129;3;1500;0;0;0;0;0;0;0
+18.7;23;33816;4.2129;3;1500;0;0;0;0;0;0;0
+18.8;23;33816;4.2129;3;1500;0;0;0;0;0;0;0
+18.9;23;33816;4.2129;3;1500;0;0;0;0;0;0;0
+19;23;33816;4.2129;3;1500;0;0;0;0;0;0;0
+19.1;23;33816;4.2129;3;1500;0;0;0;0;0;0;0
+19.2;23;33816;4.2129;4;1500;0;0;0;0;0;0;0
+19.3;23;33816;4.2129;5;1500;0;0;0;0;0;0;0
+19.4;23;33816;4.2129;6;1500;0;0;0;0;0;0;0
+19.5;23;33816;4.2129;8;1500;0;0;0;0;0;0;0
+19.6;23;33816;4.2129;6;1500;0;0;0;0;0;0;0
+19.7;23;33816;4.2129;4;1500;0;0;0;0;0;0;0
+19.8;23;33816;4.2129;3;1500;0;0;0;0;0;0;0
+19.9;23;33816;4.2129;2;1500;0;0;0;0;0;0;0
+20;23;33816;4.2129;2;1500;0;0;0;0;0;0;0
+20.1;23;33816;4.2129;1;1500;0;0;0;0;0;0;0
+20.2;23;33816;4.2129;1;1500;0;0;0;0;0;0;0
+20.3;23;33816;4.2129;0;1500;0;0;0;0;0;0;0
+20.4;23;33816;4.2129;0;1500;0;0;0;0;0;0;0
+20.5;23;33816;4.2129;0;1500;0;0;0;0;0;0;0
+20.6;23;33816;4.2129;0;1500;0;0;0;0;0;0;0
+20.7;23;33816;4.2129;0;1500;0;0;0;0;0;0;0
+20.8;23;33816;4.2129;0;1500;0;0;0;0;0;0;0
+20.9;23;33816;4.2129;0;1500;0;0;0;0;0;0;0
+21;23;33816;4.2129;0;1500;0;0;0;0;0;0;0
+21.1;23;33816;4.2129;0;1500;0;0;0;0;0;0;0
+21.2;23;33816;4.2129;0;1500;0;0;0;0;0;0;0
+21.3;23;33816;4.2129;0;1500;0;0;0;0;0;0;0
+21.4;23;33816;4.2129;0;1500;0;0;0;0;0;0;0
+21.5;23;33816;4.2129;0;1500;0;0;0;0;0;0;0
+21.6;23;33816;4.2129;0;1500;0;0;0;0;0;0;0
+21.7;23;33816;4.2129;0;1500;0;0;0;0;0;0;0
+21.8;23;33816;4.2129;0;1500;0;0;0;0;0;0;0
+21.9;23;33816;4.2129;0;1500;0;0;0;0;0;0;0
+22;23;33816;4.2129;0;1500;0;0;0;0;0;0;0
+22.1;23;33816;4.2129;0;1500;0;0;0;0;0;0;0
+22.2;23;33816;4.2129;0;1500;0;0;0;0;0;0;0
+22.3;23;33816;4.2129;0;1500;0;0;0;0;0;0;0
+22.4;23;33816;4.2129;0;1500;0;0;0;0;0;0;0
+22.5;23;33816;4.2129;0;1500;0;0;0;0;0;0;0
+22.6;23;33816;4.2129;0;1500;0;0;0;0;0;0;0
+22.7;23;33816;4.2129;0;1500;0;0;0;0;0;0;0
+22.8;23;33816;4.2129;0;1500;0;0;0;0;0;0;0
+22.9;23;33816;4.2129;0;1500;0;0;0;0;0;0;0
+23;23;33816;4.2129;0;1500;0;0;0;0;0;0;0
+23.1;23;33816;4.2129;0;1500;0;0;0;0;0;0;0
+23.2;23;33816;4.2129;0;1500;0;0;0;0;0;0;0
+23.3;23;33816;4.2129;0;1500;0;0;0;0;0;0;0
+23.4;23;33816;4.2129;0;1500;0;0;0;0;0;0;0
+23.5;23;33816;4.2129;0;1500;0;0;0;0;0;0;0
+23.6;23;33816;4.2129;0;1500;0;0;0;0;0;0;0
+23.7;23;33816;4.2129;0;1500;0;0;0;0;0;0;0
+23.8;23;33816;4.2129;0;1500;0;0;0;0;0;0;0
+23.9;23;33816;4.2129;0;1500;0;0;0;0;0;0;0
+24;23;33816;4.2129;0;1500;0;0;0;0;0;0;0
diff --git a/openair1/SIMULATION/NR_PHY/BLER_SIMULATIONS/AWGN/AWGN_results/mcs24_awgn_5G.csv b/openair1/SIMULATION/NR_PHY/BLER_SIMULATIONS/AWGN/AWGN_results/mcs24_awgn_5G.csv
new file mode 100644
index 0000000000000000000000000000000000000000..6eac0f3f7ddcbce37fee28f8d3c012830a2e1287
--- /dev/null
+++ b/openair1/SIMULATION/NR_PHY/BLER_SIMULATIONS/AWGN/AWGN_results/mcs24_awgn_5G.csv
@@ -0,0 +1,92 @@
+SNR;MCS;TBS;rate;err0;trials0;err1;trials1;err2;trials2;err3;trials3;dci_err
+15;24;35856;4.5234;1500;1500;0;0;0;0;0;0;0
+15.1;24;35856;4.5234;1500;1500;0;0;0;0;0;0;0
+15.2;24;35856;4.5234;1500;1500;0;0;0;0;0;0;0
+15.3;24;35856;4.5234;1500;1500;0;0;0;0;0;0;0
+15.4;24;35856;4.5234;1500;1500;0;0;0;0;0;0;0
+15.5;24;35856;4.5234;1500;1500;0;0;0;0;0;0;0
+15.6;24;35856;4.5234;1500;1500;0;0;0;0;0;0;0
+15.7;24;35856;4.5234;1500;1500;0;0;0;0;0;0;0
+15.8;24;35856;4.5234;1500;1500;0;0;0;0;0;0;0
+15.9;24;35856;4.5234;1500;1500;0;0;0;0;0;0;0
+16;24;35856;4.5234;1500;1500;0;0;0;0;0;0;0
+16.1;24;35856;4.5234;1500;1500;0;0;0;0;0;0;0
+16.2;24;35856;4.5234;1500;1500;0;0;0;0;0;0;0
+16.3;24;35856;4.5234;1500;1500;0;0;0;0;0;0;0
+16.4;24;35856;4.5234;1500;1500;0;0;0;0;0;0;0
+16.5;24;35856;4.5234;1500;1500;0;0;0;0;0;0;0
+16.6;24;35856;4.5234;1474;1500;0;0;0;0;0;0;0
+16.7;24;35856;4.5234;1449;1500;0;0;0;0;0;0;0
+16.8;24;35856;4.5234;1424;1500;0;0;0;0;0;0;0
+16.9;24;35856;4.5234;1400;1500;0;0;0;0;0;0;0
+17;24;35856;4.5234;1376;1500;0;0;0;0;0;0;0
+17.1;24;35856;4.5234;1016;1500;0;0;0;0;0;0;0
+17.2;24;35856;4.5234;751;1500;0;0;0;0;0;0;0
+17.3;24;35856;4.5234;554;1500;0;0;0;0;0;0;0
+17.4;24;35856;4.5234;410;1500;0;0;0;0;0;0;0
+17.5;24;35856;4.5234;303;1500;0;0;0;0;0;0;0
+17.6;24;35856;4.5234;232;1500;0;0;0;0;0;0;0
+17.7;24;35856;4.5234;177;1500;0;0;0;0;0;0;0
+17.8;24;35856;4.5234;136;1500;0;0;0;0;0;0;0
+17.9;24;35856;4.5234;104;1500;0;0;0;0;0;0;0
+18;24;35856;4.5234;80;1500;0;0;0;0;0;0;0
+18.1;24;35856;4.5234;79;1500;0;0;0;0;0;0;0
+18.2;24;35856;4.5234;78;1500;0;0;0;0;0;0;0
+18.3;24;35856;4.5234;77;1500;0;0;0;0;0;0;0
+18.4;24;35856;4.5234;76;1500;0;0;0;0;0;0;0
+18.5;24;35856;4.5234;75;1500;0;0;0;0;0;0;0
+18.6;24;35856;4.5234;59;1500;0;0;0;0;0;0;0
+18.7;24;35856;4.5234;46;1500;0;0;0;0;0;0;0
+18.8;24;35856;4.5234;36;1500;0;0;0;0;0;0;0
+18.9;24;35856;4.5234;28;1500;0;0;0;0;0;0;0
+19;24;35856;4.5234;22;1500;0;0;0;0;0;0;0
+19.1;24;35856;4.5234;21;1500;0;0;0;0;0;0;0
+19.2;24;35856;4.5234;20;1500;0;0;0;0;0;0;0
+19.3;24;35856;4.5234;20;1500;0;0;0;0;0;0;0
+19.4;24;35856;4.5234;19;1500;0;0;0;0;0;0;0
+19.5;24;35856;4.5234;18;1500;0;0;0;0;0;0;0
+19.6;24;35856;4.5234;22;1500;0;0;0;0;0;0;0
+19.7;24;35856;4.5234;26;1500;0;0;0;0;0;0;0
+19.8;24;35856;4.5234;31;1500;0;0;0;0;0;0;0
+19.9;24;35856;4.5234;36;1500;0;0;0;0;0;0;0
+20;24;35856;4.5234;43;1500;0;0;0;0;0;0;0
+20.1;24;35856;4.5234;35;1500;0;0;0;0;0;0;0
+20.2;24;35856;4.5234;29;1500;0;0;0;0;0;0;0
+20.3;24;35856;4.5234;23;1500;0;0;0;0;0;0;0
+20.4;24;35856;4.5234;19;1500;0;0;0;0;0;0;0
+20.5;24;35856;4.5234;15;1500;0;0;0;0;0;0;0
+20.6;24;35856;4.5234;8;1500;0;0;0;0;0;0;0
+20.7;24;35856;4.5234;4;1500;0;0;0;0;0;0;0
+20.8;24;35856;4.5234;2;1500;0;0;0;0;0;0;0
+20.9;24;35856;4.5234;1;1500;0;0;0;0;0;0;0
+21;24;35856;4.5234;1;1500;0;0;0;0;0;0;0
+21.1;24;35856;4.5234;0;1500;0;0;0;0;0;0;0
+21.2;24;35856;4.5234;0;1500;0;0;0;0;0;0;0
+21.3;24;35856;4.5234;0;1500;0;0;0;0;0;0;0
+21.4;24;35856;4.5234;0;1500;0;0;0;0;0;0;0
+21.5;24;35856;4.5234;0;1500;0;0;0;0;0;0;0
+21.6;24;35856;4.5234;0;1500;0;0;0;0;0;0;0
+21.7;24;35856;4.5234;0;1500;0;0;0;0;0;0;0
+21.8;24;35856;4.5234;0;1500;0;0;0;0;0;0;0
+21.9;24;35856;4.5234;0;1500;0;0;0;0;0;0;0
+22;24;35856;4.5234;0;1500;0;0;0;0;0;0;0
+22.1;24;35856;4.5234;0;1500;0;0;0;0;0;0;0
+22.2;24;35856;4.5234;0;1500;0;0;0;0;0;0;0
+22.3;24;35856;4.5234;0;1500;0;0;0;0;0;0;0
+22.4;24;35856;4.5234;0;1500;0;0;0;0;0;0;0
+22.5;24;35856;4.5234;0;1500;0;0;0;0;0;0;0
+22.6;24;35856;4.5234;0;1500;0;0;0;0;0;0;0
+22.7;24;35856;4.5234;0;1500;0;0;0;0;0;0;0
+22.8;24;35856;4.5234;0;1500;0;0;0;0;0;0;0
+22.9;24;35856;4.5234;0;1500;0;0;0;0;0;0;0
+23;24;35856;4.5234;0;1500;0;0;0;0;0;0;0
+23.1;24;35856;4.5234;0;1500;0;0;0;0;0;0;0
+23.2;24;35856;4.5234;0;1500;0;0;0;0;0;0;0
+23.3;24;35856;4.5234;0;1500;0;0;0;0;0;0;0
+23.4;24;35856;4.5234;0;1500;0;0;0;0;0;0;0
+23.5;24;35856;4.5234;0;1500;0;0;0;0;0;0;0
+23.6;24;35856;4.5234;0;1500;0;0;0;0;0;0;0
+23.7;24;35856;4.5234;0;1500;0;0;0;0;0;0;0
+23.8;24;35856;4.5234;0;1500;0;0;0;0;0;0;0
+23.9;24;35856;4.5234;0;1500;0;0;0;0;0;0;0
+24;24;35856;4.5234;0;1500;0;0;0;0;0;0;0
diff --git a/openair1/SIMULATION/NR_PHY/BLER_SIMULATIONS/AWGN/AWGN_results/mcs25_awgn_5G.csv b/openair1/SIMULATION/NR_PHY/BLER_SIMULATIONS/AWGN/AWGN_results/mcs25_awgn_5G.csv
new file mode 100644
index 0000000000000000000000000000000000000000..6f158f5bdc059d0a6351d3ea3e2a566021b60c9a
--- /dev/null
+++ b/openair1/SIMULATION/NR_PHY/BLER_SIMULATIONS/AWGN/AWGN_results/mcs25_awgn_5G.csv
@@ -0,0 +1,92 @@
+SNR;MCS;TBS;rate;err0;trials0;err1;trials1;err2;trials2;err3;trials3;dci_err
+15;25;37896;4.8164;1500;1500;0;0;0;0;0;0;0
+15.1;25;37896;4.8164;1500;1500;0;0;0;0;0;0;0
+15.2;25;37896;4.8164;1500;1500;0;0;0;0;0;0;0
+15.3;25;37896;4.8164;1500;1500;0;0;0;0;0;0;0
+15.4;25;37896;4.8164;1500;1500;0;0;0;0;0;0;0
+15.5;25;37896;4.8164;1500;1500;0;0;0;0;0;0;0
+15.6;25;37896;4.8164;1500;1500;0;0;0;0;0;0;0
+15.7;25;37896;4.8164;1500;1500;0;0;0;0;0;0;0
+15.8;25;37896;4.8164;1500;1500;0;0;0;0;0;0;0
+15.9;25;37896;4.8164;1500;1500;0;0;0;0;0;0;0
+16;25;37896;4.8164;1500;1500;0;0;0;0;0;0;0
+16.1;25;37896;4.8164;1500;1500;0;0;0;0;0;0;0
+16.2;25;37896;4.8164;1500;1500;0;0;0;0;0;0;0
+16.3;25;37896;4.8164;1500;1500;0;0;0;0;0;0;0
+16.4;25;37896;4.8164;1500;1500;0;0;0;0;0;0;0
+16.5;25;37896;4.8164;1500;1500;0;0;0;0;0;0;0
+16.6;25;37896;4.8164;1500;1500;0;0;0;0;0;0;0
+16.7;25;37896;4.8164;1500;1500;0;0;0;0;0;0;0
+16.8;25;37896;4.8164;1500;1500;0;0;0;0;0;0;0
+16.9;25;37896;4.8164;1500;1500;0;0;0;0;0;0;0
+17;25;37896;4.8164;1500;1500;0;0;0;0;0;0;0
+17.1;25;37896;4.8164;1493;1500;0;0;0;0;0;0;0
+17.2;25;37896;4.8164;1486;1500;0;0;0;0;0;0;0
+17.3;25;37896;4.8164;1478;1500;0;0;0;0;0;0;0
+17.4;25;37896;4.8164;1471;1500;0;0;0;0;0;0;0
+17.5;25;37896;4.8164;1464;1500;0;0;0;0;0;0;0
+17.6;25;37896;4.8164;1138;1500;0;0;0;0;0;0;0
+17.7;25;37896;4.8164;885;1500;0;0;0;0;0;0;0
+17.8;25;37896;4.8164;688;1500;0;0;0;0;0;0;0
+17.9;25;37896;4.8164;535;1500;0;0;0;0;0;0;0
+18;25;37896;4.8164;416;1500;0;0;0;0;0;0;0
+18.1;25;37896;4.8164;302;1500;0;0;0;0;0;0;0
+18.2;25;37896;4.8164;219;1500;0;0;0;0;0;0;0
+18.3;25;37896;4.8164;159;1500;0;0;0;0;0;0;0
+18.4;25;37896;4.8164;115;1500;0;0;0;0;0;0;0
+18.5;25;37896;4.8164;84;1500;0;0;0;0;0;0;0
+18.6;25;37896;4.8164;89;1500;0;0;0;0;0;0;0
+18.7;25;37896;4.8164;94;1500;0;0;0;0;0;0;0
+18.8;25;37896;4.8164;100;1500;0;0;0;0;0;0;0
+18.9;25;37896;4.8164;106;1500;0;0;0;0;0;0;0
+19;25;37896;4.8164;113;1500;0;0;0;0;0;0;0
+19.1;25;37896;4.8164;110;1500;0;0;0;0;0;0;0
+19.2;25;37896;4.8164;108;1500;0;0;0;0;0;0;0
+19.3;25;37896;4.8164;105;1500;0;0;0;0;0;0;0
+19.4;25;37896;4.8164;103;1500;0;0;0;0;0;0;0
+19.5;25;37896;4.8164;101;1500;0;0;0;0;0;0;0
+19.6;25;37896;4.8164;89;1500;0;0;0;0;0;0;0
+19.7;25;37896;4.8164;79;1500;0;0;0;0;0;0;0
+19.8;25;37896;4.8164;71;1500;0;0;0;0;0;0;0
+19.9;25;37896;4.8164;63;1500;0;0;0;0;0;0;0
+20;25;37896;4.8164;56;1500;0;0;0;0;0;0;0
+20.1;25;37896;4.8164;58;1500;0;0;0;0;0;0;0
+20.2;25;37896;4.8164;61;1500;0;0;0;0;0;0;0
+20.3;25;37896;4.8164;64;1500;0;0;0;0;0;0;0
+20.4;25;37896;4.8164;67;1500;0;0;0;0;0;0;0
+20.5;25;37896;4.8164;71;1500;0;0;0;0;0;0;0
+20.6;25;37896;4.8164;64;1500;0;0;0;0;0;0;0
+20.7;25;37896;4.8164;58;1500;0;0;0;0;0;0;0
+20.8;25;37896;4.8164;52;1500;0;0;0;0;0;0;0
+20.9;25;37896;4.8164;47;1500;0;0;0;0;0;0;0
+21;25;37896;4.8164;43;1500;0;0;0;0;0;0;0
+21.1;25;37896;4.8164;27;1500;0;0;0;0;0;0;0
+21.2;25;37896;4.8164;17;1500;0;0;0;0;0;0;0
+21.3;25;37896;4.8164;10;1500;0;0;0;0;0;0;0
+21.4;25;37896;4.8164;6;1500;0;0;0;0;0;0;0
+21.5;25;37896;4.8164;4;1500;0;0;0;0;0;0;0
+21.6;25;37896;4.8164;2;1500;0;0;0;0;0;0;0
+21.7;25;37896;4.8164;1;1500;0;0;0;0;0;0;0
+21.8;25;37896;4.8164;1;1500;0;0;0;0;0;0;0
+21.9;25;37896;4.8164;0;1500;0;0;0;0;0;0;0
+22;25;37896;4.8164;0;1500;0;0;0;0;0;0;0
+22.1;25;37896;4.8164;0;1500;0;0;0;0;0;0;0
+22.2;25;37896;4.8164;0;1500;0;0;0;0;0;0;0
+22.3;25;37896;4.8164;0;1500;0;0;0;0;0;0;0
+22.4;25;37896;4.8164;0;1500;0;0;0;0;0;0;0
+22.5;25;37896;4.8164;0;1500;0;0;0;0;0;0;0
+22.6;25;37896;4.8164;0;1500;0;0;0;0;0;0;0
+22.7;25;37896;4.8164;0;1500;0;0;0;0;0;0;0
+22.8;25;37896;4.8164;0;1500;0;0;0;0;0;0;0
+22.9;25;37896;4.8164;0;1500;0;0;0;0;0;0;0
+23;25;37896;4.8164;0;1500;0;0;0;0;0;0;0
+23.1;25;37896;4.8164;0;1500;0;0;0;0;0;0;0
+23.2;25;37896;4.8164;0;1500;0;0;0;0;0;0;0
+23.3;25;37896;4.8164;0;1500;0;0;0;0;0;0;0
+23.4;25;37896;4.8164;0;1500;0;0;0;0;0;0;0
+23.5;25;37896;4.8164;0;1500;0;0;0;0;0;0;0
+23.6;25;37896;4.8164;0;1500;0;0;0;0;0;0;0
+23.7;25;37896;4.8164;0;1500;0;0;0;0;0;0;0
+23.8;25;37896;4.8164;0;1500;0;0;0;0;0;0;0
+23.9;25;37896;4.8164;0;1500;0;0;0;0;0;0;0
+24;25;37896;4.8164;0;1500;0;0;0;0;0;0;0
diff --git a/openair1/SIMULATION/NR_PHY/BLER_SIMULATIONS/AWGN/AWGN_results/mcs26_awgn_5G.csv b/openair1/SIMULATION/NR_PHY/BLER_SIMULATIONS/AWGN/AWGN_results/mcs26_awgn_5G.csv
new file mode 100644
index 0000000000000000000000000000000000000000..94d779fb210f3c3ae5a84c3192a226a92a1a7a7b
--- /dev/null
+++ b/openair1/SIMULATION/NR_PHY/BLER_SIMULATIONS/AWGN/AWGN_results/mcs26_awgn_5G.csv
@@ -0,0 +1,92 @@
+SNR;MCS;TBS;rate;err0;trials0;err1;trials1;err2;trials2;err3;trials3;dci_err
+15;26;40976;5.1152;1500;1500;0;0;0;0;0;0;0
+15.1;26;40976;5.1152;1500;1500;0;0;0;0;0;0;0
+15.2;26;40976;5.1152;1500;1500;0;0;0;0;0;0;0
+15.3;26;40976;5.1152;1500;1500;0;0;0;0;0;0;0
+15.4;26;40976;5.1152;1500;1500;0;0;0;0;0;0;0
+15.5;26;40976;5.1152;1500;1500;0;0;0;0;0;0;0
+15.6;26;40976;5.1152;1500;1500;0;0;0;0;0;0;0
+15.7;26;40976;5.1152;1500;1500;0;0;0;0;0;0;0
+15.8;26;40976;5.1152;1500;1500;0;0;0;0;0;0;0
+15.9;26;40976;5.1152;1500;1500;0;0;0;0;0;0;0
+16;26;40976;5.1152;1500;1500;0;0;0;0;0;0;0
+16.1;26;40976;5.1152;1500;1500;0;0;0;0;0;0;0
+16.2;26;40976;5.1152;1500;1500;0;0;0;0;0;0;0
+16.3;26;40976;5.1152;1500;1500;0;0;0;0;0;0;0
+16.4;26;40976;5.1152;1500;1500;0;0;0;0;0;0;0
+16.5;26;40976;5.1152;1500;1500;0;0;0;0;0;0;0
+16.6;26;40976;5.1152;1500;1500;0;0;0;0;0;0;0
+16.7;26;40976;5.1152;1500;1500;0;0;0;0;0;0;0
+16.8;26;40976;5.1152;1500;1500;0;0;0;0;0;0;0
+16.9;26;40976;5.1152;1500;1500;0;0;0;0;0;0;0
+17;26;40976;5.1152;1500;1500;0;0;0;0;0;0;0
+17.1;26;40976;5.1152;1500;1500;0;0;0;0;0;0;0
+17.2;26;40976;5.1152;1500;1500;0;0;0;0;0;0;0
+17.3;26;40976;5.1152;1500;1500;0;0;0;0;0;0;0
+17.4;26;40976;5.1152;1500;1500;0;0;0;0;0;0;0
+17.5;26;40976;5.1152;1500;1500;0;0;0;0;0;0;0
+17.6;26;40976;5.1152;1500;1500;0;0;0;0;0;0;0
+17.7;26;40976;5.1152;1500;1500;0;0;0;0;0;0;0
+17.8;26;40976;5.1152;1500;1500;0;0;0;0;0;0;0
+17.9;26;40976;5.1152;1500;1500;0;0;0;0;0;0;0
+18;26;40976;5.1152;1500;1500;0;0;0;0;0;0;0
+18.1;26;40976;5.1152;1496;1500;0;0;0;0;0;0;0
+18.2;26;40976;5.1152;1492;1500;0;0;0;0;0;0;0
+18.3;26;40976;5.1152;1487;1500;0;0;0;0;0;0;0
+18.4;26;40976;5.1152;1483;1500;0;0;0;0;0;0;0
+18.5;26;40976;5.1152;1479;1500;0;0;0;0;0;0;0
+18.6;26;40976;5.1152;1188;1500;0;0;0;0;0;0;0
+18.7;26;40976;5.1152;954;1500;0;0;0;0;0;0;0
+18.8;26;40976;5.1152;766;1500;0;0;0;0;0;0;0
+18.9;26;40976;5.1152;615;1500;0;0;0;0;0;0;0
+19;26;40976;5.1152;494;1500;0;0;0;0;0;0;0
+19.1;26;40976;5.1152;478;1500;0;0;0;0;0;0;0
+19.2;26;40976;5.1152;462;1500;0;0;0;0;0;0;0
+19.3;26;40976;5.1152;447;1500;0;0;0;0;0;0;0
+19.4;26;40976;5.1152;433;1500;0;0;0;0;0;0;0
+19.5;26;40976;5.1152;419;1500;0;0;0;0;0;0;0
+19.6;26;40976;5.1152;491;1500;0;0;0;0;0;0;0
+19.7;26;40976;5.1152;577;1500;0;0;0;0;0;0;0
+19.8;26;40976;5.1152;677;1500;0;0;0;0;0;0;0
+19.9;26;40976;5.1152;795;1500;0;0;0;0;0;0;0
+20;26;40976;5.1152;934;1500;0;0;0;0;0;0;0
+20.1;26;40976;5.1152;799;1500;0;0;0;0;0;0;0
+20.2;26;40976;5.1152;684;1500;0;0;0;0;0;0;0
+20.3;26;40976;5.1152;586;1500;0;0;0;0;0;0;0
+20.4;26;40976;5.1152;502;1500;0;0;0;0;0;0;0
+20.5;26;40976;5.1152;429;1500;0;0;0;0;0;0;0
+20.6;26;40976;5.1152;315;1500;0;0;0;0;0;0;0
+20.7;26;40976;5.1152;231;1500;0;0;0;0;0;0;0
+20.8;26;40976;5.1152;169;1500;0;0;0;0;0;0;0
+20.9;26;40976;5.1152;124;1500;0;0;0;0;0;0;0
+21;26;40976;5.1152;91;1500;0;0;0;0;0;0;0
+21.1;26;40976;5.1152;87;1500;0;0;0;0;0;0;0
+21.2;26;40976;5.1152;84;1500;0;0;0;0;0;0;0
+21.3;26;40976;5.1152;81;1500;0;0;0;0;0;0;0
+21.4;26;40976;5.1152;78;1500;0;0;0;0;0;0;0
+21.5;26;40976;5.1152;75;1500;0;0;0;0;0;0;0
+21.6;26;40976;5.1152;75;1500;0;0;0;0;0;0;0
+21.7;26;40976;5.1152;75;1500;0;0;0;0;0;0;0
+21.8;26;40976;5.1152;75;1500;0;0;0;0;0;0;0
+21.9;26;40976;5.1152;75;1500;0;0;0;0;0;0;0
+22;26;40976;5.1152;75;1500;0;0;0;0;0;0;0
+22.1;26;40976;5.1152;73;1500;0;0;0;0;0;0;0
+22.2;26;40976;5.1152;72;1500;0;0;0;0;0;0;0
+22.3;26;40976;5.1152;70;1500;0;0;0;0;0;0;0
+22.4;26;40976;5.1152;68;1500;0;0;0;0;0;0;0
+22.5;26;40976;5.1152;67;1500;0;0;0;0;0;0;0
+22.6;26;40976;5.1152;53;1500;0;0;0;0;0;0;0
+22.7;26;40976;5.1152;42;1500;0;0;0;0;0;0;0
+22.8;26;40976;5.1152;33;1500;0;0;0;0;0;0;0
+22.9;26;40976;5.1152;26;1500;0;0;0;0;0;0;0
+23;26;40976;5.1152;21;1500;0;0;0;0;0;0;0
+23.1;26;40976;5.1152;11;1500;0;0;0;0;0;0;0
+23.2;26;40976;5.1152;6;1500;0;0;0;0;0;0;0
+23.3;26;40976;5.1152;3;1500;0;0;0;0;0;0;0
+23.4;26;40976;5.1152;2;1500;0;0;0;0;0;0;0
+23.5;26;40976;5.1152;1;1500;0;0;0;0;0;0;0
+23.6;26;40976;5.1152;1;1500;0;0;0;0;0;0;0
+23.7;26;40976;5.1152;0;1500;0;0;0;0;0;0;0
+23.8;26;40976;5.1152;0;1500;0;0;0;0;0;0;0
+23.9;26;40976;5.1152;0;1500;0;0;0;0;0;0;0
+24;26;40976;5.1152;0;1500;0;0;0;0;0;0;0
diff --git a/openair1/SIMULATION/NR_PHY/BLER_SIMULATIONS/AWGN/AWGN_results/mcs27_awgn_5G.csv b/openair1/SIMULATION/NR_PHY/BLER_SIMULATIONS/AWGN/AWGN_results/mcs27_awgn_5G.csv
new file mode 100644
index 0000000000000000000000000000000000000000..5f25579439d10df6955bf607def8d73084880045
--- /dev/null
+++ b/openair1/SIMULATION/NR_PHY/BLER_SIMULATIONS/AWGN/AWGN_results/mcs27_awgn_5G.csv
@@ -0,0 +1,92 @@
+SNR;MCS;TBS;rate;err0;trials0;err1;trials1;err2;trials2;err3;trials3;dci_err
+18;27;42016;5.332;1500;1500;0;0;0;0;0;0;0
+18.1;27;42016;5.332;1500;1500;0;0;0;0;0;0;0
+18.2;27;42016;5.332;1500;1500;0;0;0;0;0;0;0
+18.3;27;42016;5.332;1500;1500;0;0;0;0;0;0;0
+18.4;27;42016;5.332;1500;1500;0;0;0;0;0;0;0
+18.5;27;42016;5.332;1500;1500;0;0;0;0;0;0;0
+18.6;27;42016;5.332;1465;1500;0;0;0;0;0;0;0
+18.7;27;42016;5.332;1430;1500;0;0;0;0;0;0;0
+18.8;27;42016;5.332;1397;1500;0;0;0;0;0;0;0
+18.9;27;42016;5.332;1364;1500;0;0;0;0;0;0;0
+19;27;42016;5.332;1332;1500;0;0;0;0;0;0;0
+19.1;27;42016;5.332;1092;1500;0;0;0;0;0;0;0
+19.2;27;42016;5.332;896;1500;0;0;0;0;0;0;0
+19.3;27;42016;5.332;735;1500;0;0;0;0;0;0;0
+19.4;27;42016;5.332;603;1500;0;0;0;0;0;0;0
+19.5;27;42016;5.332;494;1500;0;0;0;0;0;0;0
+19.6;27;42016;5.332;572;1500;0;0;0;0;0;0;0
+19.7;27;42016;5.332;662;1500;0;0;0;0;0;0;0
+19.8;27;42016;5.332;766;1500;0;0;0;0;0;0;0
+19.9;27;42016;5.332;886;1500;0;0;0;0;0;0;0
+20;27;42016;5.332;1025;1500;0;0;0;0;0;0;0
+20.1;27;42016;5.332;1041;1500;0;0;0;0;0;0;0
+20.2;27;42016;5.332;1058;1500;0;0;0;0;0;0;0
+20.3;27;42016;5.332;1074;1500;0;0;0;0;0;0;0
+20.4;27;42016;5.332;1091;1500;0;0;0;0;0;0;0
+20.5;27;42016;5.332;1109;1500;0;0;0;0;0;0;0
+20.6;27;42016;5.332;811;1500;0;0;0;0;0;0;0
+20.7;27;42016;5.332;594;1500;0;0;0;0;0;0;0
+20.8;27;42016;5.332;434;1500;0;0;0;0;0;0;0
+20.9;27;42016;5.332;318;1500;0;0;0;0;0;0;0
+21;27;42016;5.332;233;1500;0;0;0;0;0;0;0
+21.1;27;42016;5.332;187;1500;0;0;0;0;0;0;0
+21.2;27;42016;5.332;150;1500;0;0;0;0;0;0;0
+21.3;27;42016;5.332;121;1500;0;0;0;0;0;0;0
+21.4;27;42016;5.332;97;1500;0;0;0;0;0;0;0
+21.5;27;42016;5.332;78;1500;0;0;0;0;0;0;0
+21.6;27;42016;5.332;78;1500;0;0;0;0;0;0;0
+21.7;27;42016;5.332;77;1500;0;0;0;0;0;0;0
+21.8;27;42016;5.332;76;1500;0;0;0;0;0;0;0
+21.9;27;42016;5.332;76;1500;0;0;0;0;0;0;0
+22;27;42016;5.332;75;1500;0;0;0;0;0;0;0
+22.1;27;42016;5.332;75;1500;0;0;0;0;0;0;0
+22.2;27;42016;5.332;75;1500;0;0;0;0;0;0;0
+22.3;27;42016;5.332;75;1500;0;0;0;0;0;0;0
+22.4;27;42016;5.332;75;1500;0;0;0;0;0;0;0
+22.5;27;42016;5.332;75;1500;0;0;0;0;0;0;0
+22.6;27;42016;5.332;75;1500;0;0;0;0;0;0;0
+22.7;27;42016;5.332;75;1500;0;0;0;0;0;0;0
+22.8;27;42016;5.332;75;1500;0;0;0;0;0;0;0
+22.9;27;42016;5.332;75;1500;0;0;0;0;0;0;0
+23;27;42016;5.332;75;1500;0;0;0;0;0;0;0
+23.1;27;42016;5.332;75;1500;0;0;0;0;0;0;0
+23.2;27;42016;5.332;74;1500;0;0;0;0;0;0;0
+23.3;27;42016;5.332;74;1500;0;0;0;0;0;0;0
+23.4;27;42016;5.332;74;1500;0;0;0;0;0;0;0
+23.5;27;42016;5.332;74;1500;0;0;0;0;0;0;0
+23.6;27;42016;5.332;68;1500;0;0;0;0;0;0;0
+23.7;27;42016;5.332;63;1500;0;0;0;0;0;0;0
+23.8;27;42016;5.332;59;1500;0;0;0;0;0;0;0
+23.9;27;42016;5.332;55;1500;0;0;0;0;0;0;0
+24;27;42016;5.332;51;1500;0;0;0;0;0;0;0
+24.1;27;42016;5.332;38;1500;0;0;0;0;0;0;0
+24.2;27;42016;5.332;29;1500;0;0;0;0;0;0;0
+24.3;27;42016;5.332;21;1500;0;0;0;0;0;0;0
+24.4;27;42016;5.332;16;1500;0;0;0;0;0;0;0
+24.5;27;42016;5.332;12;1500;0;0;0;0;0;0;0
+24.6;27;42016;5.332;7;1500;0;0;0;0;0;0;0
+24.7;27;42016;5.332;4;1500;0;0;0;0;0;0;0
+24.8;27;42016;5.332;3;1500;0;0;0;0;0;0;0
+24.9;27;42016;5.332;2;1500;0;0;0;0;0;0;0
+25;27;42016;5.332;1;1500;0;0;0;0;0;0;0
+25.1;27;42016;5.332;1;1500;0;0;0;0;0;0;0
+25.2;27;42016;5.332;0;1500;0;0;0;0;0;0;0
+25.3;27;42016;5.332;0;1500;0;0;0;0;0;0;0
+25.4;27;42016;5.332;0;1500;0;0;0;0;0;0;0
+25.5;27;42016;5.332;0;1500;0;0;0;0;0;0;0
+25.6;27;42016;5.332;0;1500;0;0;0;0;0;0;0
+25.7;27;42016;5.332;0;1500;0;0;0;0;0;0;0
+25.8;27;42016;5.332;0;1500;0;0;0;0;0;0;0
+25.9;27;42016;5.332;0;1500;0;0;0;0;0;0;0
+26;27;42016;5.332;0;1500;0;0;0;0;0;0;0
+26.1;27;42016;5.332;0;1500;0;0;0;0;0;0;0
+26.2;27;42016;5.332;0;1500;0;0;0;0;0;0;0
+26.3;27;42016;5.332;0;1500;0;0;0;0;0;0;0
+26.4;27;42016;5.332;0;1500;0;0;0;0;0;0;0
+26.5;27;42016;5.332;0;1500;0;0;0;0;0;0;0
+26.6;27;42016;5.332;0;1500;0;0;0;0;0;0;0
+26.7;27;42016;5.332;0;1500;0;0;0;0;0;0;0
+26.8;27;42016;5.332;0;1500;0;0;0;0;0;0;0
+26.9;27;42016;5.332;0;1500;0;0;0;0;0;0;0
+27;27;42016;5.332;0;1500;0;0;0;0;0;0;0
diff --git a/openair1/SIMULATION/NR_PHY/BLER_SIMULATIONS/AWGN/AWGN_results/mcs28_awgn_5G.csv b/openair1/SIMULATION/NR_PHY/BLER_SIMULATIONS/AWGN/AWGN_results/mcs28_awgn_5G.csv
new file mode 100644
index 0000000000000000000000000000000000000000..edf6ef2e2c54c3aef3cab0220bbc896c7fb6b035
--- /dev/null
+++ b/openair1/SIMULATION/NR_PHY/BLER_SIMULATIONS/AWGN/AWGN_results/mcs28_awgn_5G.csv
@@ -0,0 +1,92 @@
+SNR;MCS;TBS;rate;err0;trials0;err1;trials1;err2;trials2;err3;trials3;dci_err
+18;28;44040;5.547;1500;1500;0;0;0;0;0;0;0
+18.1;28;44040;5.547;1500;1500;0;0;0;0;0;0;0
+18.2;28;44040;5.547;1500;1500;0;0;0;0;0;0;0
+18.3;28;44040;5.547;1500;1500;0;0;0;0;0;0;0
+18.4;28;44040;5.547;1500;1500;0;0;0;0;0;0;0
+18.5;28;44040;5.547;1500;1500;0;0;0;0;0;0;0
+18.6;28;44040;5.547;1500;1500;0;0;0;0;0;0;0
+18.7;28;44040;5.547;1500;1500;0;0;0;0;0;0;0
+18.8;28;44040;5.547;1500;1500;0;0;0;0;0;0;0
+18.9;28;44040;5.547;1500;1500;0;0;0;0;0;0;0
+19;28;44040;5.547;1500;1500;0;0;0;0;0;0;0
+19.1;28;44040;5.547;1499;1500;0;0;0;0;0;0;0
+19.2;28;44040;5.547;1498;1500;0;0;0;0;0;0;0
+19.3;28;44040;5.547;1498;1500;0;0;0;0;0;0;0
+19.4;28;44040;5.547;1497;1500;0;0;0;0;0;0;0
+19.5;28;44040;5.547;1496;1500;0;0;0;0;0;0;0
+19.6;28;44040;5.547;1429;1500;0;0;0;0;0;0;0
+19.7;28;44040;5.547;1366;1500;0;0;0;0;0;0;0
+19.8;28;44040;5.547;1305;1500;0;0;0;0;0;0;0
+19.9;28;44040;5.547;1247;1500;0;0;0;0;0;0;0
+20;28;44040;5.547;1191;1500;0;0;0;0;0;0;0
+20.1;28;44040;5.547;1234;1500;0;0;0;0;0;0;0
+20.2;28;44040;5.547;1279;1500;0;0;0;0;0;0;0
+20.3;28;44040;5.547;1325;1500;0;0;0;0;0;0;0
+20.4;28;44040;5.547;1373;1500;0;0;0;0;0;0;0
+20.5;28;44040;5.547;1423;1500;0;0;0;0;0;0;0
+20.6;28;44040;5.547;1426;1500;0;0;0;0;0;0;0
+20.7;28;44040;5.547;1429;1500;0;0;0;0;0;0;0
+20.8;28;44040;5.547;1432;1500;0;0;0;0;0;0;0
+20.9;28;44040;5.547;1435;1500;0;0;0;0;0;0;0
+21;28;44040;5.547;1438;1500;0;0;0;0;0;0;0
+21.1;28;44040;5.547;1207;1500;0;0;0;0;0;0;0
+21.2;28;44040;5.547;1014;1500;0;0;0;0;0;0;0
+21.3;28;44040;5.547;851;1500;0;0;0;0;0;0;0
+21.4;28;44040;5.547;715;1500;0;0;0;0;0;0;0
+21.5;28;44040;5.547;600;1500;0;0;0;0;0;0;0
+21.6;28;44040;5.547;418;1500;0;0;0;0;0;0;0
+21.7;28;44040;5.547;290;1500;0;0;0;0;0;0;0
+21.8;28;44040;5.547;202;1500;0;0;0;0;0;0;0
+21.9;28;44040;5.547;140;1500;0;0;0;0;0;0;0
+22;28;44040;5.547;98;1500;0;0;0;0;0;0;0
+22.1;28;44040;5.547;93;1500;0;0;0;0;0;0;0
+22.2;28;44040;5.547;88;1500;0;0;0;0;0;0;0
+22.3;28;44040;5.547;83;1500;0;0;0;0;0;0;0
+22.4;28;44040;5.547;79;1500;0;0;0;0;0;0;0
+22.5;28;44040;5.547;75;1500;0;0;0;0;0;0;0
+22.6;28;44040;5.547;0;1500;0;0;0;0;0;0;0
+22.7;28;44040;5.547;0;1500;0;0;0;0;0;0;0
+22.8;28;44040;5.547;0;1500;0;0;0;0;0;0;0
+22.9;28;44040;5.547;0;1500;0;0;0;0;0;0;0
+23;28;44040;5.547;0;1500;0;0;0;0;0;0;0
+23.1;28;44040;5.547;0;1500;0;0;0;0;0;0;0
+23.2;28;44040;5.547;0;1500;0;0;0;0;0;0;0
+23.3;28;44040;5.547;0;1500;0;0;0;0;0;0;0
+23.4;28;44040;5.547;0;1500;0;0;0;0;0;0;0
+23.5;28;44040;5.547;0;1500;0;0;0;0;0;0;0
+23.6;28;44040;5.547;0;1500;0;0;0;0;0;0;0
+23.7;28;44040;5.547;0;1500;0;0;0;0;0;0;0
+23.8;28;44040;5.547;0;1500;0;0;0;0;0;0;0
+23.9;28;44040;5.547;0;1500;0;0;0;0;0;0;0
+24;28;44040;5.547;0;1500;0;0;0;0;0;0;0
+24.1;28;44040;5.547;0;1500;0;0;0;0;0;0;0
+24.2;28;44040;5.547;0;1500;0;0;0;0;0;0;0
+24.3;28;44040;5.547;0;1500;0;0;0;0;0;0;0
+24.4;28;44040;5.547;0;1500;0;0;0;0;0;0;0
+24.5;28;44040;5.547;0;1500;0;0;0;0;0;0;0
+24.6;28;44040;5.547;0;1500;0;0;0;0;0;0;0
+24.7;28;44040;5.547;0;1500;0;0;0;0;0;0;0
+24.8;28;44040;5.547;0;1500;0;0;0;0;0;0;0
+24.9;28;44040;5.547;0;1500;0;0;0;0;0;0;0
+25;28;44040;5.547;0;1500;0;0;0;0;0;0;0
+25.1;28;44040;5.547;0;1500;0;0;0;0;0;0;0
+25.2;28;44040;5.547;0;1500;0;0;0;0;0;0;0
+25.3;28;44040;5.547;0;1500;0;0;0;0;0;0;0
+25.4;28;44040;5.547;0;1500;0;0;0;0;0;0;0
+25.5;28;44040;5.547;0;1500;0;0;0;0;0;0;0
+25.6;28;44040;5.547;0;1500;0;0;0;0;0;0;0
+25.7;28;44040;5.547;0;1500;0;0;0;0;0;0;0
+25.8;28;44040;5.547;0;1500;0;0;0;0;0;0;0
+25.9;28;44040;5.547;0;1500;0;0;0;0;0;0;0
+26;28;44040;5.547;0;1500;0;0;0;0;0;0;0
+26.1;28;44040;5.547;0;1500;0;0;0;0;0;0;0
+26.2;28;44040;5.547;0;1500;0;0;0;0;0;0;0
+26.3;28;44040;5.547;0;1500;0;0;0;0;0;0;0
+26.4;28;44040;5.547;0;1500;0;0;0;0;0;0;0
+26.5;28;44040;5.547;0;1500;0;0;0;0;0;0;0
+26.6;28;44040;5.547;0;1500;0;0;0;0;0;0;0
+26.7;28;44040;5.547;0;1500;0;0;0;0;0;0;0
+26.8;28;44040;5.547;0;1500;0;0;0;0;0;0;0
+26.9;28;44040;5.547;0;1500;0;0;0;0;0;0;0
+27;28;44040;5.547;0;1500;0;0;0;0;0;0;0
diff --git a/openair1/SIMULATION/NR_PHY/BLER_SIMULATIONS/AWGN/AWGN_results/mcs2_awgn_5G.csv b/openair1/SIMULATION/NR_PHY/BLER_SIMULATIONS/AWGN/AWGN_results/mcs2_awgn_5G.csv
new file mode 100644
index 0000000000000000000000000000000000000000..2fbb6a20b973e1fcb5e934d999e4586b80d09040
--- /dev/null
+++ b/openair1/SIMULATION/NR_PHY/BLER_SIMULATIONS/AWGN/AWGN_results/mcs2_awgn_5G.csv
@@ -0,0 +1,62 @@
+SNR;MCS;TBS;rate;err0;trials0;err1;trials1;err2;trials2;err3;trials3;dci_err
+-4;2;2976;0.377;1500;1500;0;0;0;0;0;0;0
+-3.9;2;2976;0.377;1500;1500;0;0;0;0;0;0;0
+-3.8;2;2976;0.377;1500;1500;0;0;0;0;0;0;0
+-3.7;2;2976;0.377;1500;1500;0;0;0;0;0;0;0
+-3.6;2;2976;0.377;1500;1500;0;0;0;0;0;0;0
+-3.5;2;2976;0.377;1500;1500;0;0;0;0;0;0;0
+-3.4;2;2976;0.377;1500;1500;0;0;0;0;0;0;0
+-3.3;2;2976;0.377;1500;1500;0;0;0;0;0;0;0
+-3.2;2;2976;0.377;1500;1500;0;0;0;0;0;0;0
+-3.1;2;2976;0.377;1500;1500;0;0;0;0;0;0;0
+-3;2;2976;0.377;1500;1500;0;0;0;0;0;0;0
+-2.9;2;2976;0.377;1500;1500;0;0;0;0;0;0;0
+-2.8;2;2976;0.377;1500;1500;0;0;0;0;0;0;0
+-2.7;2;2976;0.377;1500;1500;0;0;0;0;0;0;0
+-2.6;2;2976;0.377;1500;1500;0;0;0;0;0;0;0
+-2.5;2;2976;0.377;1500;1500;0;0;0;0;0;0;0
+-2.4;2;2976;0.377;1500;1500;0;0;0;0;0;0;0
+-2.3;2;2976;0.377;1500;1500;0;0;0;0;0;0;0
+-2.2;2;2976;0.377;1500;1500;0;0;0;0;0;0;0
+-2.1;2;2976;0.377;1500;1500;0;0;0;0;0;0;0
+-2;2;2976;0.377;1500;1500;0;0;0;0;0;0;0
+-1.9;2;2976;0.377;1500;1500;0;0;0;0;0;0;0
+-1.8;2;2976;0.377;1500;1500;0;0;0;0;0;0;0
+-1.7;2;2976;0.377;1500;1500;0;0;0;0;0;0;0
+-1.6;2;2976;0.377;1500;1500;0;0;0;0;0;0;0
+-1.5;2;2976;0.377;1500;1500;0;0;0;0;0;0;0
+-1.4;2;2976;0.377;1486;1500;0;0;0;0;0;0;0
+-1.3;2;2976;0.377;1473;1500;0;0;0;0;0;0;0
+-1.2;2;2976;0.377;1459;1500;0;0;0;0;0;0;0
+-1.1;2;2976;0.377;1446;1500;0;0;0;0;0;0;0
+-1;2;2976;0.377;1432;1500;0;0;0;0;0;0;0
+-0.9;2;2976;0.377;1149;1500;0;0;0;0;0;0;0
+-0.8;2;2976;0.377;921;1500;0;0;0;0;0;0;0
+-0.7;2;2976;0.377;738;1500;0;0;0;0;0;0;0
+-0.6;2;2976;0.377;592;1500;0;0;0;0;0;0;0
+-0.5;2;2976;0.377;475;1500;0;0;0;0;0;0;0
+-0.4;2;2976;0.377;292;1500;0;0;0;0;0;0;0
+-0.3;2;2976;0.377;179;1500;0;0;0;0;0;0;0
+-0.2;2;2976;0.377;110;1500;0;0;0;0;0;0;0
+-0.1;2;2976;0.377;68;1500;0;0;0;0;0;0;0
+0;2;2976;0.377;42;1500;0;0;0;0;0;0;0
+0.1;2;2976;0.377;22;1500;0;0;0;0;0;0;0
+0.2;2;2976;0.377;11;1500;0;0;0;0;0;0;0
+0.3;2;2976;0.377;6;1500;0;0;0;0;0;0;0
+0.4;2;2976;0.377;3;1500;0;0;0;0;0;0;0
+0.5;2;2976;0.377;2;1500;0;0;0;0;0;0;0
+0.6;2;2976;0.377;0;1500;0;0;0;0;0;0;0
+0.7;2;2976;0.377;0;1500;0;0;0;0;0;0;0
+0.8;2;2976;0.377;0;1500;0;0;0;0;0;0;0
+0.9;2;2976;0.377;0;1500;0;0;0;0;0;0;0
+1;2;2976;0.377;0;1500;0;0;0;0;0;0;0
+1.1;2;2976;0.377;0;1500;0;0;0;0;0;0;0
+1.2;2;2976;0.377;0;1500;0;0;0;0;0;0;0
+1.3;2;2976;0.377;0;1500;0;0;0;0;0;0;0
+1.4;2;2976;0.377;0;1500;0;0;0;0;0;0;0
+1.5;2;2976;0.377;0;1500;0;0;0;0;0;0;0
+1.6;2;2976;0.377;0;1500;0;0;0;0;0;0;0
+1.7;2;2976;0.377;0;1500;0;0;0;0;0;0;0
+1.8;2;2976;0.377;0;1500;0;0;0;0;0;0;0
+1.9;2;2976;0.377;0;1500;0;0;0;0;0;0;0
+2;2;2976;0.377;0;1500;0;0;0;0;0;0;0
diff --git a/openair1/SIMULATION/NR_PHY/BLER_SIMULATIONS/AWGN/AWGN_results/mcs3_awgn_5G.csv b/openair1/SIMULATION/NR_PHY/BLER_SIMULATIONS/AWGN/AWGN_results/mcs3_awgn_5G.csv
new file mode 100644
index 0000000000000000000000000000000000000000..531c1548b093bdb58554e750106fd4e424ce77c0
--- /dev/null
+++ b/openair1/SIMULATION/NR_PHY/BLER_SIMULATIONS/AWGN/AWGN_results/mcs3_awgn_5G.csv
@@ -0,0 +1,62 @@
+SNR;MCS;TBS;rate;err0;trials0;err1;trials1;err2;trials2;err3;trials3;dci_err
+-4;3;3912;0.4902;1500;1500;0;0;0;0;0;0;0
+-3.9;3;3912;0.4902;1500;1500;0;0;0;0;0;0;0
+-3.8;3;3912;0.4902;1500;1500;0;0;0;0;0;0;0
+-3.7;3;3912;0.4902;1500;1500;0;0;0;0;0;0;0
+-3.6;3;3912;0.4902;1500;1500;0;0;0;0;0;0;0
+-3.5;3;3912;0.4902;1500;1500;0;0;0;0;0;0;0
+-3.4;3;3912;0.4902;1500;1500;0;0;0;0;0;0;0
+-3.3;3;3912;0.4902;1500;1500;0;0;0;0;0;0;0
+-3.2;3;3912;0.4902;1500;1500;0;0;0;0;0;0;0
+-3.1;3;3912;0.4902;1500;1500;0;0;0;0;0;0;0
+-3;3;3912;0.4902;1500;1500;0;0;0;0;0;0;0
+-2.9;3;3912;0.4902;1500;1500;0;0;0;0;0;0;0
+-2.8;3;3912;0.4902;1500;1500;0;0;0;0;0;0;0
+-2.7;3;3912;0.4902;1500;1500;0;0;0;0;0;0;0
+-2.6;3;3912;0.4902;1500;1500;0;0;0;0;0;0;0
+-2.5;3;3912;0.4902;1500;1500;0;0;0;0;0;0;0
+-2.4;3;3912;0.4902;1500;1500;0;0;0;0;0;0;0
+-2.3;3;3912;0.4902;1500;1500;0;0;0;0;0;0;0
+-2.2;3;3912;0.4902;1500;1500;0;0;0;0;0;0;0
+-2.1;3;3912;0.4902;1500;1500;0;0;0;0;0;0;0
+-2;3;3912;0.4902;1500;1500;0;0;0;0;0;0;0
+-1.9;3;3912;0.4902;1500;1500;0;0;0;0;0;0;0
+-1.8;3;3912;0.4902;1500;1500;0;0;0;0;0;0;0
+-1.7;3;3912;0.4902;1500;1500;0;0;0;0;0;0;0
+-1.6;3;3912;0.4902;1500;1500;0;0;0;0;0;0;0
+-1.5;3;3912;0.4902;1500;1500;0;0;0;0;0;0;0
+-1.4;3;3912;0.4902;1500;1500;0;0;0;0;0;0;0
+-1.3;3;3912;0.4902;1500;1500;0;0;0;0;0;0;0
+-1.2;3;3912;0.4902;1500;1500;0;0;0;0;0;0;0
+-1.1;3;3912;0.4902;1500;1500;0;0;0;0;0;0;0
+-1;3;3912;0.4902;1500;1500;0;0;0;0;0;0;0
+-0.9;3;3912;0.4902;1499;1500;0;0;0;0;0;0;0
+-0.8;3;3912;0.4902;1498;1500;0;0;0;0;0;0;0
+-0.7;3;3912;0.4902;1496;1500;0;0;0;0;0;0;0
+-0.6;3;3912;0.4902;1495;1500;0;0;0;0;0;0;0
+-0.5;3;3912;0.4902;1494;1500;0;0;0;0;0;0;0
+-0.4;3;3912;0.4902;1322;1500;0;0;0;0;0;0;0
+-0.3;3;3912;0.4902;1169;1500;0;0;0;0;0;0;0
+-0.2;3;3912;0.4902;1034;1500;0;0;0;0;0;0;0
+-0.1;3;3912;0.4902;915;1500;0;0;0;0;0;0;0
+0;3;3912;0.4902;809;1500;0;0;0;0;0;0;0
+0.1;3;3912;0.4902;504;1500;0;0;0;0;0;0;0
+0.2;3;3912;0.4902;314;1500;0;0;0;0;0;0;0
+0.3;3;3912;0.4902;196;1500;0;0;0;0;0;0;0
+0.4;3;3912;0.4902;122;1500;0;0;0;0;0;0;0
+0.5;3;3912;0.4902;76;1500;0;0;0;0;0;0;0
+0.6;3;3912;0.4902;37;1500;0;0;0;0;0;0;0
+0.7;3;3912;0.4902;18;1500;0;0;0;0;0;0;0
+0.8;3;3912;0.4902;9;1500;0;0;0;0;0;0;0
+0.9;3;3912;0.4902;4;1500;0;0;0;0;0;0;0
+1;3;3912;0.4902;2;1500;0;0;0;0;0;0;0
+1.1;3;3912;0.4902;0;1500;0;0;0;0;0;0;0
+1.2;3;3912;0.4902;0;1500;0;0;0;0;0;0;0
+1.3;3;3912;0.4902;0;1500;0;0;0;0;0;0;0
+1.4;3;3912;0.4902;0;1500;0;0;0;0;0;0;0
+1.5;3;3912;0.4902;0;1500;0;0;0;0;0;0;0
+1.6;3;3912;0.4902;0;1500;0;0;0;0;0;0;0
+1.7;3;3912;0.4902;0;1500;0;0;0;0;0;0;0
+1.8;3;3912;0.4902;0;1500;0;0;0;0;0;0;0
+1.9;3;3912;0.4902;0;1500;0;0;0;0;0;0;0
+2;3;3912;0.4902;0;1500;0;0;0;0;0;0;0
diff --git a/openair1/SIMULATION/NR_PHY/BLER_SIMULATIONS/AWGN/AWGN_results/mcs4_awgn_5G.csv b/openair1/SIMULATION/NR_PHY/BLER_SIMULATIONS/AWGN/AWGN_results/mcs4_awgn_5G.csv
new file mode 100644
index 0000000000000000000000000000000000000000..033c81afafc73ffaeed895df9d7129fe83b2cc66
--- /dev/null
+++ b/openair1/SIMULATION/NR_PHY/BLER_SIMULATIONS/AWGN/AWGN_results/mcs4_awgn_5G.csv
@@ -0,0 +1,62 @@
+SNR;MCS;TBS;rate;err0;trials0;err1;trials1;err2;trials2;err3;trials3;dci_err
+-1;4;4736;0.6016;1500;1500;0;0;0;0;0;0;0
+-0.9;4;4736;0.6016;1499;1500;0;0;0;0;0;0;0
+-0.8;4;4736;0.6016;1498;1500;0;0;0;0;0;0;0
+-0.7;4;4736;0.6016;1496;1500;0;0;0;0;0;0;0
+-0.6;4;4736;0.6016;1495;1500;0;0;0;0;0;0;0
+-0.5;4;4736;0.6016;1494;1500;0;0;0;0;0;0;0
+-0.4;4;4736;0.6016;1322;1500;0;0;0;0;0;0;0
+-0.3;4;4736;0.6016;1169;1500;0;0;0;0;0;0;0
+-0.2;4;4736;0.6016;1034;1500;0;0;0;0;0;0;0
+-0.1;4;4736;0.6016;915;1500;0;0;0;0;0;0;0
+0;4;4736;0.6016;809;1500;0;0;0;0;0;0;0
+0.1;4;4736;0.6016;504;1500;0;0;0;0;0;0;0
+0.2;4;4736;0.6016;314;1500;0;0;0;0;0;0;0
+0.3;4;4736;0.6016;196;1500;0;0;0;0;0;0;0
+0.4;4;4736;0.6016;122;1500;0;0;0;0;0;0;0
+0.5;4;4736;0.6016;76;1500;0;0;0;0;0;0;0
+0.6;4;4736;0.6016;37;1500;0;0;0;0;0;0;0
+0.7;4;4736;0.6016;18;1500;0;0;0;0;0;0;0
+0.8;4;4736;0.6016;9;1500;0;0;0;0;0;0;0
+0.9;4;4736;0.6016;4;1500;0;0;0;0;0;0;0
+1;4;4736;0.6016;2;1500;0;0;0;0;0;0;0
+1.1;4;4736;0.6016;0;1500;0;0;0;0;0;0;0
+1.2;4;4736;0.6016;0;1500;0;0;0;0;0;0;0
+1.3;4;4736;0.6016;0;1500;0;0;0;0;0;0;0
+1.4;4;4736;0.6016;0;1500;0;0;0;0;0;0;0
+1.5;4;4736;0.6016;0;1500;0;0;0;0;0;0;0
+1.6;4;4736;0.6016;0;1500;0;0;0;0;0;0;0
+1.7;4;4736;0.6016;0;1500;0;0;0;0;0;0;0
+1.8;4;4736;0.6016;0;1500;0;0;0;0;0;0;0
+1.9;4;4736;0.6016;0;1500;0;0;0;0;0;0;0
+2;4;4736;0.6016;0;1500;0;0;0;0;0;0;0
+2.1;4;4736;0.6016;0;1500;0;0;0;0;0;0;0
+2.2;4;4736;0.6016;0;1500;0;0;0;0;0;0;0
+2.3;4;4736;0.6016;0;1500;0;0;0;0;0;0;0
+2.4;4;4736;0.6016;0;1500;0;0;0;0;0;0;0
+2.5;4;4736;0.6016;0;1500;0;0;0;0;0;0;0
+2.6;4;4736;0.6016;0;1500;0;0;0;0;0;0;0
+2.7;4;4736;0.6016;0;1500;0;0;0;0;0;0;0
+2.8;4;4736;0.6016;0;1500;0;0;0;0;0;0;0
+2.9;4;4736;0.6016;0;1500;0;0;0;0;0;0;0
+3;4;4736;0.6016;0;1500;0;0;0;0;0;0;0
+3.1;4;4736;0.6016;0;1500;0;0;0;0;0;0;0
+3.2;4;4736;0.6016;0;1500;0;0;0;0;0;0;0
+3.3;4;4736;0.6016;0;1500;0;0;0;0;0;0;0
+3.4;4;4736;0.6016;0;1500;0;0;0;0;0;0;0
+3.5;4;4736;0.6016;0;1500;0;0;0;0;0;0;0
+3.6;4;4736;0.6016;0;1500;0;0;0;0;0;0;0
+3.7;4;4736;0.6016;0;1500;0;0;0;0;0;0;0
+3.8;4;4736;0.6016;0;1500;0;0;0;0;0;0;0
+3.9;4;4736;0.6016;0;1500;0;0;0;0;0;0;0
+4;4;4736;0.6016;0;1500;0;0;0;0;0;0;0
+4.1;4;4736;0.6016;0;1500;0;0;0;0;0;0;0
+4.2;4;4736;0.6016;0;1500;0;0;0;0;0;0;0
+4.3;4;4736;0.6016;0;1500;0;0;0;0;0;0;0
+4.4;4;4736;0.6016;0;1500;0;0;0;0;0;0;0
+4.5;4;4736;0.6016;0;1500;0;0;0;0;0;0;0
+4.6;4;4736;0.6016;0;1500;0;0;0;0;0;0;0
+4.7;4;4736;0.6016;0;1500;0;0;0;0;0;0;0
+4.8;4;4736;0.6016;0;1500;0;0;0;0;0;0;0
+4.9;4;4736;0.6016;0;1500;0;0;0;0;0;0;0
+5;4;4736;0.6016;0;1500;0;0;0;0;0;0;0
diff --git a/openair1/SIMULATION/NR_PHY/BLER_SIMULATIONS/AWGN/AWGN_results/mcs5_awgn_5G.csv b/openair1/SIMULATION/NR_PHY/BLER_SIMULATIONS/AWGN/AWGN_results/mcs5_awgn_5G.csv
new file mode 100644
index 0000000000000000000000000000000000000000..f7419660164c4911dbe60b904fe321cdf1f85287
--- /dev/null
+++ b/openair1/SIMULATION/NR_PHY/BLER_SIMULATIONS/AWGN/AWGN_results/mcs5_awgn_5G.csv
@@ -0,0 +1,62 @@
+SNR;MCS;TBS;rate;err0;trials0;err1;trials1;err2;trials2;err3;trials3;dci_err
+-1;5;5888;0.7402;1500;1500;0;0;0;0;0;0;0
+-0.9;5;5888;0.7402;1500;1500;0;0;0;0;0;0;0
+-0.8;5;5888;0.7402;1500;1500;0;0;0;0;0;0;0
+-0.7;5;5888;0.7402;1500;1500;0;0;0;0;0;0;0
+-0.6;5;5888;0.7402;1500;1500;0;0;0;0;0;0;0
+-0.5;5;5888;0.7402;1500;1500;0;0;0;0;0;0;0
+-0.4;5;5888;0.7402;1500;1500;0;0;0;0;0;0;0
+-0.3;5;5888;0.7402;1500;1500;0;0;0;0;0;0;0
+-0.2;5;5888;0.7402;1500;1500;0;0;0;0;0;0;0
+-0.1;5;5888;0.7402;1500;1500;0;0;0;0;0;0;0
+0;5;5888;0.7402;1500;1500;0;0;0;0;0;0;0
+0.1;5;5888;0.7402;1499;1500;0;0;0;0;0;0;0
+0.2;5;5888;0.7402;1499;1500;0;0;0;0;0;0;0
+0.3;5;5888;0.7402;1498;1500;0;0;0;0;0;0;0
+0.4;5;5888;0.7402;1498;1500;0;0;0;0;0;0;0
+0.5;5;5888;0.7402;1497;1500;0;0;0;0;0;0;0
+0.6;5;5888;0.7402;1323;1500;0;0;0;0;0;0;0
+0.7;5;5888;0.7402;1170;1500;0;0;0;0;0;0;0
+0.8;5;5888;0.7402;1034;1500;0;0;0;0;0;0;0
+0.9;5;5888;0.7402;914;1500;0;0;0;0;0;0;0
+1;5;5888;0.7402;808;1500;0;0;0;0;0;0;0
+1.1;5;5888;0.7402;513;1500;0;0;0;0;0;0;0
+1.2;5;5888;0.7402;326;1500;0;0;0;0;0;0;0
+1.3;5;5888;0.7402;207;1500;0;0;0;0;0;0;0
+1.4;5;5888;0.7402;131;1500;0;0;0;0;0;0;0
+1.5;5;5888;0.7402;83;1500;0;0;0;0;0;0;0
+1.6;5;5888;0.7402;48;1500;0;0;0;0;0;0;0
+1.7;5;5888;0.7402;28;1500;0;0;0;0;0;0;0
+1.8;5;5888;0.7402;16;1500;0;0;0;0;0;0;0
+1.9;5;5888;0.7402;9;1500;0;0;0;0;0;0;0
+2;5;5888;0.7402;5;1500;0;0;0;0;0;0;0
+2.1;5;5888;0.7402;2;1500;0;0;0;0;0;0;0
+2.2;5;5888;0.7402;1;1500;0;0;0;0;0;0;0
+2.3;5;5888;0.7402;0;1500;0;0;0;0;0;0;0
+2.4;5;5888;0.7402;0;1500;0;0;0;0;0;0;0
+2.5;5;5888;0.7402;0;1500;0;0;0;0;0;0;0
+2.6;5;5888;0.7402;0;1500;0;0;0;0;0;0;0
+2.7;5;5888;0.7402;0;1500;0;0;0;0;0;0;0
+2.8;5;5888;0.7402;0;1500;0;0;0;0;0;0;0
+2.9;5;5888;0.7402;0;1500;0;0;0;0;0;0;0
+3;5;5888;0.7402;0;1500;0;0;0;0;0;0;0
+3.1;5;5888;0.7402;0;1500;0;0;0;0;0;0;0
+3.2;5;5888;0.7402;0;1500;0;0;0;0;0;0;0
+3.3;5;5888;0.7402;0;1500;0;0;0;0;0;0;0
+3.4;5;5888;0.7402;0;1500;0;0;0;0;0;0;0
+3.5;5;5888;0.7402;0;1500;0;0;0;0;0;0;0
+3.6;5;5888;0.7402;0;1500;0;0;0;0;0;0;0
+3.7;5;5888;0.7402;0;1500;0;0;0;0;0;0;0
+3.8;5;5888;0.7402;0;1500;0;0;0;0;0;0;0
+3.9;5;5888;0.7402;0;1500;0;0;0;0;0;0;0
+4;5;5888;0.7402;0;1500;0;0;0;0;0;0;0
+4.1;5;5888;0.7402;0;1500;0;0;0;0;0;0;0
+4.2;5;5888;0.7402;0;1500;0;0;0;0;0;0;0
+4.3;5;5888;0.7402;0;1500;0;0;0;0;0;0;0
+4.4;5;5888;0.7402;0;1500;0;0;0;0;0;0;0
+4.5;5;5888;0.7402;0;1500;0;0;0;0;0;0;0
+4.6;5;5888;0.7402;0;1500;0;0;0;0;0;0;0
+4.7;5;5888;0.7402;0;1500;0;0;0;0;0;0;0
+4.8;5;5888;0.7402;0;1500;0;0;0;0;0;0;0
+4.9;5;5888;0.7402;0;1500;0;0;0;0;0;0;0
+5;5;5888;0.7402;0;1500;0;0;0;0;0;0;0
diff --git a/openair1/SIMULATION/NR_PHY/BLER_SIMULATIONS/AWGN/AWGN_results/mcs6_awgn_5G.csv b/openair1/SIMULATION/NR_PHY/BLER_SIMULATIONS/AWGN/AWGN_results/mcs6_awgn_5G.csv
new file mode 100644
index 0000000000000000000000000000000000000000..350c53d695e25ff3c4387cd735d69c869c272911
--- /dev/null
+++ b/openair1/SIMULATION/NR_PHY/BLER_SIMULATIONS/AWGN/AWGN_results/mcs6_awgn_5G.csv
@@ -0,0 +1,62 @@
+SNR;MCS;TBS;rate;err0;trials0;err1;trials1;err2;trials2;err3;trials3;dci_err
+-1;6;6912;0.877;1500;1500;0;0;0;0;0;0;0
+-0.9;6;6912;0.877;1500;1500;0;0;0;0;0;0;0
+-0.8;6;6912;0.877;1500;1500;0;0;0;0;0;0;0
+-0.7;6;6912;0.877;1500;1500;0;0;0;0;0;0;0
+-0.6;6;6912;0.877;1500;1500;0;0;0;0;0;0;0
+-0.5;6;6912;0.877;1500;1500;0;0;0;0;0;0;0
+-0.4;6;6912;0.877;1500;1500;0;0;0;0;0;0;0
+-0.3;6;6912;0.877;1500;1500;0;0;0;0;0;0;0
+-0.2;6;6912;0.877;1500;1500;0;0;0;0;0;0;0
+-0.1;6;6912;0.877;1500;1500;0;0;0;0;0;0;0
+0;6;6912;0.877;1500;1500;0;0;0;0;0;0;0
+0.1;6;6912;0.877;1500;1500;0;0;0;0;0;0;0
+0.2;6;6912;0.877;1500;1500;0;0;0;0;0;0;0
+0.3;6;6912;0.877;1500;1500;0;0;0;0;0;0;0
+0.4;6;6912;0.877;1500;1500;0;0;0;0;0;0;0
+0.5;6;6912;0.877;1500;1500;0;0;0;0;0;0;0
+0.6;6;6912;0.877;1500;1500;0;0;0;0;0;0;0
+0.7;6;6912;0.877;1500;1500;0;0;0;0;0;0;0
+0.8;6;6912;0.877;1500;1500;0;0;0;0;0;0;0
+0.9;6;6912;0.877;1500;1500;0;0;0;0;0;0;0
+1;6;6912;0.877;1500;1500;0;0;0;0;0;0;0
+1.1;6;6912;0.877;1493;1500;0;0;0;0;0;0;0
+1.2;6;6912;0.877;1487;1500;0;0;0;0;0;0;0
+1.3;6;6912;0.877;1480;1500;0;0;0;0;0;0;0
+1.4;6;6912;0.877;1473;1500;0;0;0;0;0;0;0
+1.5;6;6912;0.877;1467;1500;0;0;0;0;0;0;0
+1.6;6;6912;0.877;1117;1500;0;0;0;0;0;0;0
+1.7;6;6912;0.877;850;1500;0;0;0;0;0;0;0
+1.8;6;6912;0.877;648;1500;0;0;0;0;0;0;0
+1.9;6;6912;0.877;493;1500;0;0;0;0;0;0;0
+2;6;6912;0.877;376;1500;0;0;0;0;0;0;0
+2.1;6;6912;0.877;254;1500;0;0;0;0;0;0;0
+2.2;6;6912;0.877;172;1500;0;0;0;0;0;0;0
+2.3;6;6912;0.877;116;1500;0;0;0;0;0;0;0
+2.4;6;6912;0.877;79;1500;0;0;0;0;0;0;0
+2.5;6;6912;0.877;53;1500;0;0;0;0;0;0;0
+2.6;6;6912;0.877;32;1500;0;0;0;0;0;0;0
+2.7;6;6912;0.877;19;1500;0;0;0;0;0;0;0
+2.8;6;6912;0.877;11;1500;0;0;0;0;0;0;0
+2.9;6;6912;0.877;7;1500;0;0;0;0;0;0;0
+3;6;6912;0.877;4;1500;0;0;0;0;0;0;0
+3.1;6;6912;0.877;0;1500;0;0;0;0;0;0;0
+3.2;6;6912;0.877;0;1500;0;0;0;0;0;0;0
+3.3;6;6912;0.877;0;1500;0;0;0;0;0;0;0
+3.4;6;6912;0.877;0;1500;0;0;0;0;0;0;0
+3.5;6;6912;0.877;0;1500;0;0;0;0;0;0;0
+3.6;6;6912;0.877;0;1500;0;0;0;0;0;0;0
+3.7;6;6912;0.877;0;1500;0;0;0;0;0;0;0
+3.8;6;6912;0.877;0;1500;0;0;0;0;0;0;0
+3.9;6;6912;0.877;0;1500;0;0;0;0;0;0;0
+4;6;6912;0.877;0;1500;0;0;0;0;0;0;0
+4.1;6;6912;0.877;0;1500;0;0;0;0;0;0;0
+4.2;6;6912;0.877;0;1500;0;0;0;0;0;0;0
+4.3;6;6912;0.877;0;1500;0;0;0;0;0;0;0
+4.4;6;6912;0.877;0;1500;0;0;0;0;0;0;0
+4.5;6;6912;0.877;0;1500;0;0;0;0;0;0;0
+4.6;6;6912;0.877;0;1500;0;0;0;0;0;0;0
+4.7;6;6912;0.877;0;1500;0;0;0;0;0;0;0
+4.8;6;6912;0.877;0;1500;0;0;0;0;0;0;0
+4.9;6;6912;0.877;0;1500;0;0;0;0;0;0;0
+5;6;6912;0.877;0;1500;0;0;0;0;0;0;0
diff --git a/openair1/SIMULATION/NR_PHY/BLER_SIMULATIONS/AWGN/AWGN_results/mcs7_awgn_5G.csv b/openair1/SIMULATION/NR_PHY/BLER_SIMULATIONS/AWGN/AWGN_results/mcs7_awgn_5G.csv
new file mode 100644
index 0000000000000000000000000000000000000000..9bd689cf0e4e87bc27d1fd69d8bd444bd1da8d7a
--- /dev/null
+++ b/openair1/SIMULATION/NR_PHY/BLER_SIMULATIONS/AWGN/AWGN_results/mcs7_awgn_5G.csv
@@ -0,0 +1,62 @@
+SNR;MCS;TBS;rate;err0;trials0;err1;trials1;err2;trials2;err3;trials3;dci_err
+-1;7;8912;1.0273;1500;1500;0;0;0;0;0;0;0
+-0.9;7;8912;1.0273;1500;1500;0;0;0;0;0;0;0
+-0.8;7;8912;1.0273;1500;1500;0;0;0;0;0;0;0
+-0.7;7;8912;1.0273;1500;1500;0;0;0;0;0;0;0
+-0.6;7;8912;1.0273;1500;1500;0;0;0;0;0;0;0
+-0.5;7;8912;1.0273;1500;1500;0;0;0;0;0;0;0
+-0.4;7;8912;1.0273;1500;1500;0;0;0;0;0;0;0
+-0.3;7;8912;1.0273;1500;1500;0;0;0;0;0;0;0
+-0.2;7;8912;1.0273;1500;1500;0;0;0;0;0;0;0
+-0.1;7;8912;1.0273;1500;1500;0;0;0;0;0;0;0
+0;7;8912;1.0273;1500;1500;0;0;0;0;0;0;0
+0.1;7;8912;1.0273;1500;1500;0;0;0;0;0;0;0
+0.2;7;8912;1.0273;1500;1500;0;0;0;0;0;0;0
+0.3;7;8912;1.0273;1500;1500;0;0;0;0;0;0;0
+0.4;7;8912;1.0273;1500;1500;0;0;0;0;0;0;0
+0.5;7;8912;1.0273;1500;1500;0;0;0;0;0;0;0
+0.6;7;8912;1.0273;1500;1500;0;0;0;0;0;0;0
+0.7;7;8912;1.0273;1500;1500;0;0;0;0;0;0;0
+0.8;7;8912;1.0273;1500;1500;0;0;0;0;0;0;0
+0.9;7;8912;1.0273;1500;1500;0;0;0;0;0;0;0
+1;7;8912;1.0273;1500;1500;0;0;0;0;0;0;0
+1.1;7;8912;1.0273;1500;1500;0;0;0;0;0;0;0
+1.2;7;8912;1.0273;1500;1500;0;0;0;0;0;0;0
+1.3;7;8912;1.0273;1500;1500;0;0;0;0;0;0;0
+1.4;7;8912;1.0273;1500;1500;0;0;0;0;0;0;0
+1.5;7;8912;1.0273;1500;1500;0;0;0;0;0;0;0
+1.6;7;8912;1.0273;1500;1500;0;0;0;0;0;0;0
+1.7;7;8912;1.0273;1500;1500;0;0;0;0;0;0;0
+1.8;7;8912;1.0273;1500;1500;0;0;0;0;0;0;0
+1.9;7;8912;1.0273;1500;1500;0;0;0;0;0;0;0
+2;7;8912;1.0273;1500;1500;0;0;0;0;0;0;0
+2.1;7;8912;1.0273;1492;1500;0;0;0;0;0;0;0
+2.2;7;8912;1.0273;1484;1500;0;0;0;0;0;0;0
+2.3;7;8912;1.0273;1477;1500;0;0;0;0;0;0;0
+2.4;7;8912;1.0273;1469;1500;0;0;0;0;0;0;0
+2.5;7;8912;1.0273;1462;1500;0;0;0;0;0;0;0
+2.6;7;8912;1.0273;1159;1500;0;0;0;0;0;0;0
+2.7;7;8912;1.0273;919;1500;0;0;0;0;0;0;0
+2.8;7;8912;1.0273;729;1500;0;0;0;0;0;0;0
+2.9;7;8912;1.0273;578;1500;0;0;0;0;0;0;0
+3;7;8912;1.0273;458;1500;0;0;0;0;0;0;0
+3.1;7;8912;1.0273;319;1500;0;0;0;0;0;0;0
+3.2;7;8912;1.0273;222;1500;0;0;0;0;0;0;0
+3.3;7;8912;1.0273;155;1500;0;0;0;0;0;0;0
+3.4;7;8912;1.0273;108;1500;0;0;0;0;0;0;0
+3.5;7;8912;1.0273;75;1500;0;0;0;0;0;0;0
+3.6;7;8912;1.0273;48;1500;0;0;0;0;0;0;0
+3.7;7;8912;1.0273;30;1500;0;0;0;0;0;0;0
+3.8;7;8912;1.0273;19;1500;0;0;0;0;0;0;0
+3.9;7;8912;1.0273;12;1500;0;0;0;0;0;0;0
+4;7;8912;1.0273;8;1500;0;0;0;0;0;0;0
+4.1;7;8912;1.0273;4;1500;0;0;0;0;0;0;0
+4.2;7;8912;1.0273;2;1500;0;0;0;0;0;0;0
+4.3;7;8912;1.0273;1;1500;0;0;0;0;0;0;0
+4.4;7;8912;1.0273;0;1500;0;0;0;0;0;0;0
+4.5;7;8912;1.0273;0;1500;0;0;0;0;0;0;0
+4.6;7;8912;1.0273;0;1500;0;0;0;0;0;0;0
+4.7;7;8912;1.0273;0;1500;0;0;0;0;0;0;0
+4.8;7;8912;1.0273;0;1500;0;0;0;0;0;0;0
+4.9;7;8912;1.0273;0;1500;0;0;0;0;0;0;0
+5;7;8912;1.0273;0;1500;0;0;0;0;0;0;0
diff --git a/openair1/SIMULATION/NR_PHY/BLER_SIMULATIONS/AWGN/AWGN_results/mcs8_awgn_5G.csv b/openair1/SIMULATION/NR_PHY/BLER_SIMULATIONS/AWGN/AWGN_results/mcs8_awgn_5G.csv
new file mode 100644
index 0000000000000000000000000000000000000000..470cce69ae6471e94a8b0371471c5a82abf61da2
--- /dev/null
+++ b/openair1/SIMULATION/NR_PHY/BLER_SIMULATIONS/AWGN/AWGN_results/mcs8_awgn_5G.csv
@@ -0,0 +1,62 @@
+SNR;MCS;TBS;rate;err0;trials0;err1;trials1;err2;trials2;err3;trials3;dci_err
+-1;8;9224;1.1758;1500;1500;0;0;0;0;0;0;0
+-0.9;8;9224;1.1758;1500;1500;0;0;0;0;0;0;0
+-0.8;8;9224;1.1758;1500;1500;0;0;0;0;0;0;0
+-0.7;8;9224;1.1758;1500;1500;0;0;0;0;0;0;0
+-0.6;8;9224;1.1758;1500;1500;0;0;0;0;0;0;0
+-0.5;8;9224;1.1758;1500;1500;0;0;0;0;0;0;0
+-0.4;8;9224;1.1758;1500;1500;0;0;0;0;0;0;0
+-0.3;8;9224;1.1758;1500;1500;0;0;0;0;0;0;0
+-0.2;8;9224;1.1758;1500;1500;0;0;0;0;0;0;0
+-0.1;8;9224;1.1758;1500;1500;0;0;0;0;0;0;0
+0;8;9224;1.1758;1500;1500;0;0;0;0;0;0;0
+0.1;8;9224;1.1758;1500;1500;0;0;0;0;0;0;0
+0.2;8;9224;1.1758;1500;1500;0;0;0;0;0;0;0
+0.3;8;9224;1.1758;1500;1500;0;0;0;0;0;0;0
+0.4;8;9224;1.1758;1500;1500;0;0;0;0;0;0;0
+0.5;8;9224;1.1758;1500;1500;0;0;0;0;0;0;0
+0.6;8;9224;1.1758;1500;1500;0;0;0;0;0;0;0
+0.7;8;9224;1.1758;1500;1500;0;0;0;0;0;0;0
+0.8;8;9224;1.1758;1500;1500;0;0;0;0;0;0;0
+0.9;8;9224;1.1758;1500;1500;0;0;0;0;0;0;0
+1;8;9224;1.1758;1500;1500;0;0;0;0;0;0;0
+1.1;8;9224;1.1758;1500;1500;0;0;0;0;0;0;0
+1.2;8;9224;1.1758;1500;1500;0;0;0;0;0;0;0
+1.3;8;9224;1.1758;1500;1500;0;0;0;0;0;0;0
+1.4;8;9224;1.1758;1500;1500;0;0;0;0;0;0;0
+1.5;8;9224;1.1758;1500;1500;0;0;0;0;0;0;0
+1.6;8;9224;1.1758;1500;1500;0;0;0;0;0;0;0
+1.7;8;9224;1.1758;1500;1500;0;0;0;0;0;0;0
+1.8;8;9224;1.1758;1500;1500;0;0;0;0;0;0;0
+1.9;8;9224;1.1758;1500;1500;0;0;0;0;0;0;0
+2;8;9224;1.1758;1500;1500;0;0;0;0;0;0;0
+2.1;8;9224;1.1758;1500;1500;0;0;0;0;0;0;0
+2.2;8;9224;1.1758;1500;1500;0;0;0;0;0;0;0
+2.3;8;9224;1.1758;1500;1500;0;0;0;0;0;0;0
+2.4;8;9224;1.1758;1500;1500;0;0;0;0;0;0;0
+2.5;8;9224;1.1758;1500;1500;0;0;0;0;0;0;0
+2.6;8;9224;1.1758;1500;1500;0;0;0;0;0;0;0
+2.7;8;9224;1.1758;1500;1500;0;0;0;0;0;0;0
+2.8;8;9224;1.1758;1500;1500;0;0;0;0;0;0;0
+2.9;8;9224;1.1758;1500;1500;0;0;0;0;0;0;0
+3;8;9224;1.1758;1500;1500;0;0;0;0;0;0;0
+3.1;8;9224;1.1758;1464;1500;0;0;0;0;0;0;0
+3.2;8;9224;1.1758;1429;1500;0;0;0;0;0;0;0
+3.3;8;9224;1.1758;1394;1500;0;0;0;0;0;0;0
+3.4;8;9224;1.1758;1361;1500;0;0;0;0;0;0;0
+3.5;8;9224;1.1758;1328;1500;0;0;0;0;0;0;0
+3.6;8;9224;1.1758;973;1500;0;0;0;0;0;0;0
+3.7;8;9224;1.1758;713;1500;0;0;0;0;0;0;0
+3.8;8;9224;1.1758;522;1500;0;0;0;0;0;0;0
+3.9;8;9224;1.1758;382;1500;0;0;0;0;0;0;0
+4;8;9224;1.1758;280;1500;0;0;0;0;0;0;0
+4.1;8;9224;1.1758;190;1500;0;0;0;0;0;0;0
+4.2;8;9224;1.1758;129;1500;0;0;0;0;0;0;0
+4.3;8;9224;1.1758;87;1500;0;0;0;0;0;0;0
+4.4;8;9224;1.1758;59;1500;0;0;0;0;0;0;0
+4.5;8;9224;1.1758;40;1500;0;0;0;0;0;0;0
+4.6;8;9224;1.1758;20;1500;0;0;0;0;0;0;0
+4.7;8;9224;1.1758;10;1500;0;0;0;0;0;0;0
+4.8;8;9224;1.1758;5;1500;0;0;0;0;0;0;0
+4.9;8;9224;1.1758;2;1500;0;0;0;0;0;0;0
+5;8;9224;1.1758;1;1500;0;0;0;0;0;0;0
diff --git a/openair1/SIMULATION/NR_PHY/BLER_SIMULATIONS/AWGN/AWGN_results/mcs9_awgn_5G.csv b/openair1/SIMULATION/NR_PHY/BLER_SIMULATIONS/AWGN/AWGN_results/mcs9_awgn_5G.csv
new file mode 100644
index 0000000000000000000000000000000000000000..2ba438ea490254885ecb7ae3545af999545a8eaa
--- /dev/null
+++ b/openair1/SIMULATION/NR_PHY/BLER_SIMULATIONS/AWGN/AWGN_results/mcs9_awgn_5G.csv
@@ -0,0 +1,64 @@
+SNR;MCS;TBS;rate;err0;trials0;err1;trials1;err2;trials2;err3;trials3;dci_err
+-1;9;10504;1.3262;1500;1500;0;0;0;0;0;0;0
+-0.9;9;10504;1.3262;1500;1500;0;0;0;0;0;0;0
+-0.8;9;10504;1.3262;1500;1500;0;0;0;0;0;0;0
+-0.7;9;10504;1.3262;1500;1500;0;0;0;0;0;0;0
+-0.6;9;10504;1.3262;1500;1500;0;0;0;0;0;0;0
+-0.5;9;10504;1.3262;1500;1500;0;0;0;0;0;0;0
+-0.4;9;10504;1.3262;1500;1500;0;0;0;0;0;0;0
+-0.3;9;10504;1.3262;1500;1500;0;0;0;0;0;0;0
+-0.2;9;10504;1.3262;1500;1500;0;0;0;0;0;0;0
+-0.1;9;10504;1.3262;1500;1500;0;0;0;0;0;0;0
+0;9;10504;1.3262;1500;1500;0;0;0;0;0;0;0
+0.1;9;10504;1.3262;1500;1500;0;0;0;0;0;0;0
+0.2;9;10504;1.3262;1500;1500;0;0;0;0;0;0;0
+0.3;9;10504;1.3262;1500;1500;0;0;0;0;0;0;0
+0.4;9;10504;1.3262;1500;1500;0;0;0;0;0;0;0
+0.5;9;10504;1.3262;1500;1500;0;0;0;0;0;0;0
+0.6;9;10504;1.3262;1500;1500;0;0;0;0;0;0;0
+0.7;9;10504;1.3262;1500;1500;0;0;0;0;0;0;0
+0.8;9;10504;1.3262;1500;1500;0;0;0;0;0;0;0
+0.9;9;10504;1.3262;1500;1500;0;0;0;0;0;0;0
+1;9;10504;1.3262;1500;1500;0;0;0;0;0;0;0
+1.1;9;10504;1.3262;1500;1500;0;0;0;0;0;0;0
+1.2;9;10504;1.3262;1500;1500;0;0;0;0;0;0;0
+1.3;9;10504;1.3262;1500;1500;0;0;0;0;0;0;0
+1.4;9;10504;1.3262;1500;1500;0;0;0;0;0;0;0
+1.5;9;10504;1.3262;1500;1500;0;0;0;0;0;0;0
+1.6;9;10504;1.3262;1500;1500;0;0;0;0;0;0;0
+1.7;9;10504;1.3262;1500;1500;0;0;0;0;0;0;0
+1.8;9;10504;1.3262;1500;1500;0;0;0;0;0;0;0
+1.9;9;10504;1.3262;1500;1500;0;0;0;0;0;0;0
+2;9;10504;1.3262;1500;1500;0;0;0;0;0;0;0
+2.1;9;10504;1.3262;1500;1500;0;0;0;0;0;0;0
+2.2;9;10504;1.3262;1500;1500;0;0;0;0;0;0;0
+2.3;9;10504;1.3262;1500;1500;0;0;0;0;0;0;0
+2.4;9;10504;1.3262;1500;1500;0;0;0;0;0;0;0
+2.5;9;10504;1.3262;1500;1500;0;0;0;0;0;0;0
+2.6;9;10504;1.3262;1500;1500;0;0;0;0;0;0;0
+2.7;9;10504;1.3262;1500;1500;0;0;0;0;0;0;0
+2.8;9;10504;1.3262;1500;1500;0;0;0;0;0;0;0
+2.9;9;10504;1.3262;1500;1500;0;0;0;0;0;0;0
+3;9;10504;1.3262;1500;1500;0;0;0;0;0;0;0
+3.1;9;10504;1.3262;1500;1500;0;0;0;0;0;0;0
+3.2;9;10504;1.3262;1500;1500;0;0;0;0;0;0;0
+3.3;9;10504;1.3262;1500;1500;0;0;0;0;0;0;0
+3.4;9;10504;1.3262;1500;1500;0;0;0;0;0;0;0
+3.5;9;10504;1.3262;1500;1500;0;0;0;0;0;0;0
+3.6;9;10504;1.3262;1500;1500;0;0;0;0;0;0;0
+3.7;9;10504;1.3262;1499;1500;0;0;0;0;0;0;0
+3.8;9;10504;1.3262;1499;1500;0;0;0;0;0;0;0
+3.9;9;10504;1.3262;1499;1500;0;0;0;0;0;0;0
+4;9;10504;1.3262;1498;1500;0;0;0;0;0;0;0
+4.1;9;10504;1.3262;1339;1500;0;0;0;0;0;0;0
+4.2;9;10504;1.3262;1196;1500;0;0;0;0;0;0;0
+4.3;9;10504;1.3262;1068;1500;0;0;0;0;0;0;0
+4.4;9;10504;1.3262;955;1500;0;0;0;0;0;0;0
+4.5;9;10504;1.3262;853;1500;0;0;0;0;0;0;0
+4.6;9;10504;1.3262;552;1500;0;0;0;0;0;0;0
+4.7;9;10504;1.3262;357;1500;0;0;0;0;0;0;0
+4.8;9;10504;1.3262;231;1500;0;0;0;0;0;0;0
+4.9;9;10504;1.3262;149;1500;0;0;0;0;0;0;0
+5;9;10504;1.3262;96;1500;0;0;0;0;0;0;0
+5.1;9;10504;1.3262;0;1500;0;0;0;0;0;0;0
+5.2;9;10504;1.3262;0;1500;0;0;0;0;0;0;0
diff --git a/openair1/SIMULATION/NR_PHY/dlschsim.c b/openair1/SIMULATION/NR_PHY/dlschsim.c
index d6812dd541164c3fd056b75bb28561ffba9488d4..6f747b36a63e59715d927a9398fadae8fc2b15cc 100644
--- a/openair1/SIMULATION/NR_PHY/dlschsim.c
+++ b/openair1/SIMULATION/NR_PHY/dlschsim.c
@@ -478,14 +478,11 @@ int main(int argc, char **argv)
 	harq_process->n_dmrs_cdm_groups = 1;
 	printf("harq process ue mcs = %d Qm = %d, symb %d\n", harq_process->mcs, harq_process->Qm, nb_symb_sch);
 
-	unsigned char *test_input;
-	test_input = (unsigned char *) malloc16(sizeof(unsigned char) * TBS / 8);
+	unsigned char *test_input=dlsch->harq_process.pdu;
 	//unsigned char test_input[TBS / 8]  __attribute__ ((aligned(16)));
 	for (i = 0; i < TBS / 8; i++)
 		test_input[i] = (unsigned char) rand();
 
-	//estimated_output = harq_process->b;
-
 #ifdef DEBUG_NR_DLSCHSIM
 	for (i = 0; i < TBS / 8; i++) printf("test_input[i]=%hhu \n",test_input[i]);
 #endif
@@ -498,7 +495,7 @@ int main(int argc, char **argv)
 	    unsigned char output[rel15->rbSize * NR_SYMBOLS_PER_SLOT * NR_NB_SC_PER_RB * 8 * NR_MAX_NB_LAYERS] __attribute__((aligned(32)));
     bzero(output,rel15->rbSize * NR_SYMBOLS_PER_SLOT * NR_NB_SC_PER_RB * 8 * NR_MAX_NB_LAYERS);
 	if (input_fd == NULL) {
-	  nr_dlsch_encoding(gNB, test_input, frame, slot, dlsch, frame_parms,output,NULL,NULL,NULL,NULL,NULL,NULL,NULL);
+	  nr_dlsch_encoding(gNB, frame, slot, &dlsch->harq_process, frame_parms,output,NULL,NULL,NULL,NULL,NULL,NULL,NULL);
 	}
 
 	for (SNR = snr0; SNR < snr1; SNR += snr_step) {
@@ -618,8 +615,6 @@ int main(int argc, char **argv)
 	 }
 	 }*/
 
-  free(test_input);
-
   free_channel_desc_scm(gNB2UE);
 
   reset_DLSCH_struct(gNB, &msgDataTx);
diff --git a/openair1/SIMULATION/NR_PHY/dlsim.c b/openair1/SIMULATION/NR_PHY/dlsim.c
index d1015e93e06bf3e9e4da106469592e2ef50ed9a3..793d7cb5acc21090d73956573e0e67cc07acac9a 100644
--- a/openair1/SIMULATION/NR_PHY/dlsim.c
+++ b/openair1/SIMULATION/NR_PHY/dlsim.c
@@ -238,6 +238,8 @@ int DU_send_INITIAL_UL_RRC_MESSAGE_TRANSFER(module_id_t     module_idP,
   return 0;
 }
 
+nr_bler_struct nr_bler_data[NR_NUM_MCS];
+
 void processSlotTX(void *arg) {}
 
 //nFAPI P7 dummy functions to avoid linking errors 
@@ -958,10 +960,10 @@ int main(int argc, char **argv)
   nr_gold_pdcch(UE, frame_parms->Nid_cell);
 
   // compute the scrambling IDs for PDSCH DMRS
-  for (int i = 0; i < 2; i++)
-    UE->scramblingID[i] = frame_parms->Nid_cell;
-
-  nr_gold_pdsch(UE, UE->scramblingID);
+  for (int i = 0; i < 2; i++) {
+    UE->scramblingID_dlsch[i] = frame_parms->Nid_cell;
+    nr_gold_pdsch(UE, i, UE->scramblingID_dlsch[i]);
+  }
 
   nr_l2_init_ue(NULL);
   UE_mac = get_mac_inst(0);
@@ -1000,6 +1002,8 @@ int main(int argc, char **argv)
 
   nr_dcireq_t dcireq;
   nr_scheduled_response_t scheduled_response;
+  NR_UE_PDCCH_CONFIG phy_pdcch_config={0};
+
   memset((void*)&dcireq,0,sizeof(dcireq));
   memset((void*)&scheduled_response,0,sizeof(scheduled_response));
   dcireq.module_id = 0;
@@ -1014,6 +1018,7 @@ int main(int argc, char **argv)
   scheduled_response.frame = frame;
   scheduled_response.slot  = slot;
   scheduled_response.thread_id = 0;
+  scheduled_response.phy_data = &phy_pdcch_config;
 
   nr_ue_phy_config_request(&UE_mac->phy_config);
   //NR_COMMON_channels_t *cc = RC.nrmac[0]->common_channels;
@@ -1083,7 +1088,7 @@ int main(int argc, char **argv)
       
       UE_harq_process->ack = 0;
       round = 0;
-      UE_harq_process->round = round;
+      UE_harq_process->DLround = round;
       UE_harq_process->first_rx = 1;
         
       while ((round<num_rounds) && (UE_harq_process->ack==0)) {
@@ -1256,6 +1261,7 @@ int main(int argc, char **argv)
                                &UE_proc,
                                0,
                                dlsch_threads,
+                               &phy_pdcch_config,
                                NULL);
         
         //printf("dlsim round %d ends\n",round);
@@ -1404,8 +1410,6 @@ int main(int argc, char **argv)
       LOG_M("chestF0.m","chF0",&UE->pdsch_vars[0][0]->dl_ch_estimates_ext[0][0],g_rbSize*12*14,1,1);
       write_output("rxF_comp.m","rxFc",&UE->pdsch_vars[0][0]->rxdataF_comp0[0][0],N_RB_DL*12*14,1,1);
       LOG_M("rxF_llr.m","rxFllr",UE->pdsch_vars[UE_proc.thread_id][0]->llr[0],available_bits,1,0);
-      LOG_M("pdcch_rxFcomp.m","pdcch_rxFcomp",&UE->pdcch_vars[0][0]->rxdataF_comp[0][0],96*12,1,1);
-      LOG_M("pdcch_rxFllr.m","pdcch_rxFllr",UE->pdcch_vars[0][0]->llr,96*12,1,1);
       break;
     }
 
diff --git a/openair1/SIMULATION/NR_PHY/nr_dummy_functions.c b/openair1/SIMULATION/NR_PHY/nr_dummy_functions.c
index 351c2f33c47a74a94e8276201289767a47b67973..2d1fc597557518e993d84c2d83636c37457b01c1 100644
--- a/openair1/SIMULATION/NR_PHY/nr_dummy_functions.c
+++ b/openair1/SIMULATION/NR_PHY/nr_dummy_functions.c
@@ -28,7 +28,8 @@ void nr_fill_dl_indication(nr_downlink_indication_t *dl_ind,
                            fapi_nr_rx_indication_t *rx_ind,
                            UE_nr_rxtx_proc_t *proc,
                            PHY_VARS_NR_UE *ue,
-                           uint8_t gNB_id) {}
+                           uint8_t gNB_id,
+                           void *phy_data) {}
 void nr_fill_rx_indication(fapi_nr_rx_indication_t *rx_ind,
                            uint8_t pdu_type,
                            uint8_t gNB_id,
diff --git a/openair1/SIMULATION/NR_PHY/pbchsim.c b/openair1/SIMULATION/NR_PHY/pbchsim.c
index 8fc6410538a25f57c55fc6b70cb60dc1c065fd13..62f6b21528e81082024a49f68e718cad646c7057 100644
--- a/openair1/SIMULATION/NR_PHY/pbchsim.c
+++ b/openair1/SIMULATION/NR_PHY/pbchsim.c
@@ -74,7 +74,10 @@ void init_downlink_harq_status(NR_DL_UE_HARQ_t *dl_harq) {}
 int nr_ue_pdcch_procedures(uint8_t gNB_id,
 			   PHY_VARS_NR_UE *ue,
 			   UE_nr_rxtx_proc_t *proc,
-                           int n_ss) {
+         int32_t pdcch_est_size,
+         int32_t pdcch_dl_ch_estimates[][pdcch_est_size],
+         NR_UE_PDCCH_CONFIG *phy_pdcch_config,
+         int n_ss) {
   return 0;
 }
 
@@ -722,6 +725,8 @@ int main(int argc, char **argv)
       }
       else {
 	UE_nr_rxtx_proc_t proc={0};
+  NR_UE_PDCCH_CONFIG phy_pdcch_config={0};
+
 	UE->rx_offset=0;
 	uint8_t ssb_index = 0;
 	const int estimateSz=7*2*sizeof(int)*frame_parms->ofdm_symbol_size;
@@ -750,7 +755,8 @@ int main(int argc, char **argv)
                          0,
                          ssb_index%8,
                          SISO,
-			 &result);
+                         &phy_pdcch_config,
+                         &result);
 
 	if (ret==0) {
 	  //UE->rx_ind.rx_indication_body->mib_pdu.ssb_index;  //not yet detected automatically
diff --git a/openair1/SIMULATION/NR_PHY/prachsim.c b/openair1/SIMULATION/NR_PHY/prachsim.c
index bc4f4a0b60a33b22bc59b911628c9d3646890d68..f255ab53371c909e4aa387ae87798cb02d03b816 100644
--- a/openair1/SIMULATION/NR_PHY/prachsim.c
+++ b/openair1/SIMULATION/NR_PHY/prachsim.c
@@ -223,6 +223,8 @@ nrUE_params_t *get_nrUE_params(void) {
   return &nrUE_params;
 }
 
+nr_bler_struct nr_bler_data[NR_NUM_MCS];
+
 void processSlotTX(void *arg) {}
 
 int main(int argc, char **argv){
diff --git a/openair1/SIMULATION/NR_PHY/pucchsim.c b/openair1/SIMULATION/NR_PHY/pucchsim.c
index 151d51d7267c77a944f7f3bc1c00a9051130fa51..b6dc3d8f11e8e804d4094e6d7074f511d1af9278 100644
--- a/openair1/SIMULATION/NR_PHY/pucchsim.c
+++ b/openair1/SIMULATION/NR_PHY/pucchsim.c
@@ -551,7 +551,7 @@ int main(int argc, char **argv)
 
       if (n_trials==1) printf("txlev %d (%f dB), offset %d, sigma2 %f ( %f dB)\n",txlev,10*log10(txlev),startingSymbolIndex*frame_parms->ofdm_symbol_size,sigma2,sigma2_dB);
 
-      struct complex16 **rxdataF =  (struct complex16 **)gNB->common_vars.rxdataF;
+      c16_t **rxdataF =  (struct complex16 **)gNB->common_vars.rxdataF;
       for (int symb=0; symb<gNB->frame_parms.symbols_per_slot;symb++) {
         if (symb<startingSymbolIndex || symb >= startingSymbolIndex+nrofSymbols) {
           int i0 = symb*gNB->frame_parms.ofdm_symbol_size;
diff --git a/openair1/SIMULATION/NR_PHY/ulsim.c b/openair1/SIMULATION/NR_PHY/ulsim.c
index ddb3d52b9c7e6fde651d4bbe6bd3fe8c651ee0d3..09499248b2c96767352c5c6e0e6189d109087327 100644
--- a/openair1/SIMULATION/NR_PHY/ulsim.c
+++ b/openair1/SIMULATION/NR_PHY/ulsim.c
@@ -221,6 +221,8 @@ int DU_send_INITIAL_UL_RRC_MESSAGE_TRANSFER(module_id_t     module_idP,
   return 0;
 }
 
+nr_bler_struct nr_bler_data[NR_NUM_MCS];
+
 //nFAPI P7 dummy functions
 
 int oai_nfapi_dl_tti_req(nfapi_nr_dl_tti_request_t *dl_config_req) { return(0);  }
@@ -780,10 +782,10 @@ int main(int argc, char **argv)
 
   init_nr_ue_transport(UE);
 
-  // initialize the pusch dmrs
-  uint16_t N_n_scid[2] = {frame_parms->Nid_cell,frame_parms->Nid_cell};
-  int n_scid = 0; // This quantity is indicated by higher layer parameter dmrs-SeqInitialization
-  nr_init_pusch_dmrs(UE, N_n_scid, n_scid);
+  for(int n_scid = 0; n_scid<2; n_scid++) {
+    UE->scramblingID_ulsch[n_scid] = frame_parms->Nid_cell;
+    nr_init_pusch_dmrs(UE, frame_parms->Nid_cell, n_scid);
+  }
 
   //Configure UE
   NR_UE_RRC_INST_t rrcue;
diff --git a/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/frame_config_test.c b/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/frame_config_test.c
index c88c261667de88bf56aebb288a4090029e42d84d..093bb2d0006c6a7bd5f1d0a41adafe9e63a210a9 100644
--- a/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/frame_config_test.c
+++ b/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/frame_config_test.c
@@ -285,7 +285,7 @@ int main(int argc, char *argv[])
   uint8_t nb_antennas_tx = 1;
   uint8_t nb_antennas_rx = 1;
   uint8_t frame_type = FDD;
-  uint8_t N_RB_DL=100;
+  int N_RB_DL=100;
   lte_prefix_type_t extended_prefix_flag = NORMAL;
   int Nid_cell[] = {(3*0+0)};
   VOID_PARAMETER argc;
diff --git a/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/harq_test.c b/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/harq_test.c
index 05170e0bc96feca3a5f67753d97b478988f1dd6a..96d7382f2b86cd08a4bd7b7fa48dcd608740d5fa 100644
--- a/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/harq_test.c
+++ b/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/harq_test.c
@@ -200,7 +200,7 @@ int main(int argc, char *argv[])
   uint8_t nb_antennas_tx = 1;
   uint8_t nb_antennas_rx = 1;
   uint8_t frame_type = FDD;
-  uint8_t N_RB_DL=100;
+  int N_RB_DL=100;
   lte_prefix_type_t extended_prefix_flag = NORMAL;
   int Nid_cell[] = {(3*0+0)};
   VOID_PARAMETER argc;
diff --git a/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/pbch_test.c b/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/pbch_test.c
index 7600dfb08f0d1987c17014df8c702da973320db2..5c7f3157e7e408ad10656e87e17eb9d62cc920e8 100644
--- a/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/pbch_test.c
+++ b/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/pbch_test.c
@@ -379,7 +379,7 @@ int main(int argc, char *argv[])
   uint8_t nb_antennas_tx = 1;
   uint8_t nb_antennas_rx = 1;
   uint8_t frame_type = FDD;
-  uint8_t N_RB_DL=100;
+  int N_RB_DL=100;
   lte_prefix_type_t extended_prefix_flag = NORMAL;
   int decoded_pbch = -1;
   int Nid1, Nid2;
diff --git a/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/pss_test.c b/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/pss_test.c
index 2088d558cb24ea60b63363b79c6762bc0d0909ff..de1249457fb2d023c88a209656bbeba671a61d83 100644
--- a/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/pss_test.c
+++ b/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/pss_test.c
@@ -184,7 +184,7 @@ int main(int argc, char *argv[])
   uint8_t nb_antennas_rx = 1;
   uint16_t Nid_cell=123;
   uint8_t frame_type=FDD;
-  uint8_t N_RB_DL=100;
+  int N_RB_DL=100;
   lte_prefix_type_t extended_prefix_flag=NORMAL;
   const char *name_test = "PSS NR";
   test_t test = { name_test, 0, 0, 0, 0};
diff --git a/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/pss_util_test.c b/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/pss_util_test.c
index 4334bd12f9d9f7adbfaa8a3fa0fa8c6f829848f6..2302c50ab190149c16be4ea5d0ff8452a8941086 100644
--- a/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/pss_util_test.c
+++ b/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/pss_util_test.c
@@ -206,7 +206,7 @@ void undefined_function(const char *function) {
 *********************************************************************/
 
 int init_test(unsigned char N_tx, unsigned char N_rx, unsigned char transmission_mode,
-              unsigned char extended_prefix_flag, uint8_t frame_type, uint16_t Nid_cell, uint8_t N_RB_DL) {
+              unsigned char extended_prefix_flag, uint8_t frame_type, uint16_t Nid_cell, int N_RB_DL) {
   (void) transmission_mode;
   NR_DL_FRAME_PARMS *frame_parms;
   int log_level = OAILOG_TRACE;
diff --git a/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/pss_util_test.h b/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/pss_util_test.h
index f0929e88c088dc12b77d99bbdf82d417c94c2779..78efc2234b6bba1ac48210b1e7838024ade28a8e 100644
--- a/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/pss_util_test.h
+++ b/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/pss_util_test.h
@@ -90,7 +90,7 @@ int set_pss_in_rx_buffer(PHY_VARS_NR_UE *PHY_vars_UE, int position_symbol, int p
 
 int init_test(unsigned char N_tx, unsigned char N_rx, unsigned char transmission_mode,
                       unsigned char extended_prefix_flag, uint8_t frame_type, uint16_t Nid_cell,
-                      uint8_t N_RB_DL);
+                      int N_RB_DL);
 
 void display_test_configuration_pss(int position, int pss_sequence_number);
 
diff --git a/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/pucch_uci_generator_test.c b/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/pucch_uci_generator_test.c
index 68acea6d9801d2b9446c8c5312c5be824f97533d..4948d0a876edc3bf2f8dd57df9251aca083bef49 100644
--- a/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/pucch_uci_generator_test.c
+++ b/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/pucch_uci_generator_test.c
@@ -142,7 +142,7 @@ int main(int argc, char *argv[]) {
   uint8_t nb_antennas_tx = 1;
   uint8_t nb_antennas_rx = 1;
   uint8_t frame_type = FDD;
-  uint8_t N_RB_DL=106;
+  int N_RB_DL=106;
   lte_prefix_type_t extended_prefix_flag = NORMAL;
   int Nid_cell[] = {(3*1+3)};
   VOID_PARAMETER argc;
diff --git a/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/pucch_uci_test.c b/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/pucch_uci_test.c
index f731edc20acab668fd873b0bcef8356306b578db..31fe15a6de8ed377a4da95aaa50b82d7d8fa2f8a 100644
--- a/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/pucch_uci_test.c
+++ b/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/pucch_uci_test.c
@@ -1239,7 +1239,7 @@ int main(int argc, char *argv[])
   uint8_t nb_antennas_tx = 1;
   uint8_t nb_antennas_rx = 1;
   uint8_t frame_type = FDD;
-  uint8_t N_RB_DL=100;
+  int N_RB_DL=100;
   lte_prefix_type_t extended_prefix_flag = NORMAL;
   int Nid_cell[] = {(3*1+3)};
   VOID_PARAMETER argc;
diff --git a/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/srs_test.c b/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/srs_test.c
index 34ea68bc61f1ddb6d353a02a665254dbc5d7f292..235387acf7eeb043fcc8ea74de566224b9eb27fd 100644
--- a/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/srs_test.c
+++ b/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/srs_test.c
@@ -442,7 +442,7 @@ int main(int argc, char *argv[])
   uint8_t nb_antennas_tx = 1;
   uint8_t nb_antennas_rx = 1;
   uint8_t frame_type = FDD;
-  uint8_t N_RB_DL=100;
+  int N_RB_DL=100;
   lte_prefix_type_t extended_prefix_flag = NORMAL;
   int Nid_cell[] = {(3*0+0)};
   VOID_PARAMETER argc;
diff --git a/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/sss_test.c b/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/sss_test.c
index 34127b604f8488b0f0e9da4b8b1c528de6df59cc..6f6594861a768da70325e9caf1f0622d24039838 100644
--- a/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/sss_test.c
+++ b/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/sss_test.c
@@ -181,7 +181,7 @@ int main(int argc, char *argv[])
   uint8_t nb_antennas_tx = 1;
   uint8_t nb_antennas_rx = 1;
   uint8_t frame_type = FDD;
-  uint8_t N_RB_DL=100;
+  int N_RB_DL=100;
   lte_prefix_type_t extended_prefix_flag = NORMAL;
   int phase;
   int Nid1, Nid2;
diff --git a/openair2/COMMON/m2ap_messages_types.h b/openair2/COMMON/m2ap_messages_types.h
index c70c50fc642517e5e7f7bf095d41f5c6a1256744..460dbfc4bb1b7d360b1bdfc856209528e2092944 100644
--- a/openair2/COMMON/m2ap_messages_types.h
+++ b/openair2/COMMON/m2ap_messages_types.h
@@ -354,7 +354,7 @@ typedef struct m2ap_register_mce_req_s {
   int32_t                 uplink_frequency_offset[MAX_NUM_CCs];
   uint32_t                Nid_cell[MAX_NUM_CCs];
   int16_t                 N_RB_DL[MAX_NUM_CCs];
-  lte_frame_type_t        frame_type[MAX_NUM_CCs];
+  frame_type_t        frame_type[MAX_NUM_CCs];
   uint32_t                fdd_earfcn_DL[MAX_NUM_CCs];
   uint32_t                fdd_earfcn_UL[MAX_NUM_CCs];
   int                     num_cc;
@@ -427,7 +427,7 @@ typedef struct m2ap_register_enb_req_s {
   int32_t                 uplink_frequency_offset[MAX_NUM_CCs];
   uint32_t                Nid_cell[MAX_NUM_CCs];
   int16_t                 N_RB_DL[MAX_NUM_CCs];
-  lte_frame_type_t        frame_type[MAX_NUM_CCs];
+  frame_type_t            frame_type[MAX_NUM_CCs];
   uint32_t                fdd_earfcn_DL[MAX_NUM_CCs];
   uint32_t                fdd_earfcn_UL[MAX_NUM_CCs];
   int                     num_cc;
diff --git a/openair2/COMMON/m3ap_messages_types.h b/openair2/COMMON/m3ap_messages_types.h
index 21e24dd449c1403386c9af38b93f8e763c875d50..36ac8fcc9ae6970e2303f8cf8b6de2964d415ccd 100644
--- a/openair2/COMMON/m3ap_messages_types.h
+++ b/openair2/COMMON/m3ap_messages_types.h
@@ -123,7 +123,7 @@ typedef struct m3ap_register_mce_req_s {
   int32_t                 uplink_frequency_offset[MAX_NUM_CCs];
   uint32_t                Nid_cell[MAX_NUM_CCs];
   int16_t                 N_RB_DL[MAX_NUM_CCs];
-  lte_frame_type_t        frame_type[MAX_NUM_CCs];
+  frame_type_t            frame_type[MAX_NUM_CCs];
   uint32_t                fdd_earfcn_DL[MAX_NUM_CCs];
   uint32_t                fdd_earfcn_UL[MAX_NUM_CCs];
   int                     num_cc;
diff --git a/openair2/COMMON/phy_messages_types.h b/openair2/COMMON/phy_messages_types.h
index 1f040a0a773e00163df53a660af70c799629f5d2..40e467822866291524343e68e6a616183604b7ec 100644
--- a/openair2/COMMON/phy_messages_types.h
+++ b/openair2/COMMON/phy_messages_types.h
@@ -70,7 +70,7 @@ typedef struct CellInfo_s {
 //-------------------------------------------------------------------------------------------//
 // eNB: ENB_APP -> PHY messages
 typedef struct PhyConfigurationReq_s {
-  lte_frame_type_t        frame_type[MAX_NUM_CCs];
+  frame_type_t            frame_type[MAX_NUM_CCs];
   lte_prefix_type_t       prefix_type[MAX_NUM_CCs];
   uint32_t                downlink_frequency[MAX_NUM_CCs];
   int32_t                 uplink_frequency_offset[MAX_NUM_CCs];
diff --git a/openair2/COMMON/platform_types.h b/openair2/COMMON/platform_types.h
index c24291de645460de2e063368cfb0566c82e54273..67300da308b92ed05e7f901ae15436794f675826 100644
--- a/openair2/COMMON/platform_types.h
+++ b/openair2/COMMON/platform_types.h
@@ -233,6 +233,7 @@ typedef uint8_t            pdusessionid_t;
 //-----------------------------------------------------------------------------
 // may be ITTI not enabled, but type instance is useful also for OTG,
 typedef intptr_t instance_t;
+
 typedef struct protocol_ctxt_s {
   module_id_t module_id;     /*!< \brief  Virtualized module identifier      */
   eNB_flag_t  enb_flag;      /*!< \brief  Flag to indicate eNB (1) or UE (0) */
diff --git a/openair2/COMMON/rrc_messages_types.h b/openair2/COMMON/rrc_messages_types.h
index 6b41970735d140ee46c882eb95ca8e1a1e21decc..5b214cf95a9ce515f04da6ec91e235be43b3711a 100644
--- a/openair2/COMMON/rrc_messages_types.h
+++ b/openair2/COMMON/rrc_messages_types.h
@@ -188,7 +188,7 @@ typedef struct RrcConfigurationReq_s {
   uint32_t                rrc_inactivity_timer_thres; // for testing, maybe change later
   paging_drx_t            default_drx;
   int16_t                 nb_cc;
-  lte_frame_type_t        frame_type[MAX_NUM_CCs];
+  frame_type_t            frame_type[MAX_NUM_CCs];
   uint8_t                 tdd_config[MAX_NUM_CCs];
   uint8_t                 tdd_config_s[MAX_NUM_CCs];
   lte_prefix_type_t       prefix_type[MAX_NUM_CCs];
@@ -339,7 +339,7 @@ typedef struct NbIoTRrcConfigurationReq_s {
   uint16_t                mcc;
   uint16_t                mnc;
   uint8_t                 mnc_digit_length;
-  lte_frame_type_t        frame_type;
+  frame_type_t            frame_type;
   uint8_t                 tdd_config;
   uint8_t                 tdd_config_s;
   lte_prefix_type_t       prefix_type;
@@ -427,6 +427,7 @@ typedef struct NRRrcConfigurationReq_s {
   bool                    force_256qam_off;
   int                     pusch_TargetSNRx10;
   int                     pucch_TargetSNRx10;
+  bool                    enable_sdap;
 } gNB_RrcConfigurationReq;
 
 typedef struct NRDuDlReq_s {
diff --git a/openair2/COMMON/x2ap_messages_types.h b/openair2/COMMON/x2ap_messages_types.h
index 9339ab12f38fd4b842cc0e0aad8b9c6e9afdeefb..cd092b6ca8987652aa2d31f0bcc95fda44a6488d 100644
--- a/openair2/COMMON/x2ap_messages_types.h
+++ b/openair2/COMMON/x2ap_messages_types.h
@@ -138,7 +138,7 @@ typedef struct x2ap_register_enb_req_s {
   int32_t                 uplink_frequency_offset[MAX_NUM_CCs];
   uint32_t                Nid_cell[MAX_NUM_CCs];
   int16_t                 N_RB_DL[MAX_NUM_CCs];
-  lte_frame_type_t        frame_type[MAX_NUM_CCs];
+  frame_type_t            frame_type[MAX_NUM_CCs];
   uint32_t                fdd_earfcn_DL[MAX_NUM_CCs];
   uint32_t                fdd_earfcn_UL[MAX_NUM_CCs];
   uint32_t                subframeAssignment[MAX_NUM_CCs];
diff --git a/openair2/ENB_APP/RRC_config_tools.h b/openair2/ENB_APP/RRC_config_tools.h
index 488441ff59f8cd68c258645cb5a9cddc3eeec9bd..89cefeaa1fd1201172f950a47200d0388f639e15 100644
--- a/openair2/ENB_APP/RRC_config_tools.h
+++ b/openair2/ENB_APP/RRC_config_tools.h
@@ -38,7 +38,7 @@ typedef struct eutra_band_s {
   uint32_t            ul_max;
   uint32_t            dl_min;
   uint32_t            dl_max;
-  lte_frame_type_t    frame_type;
+  frame_type_t        frame_type;
 } eutra_band_t;
 
 
diff --git a/openair2/ENB_APP/flexran_agent_ran_api.c b/openair2/ENB_APP/flexran_agent_ran_api.c
index 68d1f3311f261ab38f45250c35371b5f53d8cd39..9926ec9e20639d356b5e1ccdc6cf13b0a5cf83a4 100644
--- a/openair2/ENB_APP/flexran_agent_ran_api.c
+++ b/openair2/ENB_APP/flexran_agent_ran_api.c
@@ -1352,7 +1352,7 @@ 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) {
+void flexran_agent_set_operating_frame_type(mid_t mod_id, uint8_t cc_id, frame_type_t frame_type) {
   if (phy_is_present(mod_id, cc_id)) {
     RC.eNB[mod_id][cc_id]->frame_parms.frame_type = frame_type;
   } else {
diff --git a/openair2/ENB_APP/flexran_agent_ran_api.h b/openair2/ENB_APP/flexran_agent_ran_api.h
index 79115b0a168b0030af938b6291d34a0a2c8ac1bc..c15865ccfd081d7ca4eb9262abc7163b4cd096f9 100644
--- a/openair2/ENB_APP/flexran_agent_ran_api.h
+++ b/openair2/ENB_APP/flexran_agent_ran_api.h
@@ -433,7 +433,7 @@ void flexran_agent_set_operating_eutra_band(mid_t mod_id, uint8_t cc_id, uint8_t
 void flexran_agent_set_operating_bandwidth(mid_t mod_id, uint8_t cc_id, uint8_t N_RB);
 
 /*set frame type*/
-void flexran_agent_set_operating_frame_type(mid_t mod_id, uint8_t cc_id, lte_frame_type_t frame_type);
+void flexran_agent_set_operating_frame_type(mid_t mod_id, uint8_t cc_id, frame_type_t frame_type);
 
 /*RRC status flexRAN*/
 uint8_t flexran_get_rrc_status(mid_t mod_id, rnti_t rnti);
diff --git a/openair2/F1AP/dummy_enb.c b/openair2/F1AP/dummy_enb.c
index d54f9b8df7b21bb90ec9ea8ca182f785e7e20787..9085fdb57cd772eb39319199540f2a22817a94da 100644
--- a/openair2/F1AP/dummy_enb.c
+++ b/openair2/F1AP/dummy_enb.c
@@ -32,16 +32,18 @@ void apply_macrlc_config(gNB_RRC_INST *rrc,
   abort();
 }
 
-boolean_t sdap_gnb_data_req(protocol_ctxt_t *ctxt_p,
-                            const srb_flag_t srb_flag,
-                            const rb_id_t rb_id,
-                            const mui_t mui,
-                            const confirm_t confirm,
-                            const sdu_size_t sdu_buffer_size,
-                            unsigned char *const sdu_buffer,
-                            const pdcp_transmission_mode_t pt_mode,
-                            const uint32_t *sourceL2Id,
-                            const uint32_t *destinationL2Id
-                           ) {
+boolean_t sdap_data_req(protocol_ctxt_t *ctxt_p,
+                        const srb_flag_t srb_flag,
+                        const rb_id_t rb_id,
+                        const mui_t mui,
+                        const confirm_t confirm,
+                        const sdu_size_t sdu_buffer_size,
+                        unsigned char *const sdu_buffer,
+                        const pdcp_transmission_mode_t pt_mode,
+                        const uint32_t *sourceL2Id,
+                        const uint32_t *destinationL2Id,
+                        const uint8_t qfi,
+                        const boolean_t rqi,
+                        const int pdusession_id) {
 abort();
 }
diff --git a/openair2/GNB_APP/gnb_config.c b/openair2/GNB_APP/gnb_config.c
index 503e04ecb93091e72fb974f3bf8a3cb87cc79219..2c486ec83244b86021550429553063d149e604a8 100644
--- a/openair2/GNB_APP/gnb_config.c
+++ b/openair2/GNB_APP/gnb_config.c
@@ -346,7 +346,7 @@ void fix_scc(NR_ServingCellConfigCommon_t *scc,uint64_t ssbmap) {
   // prepare DL Allocation lists
   nr_rrc_config_dl_tda(scc);
 
-  lte_frame_type_t frame_type = get_frame_type((int)*scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0], *scc->ssbSubcarrierSpacing);
+  frame_type_t frame_type = get_frame_type((int)*scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0], *scc->ssbSubcarrierSpacing);
   if (frame_type == FDD) {
     ASN_STRUCT_FREE(asn_DEF_NR_TDD_UL_DL_ConfigCommon, scc->tdd_UL_DL_ConfigurationCommon);
     scc->tdd_UL_DL_ConfigurationCommon = NULL;
@@ -1192,7 +1192,9 @@ void RCconfig_NRRRC(MessageDef *msg_p, uint32_t i, gNB_RRC_INST *rrc) {
         LOG_I(RRC, "256 QAM: %s\n", NRRRC_CONFIGURATION_REQ (msg_p).force_256qam_off ? "force off" : "may be on");
         NRRRC_CONFIGURATION_REQ (msg_p).scc = scc;
         NRRRC_CONFIGURATION_REQ (msg_p).scd = scd;
-	  
+	    NRRRC_CONFIGURATION_REQ (msg_p).enable_sdap = *GNBParamList.paramarray[i][GNB_ENABLE_SDAP_IDX].iptr;
+        LOG_I(GNB_APP, "SDAP layer is %s\n", NRRRC_CONFIGURATION_REQ (msg_p).enable_sdap ? "enabled" : "disabled");
+        
       }//
     }//End for (k=0; k <num_gnbs ; k++)
     memcpy(&rrc->configuration, &NRRRC_CONFIGURATION_REQ(msg_p), sizeof(NRRRC_CONFIGURATION_REQ(msg_p)));
diff --git a/openair2/GNB_APP/gnb_paramdef.h b/openair2/GNB_APP/gnb_paramdef.h
index e1d3d93d0b2f91d569e127fc122e518e5779d9f8..8cd831970fae7b9b6a4a84aa6b4959b0ab2893b1 100644
--- a/openair2/GNB_APP/gnb_paramdef.h
+++ b/openair2/GNB_APP/gnb_paramdef.h
@@ -125,7 +125,8 @@ typedef enum {
 #define GNB_CONFIG_STRING_MINRXTXTIME                   "min_rxtxtime"
 #define GNB_CONFIG_STRING_ULPRBBLACKLIST                "ul_prbblacklist"
 #define GNB_CONFIG_STRING_FORCE256QAMOFF                "force_256qam_off"
-
+#define GNB_CONFIG_STRING_ENABLE_SDAP                   "enable_sdap"
+#define GNB_CONFIG_HLP_STRING_ENABLE_SDAP               "enable the SDAP layer\n"
 
 #define GNB_CONFIG_HLP_FORCE256QAMOFF                   "suppress activation of 256 QAM despite UE support"
 
@@ -153,13 +154,14 @@ typedef enum {
 {GNB_CONFIG_STRING_PDSCHANTENNAPORTS_N2, "vert. log. antenna ports", 0, iptr:NULL,  defintval:1,                 TYPE_INT,       0},  \
 {GNB_CONFIG_STRING_PDSCHANTENNAPORTS_XP, "XP log. antenna ports",   0, iptr:NULL,   defintval:1,                 TYPE_INT,       0},  \
 {GNB_CONFIG_STRING_PUSCHANTENNAPORTS,            NULL,   0,            iptr:NULL,   defintval:1,                 TYPE_INT,       0},  \
-{GNB_CONFIG_STRING_SIB1TDA,                      NULL,   0,            iptr:NULL,   defintval:0,                 TYPE_INT,       0},  \
+{GNB_CONFIG_STRING_SIB1TDA,                      NULL,   0,            iptr:NULL,   defintval:1,                 TYPE_INT,       0},  \
 {GNB_CONFIG_STRING_DOCSIRS,                      NULL,   0,            iptr:NULL,   defintval:0,                 TYPE_INT,       0},  \
 {GNB_CONFIG_STRING_DOSRS,                        NULL,   0,            iptr:NULL,   defintval:0,                 TYPE_INT,       0},  \
 {GNB_CONFIG_STRING_NRCELLID,                     NULL,   0,            u64ptr:NULL, defint64val:1,               TYPE_UINT64,    0},  \
 {GNB_CONFIG_STRING_MINRXTXTIME,                  NULL,   0,            iptr:NULL,   defintval:2,                 TYPE_INT,       0},  \
 {GNB_CONFIG_STRING_ULPRBBLACKLIST,               NULL,   0,            strptr:NULL, defstrval:"",                TYPE_STRING,    0},  \
-{GNB_CONFIG_STRING_FORCE256QAMOFF, GNB_CONFIG_HLP_FORCE256QAMOFF, PARAMFLAG_BOOL, iptr:NULL, defintval:0,        TYPE_INT,       0}   \
+{GNB_CONFIG_STRING_FORCE256QAMOFF, GNB_CONFIG_HLP_FORCE256QAMOFF, PARAMFLAG_BOOL, iptr:NULL, defintval:0,        TYPE_INT,       0},  \
+{GNB_CONFIG_STRING_ENABLE_SDAP, GNB_CONFIG_HLP_STRING_ENABLE_SDAP, PARAMFLAG_BOOL, iptr:NULL, defintval:0,       TYPE_INT,       0},  \
 }
 
 #define GNB_GNB_ID_IDX                  0
@@ -188,6 +190,7 @@ typedef enum {
 #define GNB_MINRXTXTIME_IDX             23
 #define GNB_ULPRBBLACKLIST_IDX          24
 #define GNB_FORCE256QAMOFF_IDX          25
+#define GNB_ENABLE_SDAP_IDX             26
 
 #define TRACKING_AREA_CODE_OKRANGE {0x0001,0xFFFD}
 #define GNBPARAMS_CHECK {                                         \
diff --git a/openair2/LAYER2/MAC/config.c b/openair2/LAYER2/MAC/config.c
index 209275acb38c69c6351fce0f87ed7fda56589662..d22485d23f261823d8b028c90a46b056273eb9eb 100644
--- a/openair2/LAYER2/MAC/config.c
+++ b/openair2/LAYER2/MAC/config.c
@@ -58,11 +58,6 @@ extern int l2_init_eNB(void);
 extern void mac_top_init_eNB(void);
 extern void mac_init_cell_params(int Mod_idP,int CC_idP);
 
-
-int32_t **rxdata;
-int32_t **txdata;
-
-
 typedef struct eutra_bandentry_s {
   int16_t band;
   uint32_t ul_min;
diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h b/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h
index ba3128923fb32e86895f99fd183a7ec179db9619..9123afd3248bb6f750f2c43ffd66a00f9bab113b 100644
--- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h
+++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h
@@ -39,6 +39,7 @@
 #include <stdbool.h>
 
 #include "NR_SubcarrierSpacing.h"
+#include "openair1/SCHED_NR_UE/harq_nr.h"
 
 #define NR_SHORT_BSR_TABLE_SIZE 32
 #define NR_LONG_BSR_TABLE_SIZE 256
@@ -106,11 +107,10 @@ typedef struct {
 } __attribute__ ((__packed__)) NR_MAC_SUBHEADER_SHORT;
 
 typedef struct {
-  uint8_t LCID: 6;    // octet 1 [5:0]
-  uint8_t F: 1;       // octet 1 [6]
-  uint8_t R: 1;       // octet 1 [7]
-  uint8_t L1: 8;      // octet 2 [7:0]
-  uint8_t L2: 8;      // octet 3 [7:0]
+  uint8_t LCID: 6;
+  uint8_t F: 1;
+  uint8_t R: 1;
+  uint16_t L: 16;
 } __attribute__ ((__packed__)) NR_MAC_SUBHEADER_LONG;
 
 typedef struct {
@@ -118,6 +118,23 @@ typedef struct {
   uint8_t R: 2;       // octet 1 [7:6]
 } __attribute__ ((__packed__)) NR_MAC_SUBHEADER_FIXED;
 
+static inline int get_mac_len(uint8_t* pdu, int pdu_len, uint16_t *mac_ce_len, uint16_t *mac_subheader_len) {
+  if ( pdu_len < sizeof(NR_MAC_SUBHEADER_SHORT))
+    return false;
+  NR_MAC_SUBHEADER_SHORT *s = (NR_MAC_SUBHEADER_SHORT*) pdu;
+  NR_MAC_SUBHEADER_LONG *l = (NR_MAC_SUBHEADER_LONG*) pdu;
+  if (s->F && pdu_len < sizeof(NR_MAC_SUBHEADER_LONG))
+    return false;
+  if (s->F) {
+    *mac_subheader_len = sizeof(*l);
+    *mac_ce_len = ntohs(l->L);
+  } else {
+    *mac_subheader_len = sizeof(*s);
+    *mac_ce_len = s->L;
+  }
+  return true;
+}
+    
 // BSR MAC CEs
 // TS 38.321 ch. 6.1.3.1
 // Short BSR for a specific logical channel group ID
@@ -264,14 +281,29 @@ typedef struct {
   uint8_t nbits;
 } dci_field_t;
 
+typedef struct {
+  /* The active harq sfn/slot field was created to save the
+     scheduled SFN/Slot transmission for the ACK/NAK. If we
+     do not save it, then we have to calculate it again as the
+     NRUE MAC layer already does in get_downlink_ack(). */
+  int active_dl_harq_sfn;
+  int active_dl_harq_slot;
+  int active_ul_harq_sfn_slot;
+  bool active;
+} emul_l1_harq_t;
+
 typedef struct {
   bool expected_sib;
-  bool index_has_sib[16];
+  bool index_has_sib[NR_MAX_HARQ_PROCESSES];
   bool expected_rar;
-  bool index_has_rar[16];
+  bool index_has_rar[NR_MAX_HARQ_PROCESSES];
   bool expected_dci;
-  bool index_has_dci[16];
-  int active_harq_sfn_slot;
+  bool index_has_dci[NR_MAX_HARQ_PROCESSES];
+  emul_l1_harq_t harq[NR_MAX_HARQ_PROCESSES];
+  int active_uci_sfn_slot;
+  int num_srs;
+  int num_harqs;
+  int num_csi_reports;
 } nr_emulated_l1_t;
 
 typedef struct {
diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c
index b25efbb5d88fed71b8b160fbff5c78f6931c5167..581930b83d2993a3637edc09714358e40aac1acd 100644
--- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c
+++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c
@@ -3092,7 +3092,7 @@ int is_nr_DL_slot(NR_TDD_UL_DL_ConfigCommon_t *tdd_UL_DL_ConfigurationCommon,slo
   else return(slot_in_period <= slots1+tdd_UL_DL_ConfigurationCommon->pattern2->nrofDownlinkSlots ? 1 : 0);    
 }
 
-int is_nr_UL_slot(NR_TDD_UL_DL_ConfigCommon_t	*tdd_UL_DL_ConfigurationCommon, slot_t slot, lte_frame_type_t frame_type) {
+int is_nr_UL_slot(NR_TDD_UL_DL_ConfigCommon_t	*tdd_UL_DL_ConfigurationCommon, slot_t slot, frame_type_t frame_type) {
 
   int period,period1,period2=0;
 
diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h
index 0f2cb42b8817e585643b305d5093559cbc87df9b..e8a3af249813d8a812a2ff8fba05eaa26fea6d1c 100644
--- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h
+++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h
@@ -45,7 +45,7 @@ int16_t fill_dmrs_mask(NR_PDSCH_Config_t *pdsch_Config,int dmrs_TypeA_Position,i
 
 int is_nr_DL_slot(NR_TDD_UL_DL_ConfigCommon_t *tdd_UL_DL_ConfigurationCommon,slot_t slotP);
 
-int is_nr_UL_slot(NR_TDD_UL_DL_ConfigCommon_t *tdd_UL_DL_ConfigurationCommon, slot_t slotP, lte_frame_type_t frame_type);
+int is_nr_UL_slot(NR_TDD_UL_DL_ConfigCommon_t *tdd_UL_DL_ConfigurationCommon, slot_t slotP, frame_type_t frame_type);
 
 uint16_t nr_dci_size(const NR_BWP_DownlinkCommon_t *initialDLBWP,
                      const NR_BWP_UplinkCommon_t *initialULBWP,
diff --git a/openair2/LAYER2/NR_MAC_UE/config_ue.c b/openair2/LAYER2/NR_MAC_UE/config_ue.c
index 3b10167e03c33d2f46c070130e91fb204dade024..bd693e4d888d15be8b1ae42d91b76efea1f123b4 100644
--- a/openair2/LAYER2/NR_MAC_UE/config_ue.c
+++ b/openair2/LAYER2/NR_MAC_UE/config_ue.c
@@ -323,7 +323,7 @@ void config_common_ue(NR_UE_MAC_INST_t *mac,
     uint32_t band = *scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0];
     mac->frequency_range = band<100?FR1:FR2;
     
-    lte_frame_type_t frame_type = get_frame_type(*scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0], *scc->ssbSubcarrierSpacing);
+    frame_type_t frame_type = get_frame_type(*scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0], *scc->ssbSubcarrierSpacing);
     
     // cell config
     
diff --git a/openair2/LAYER2/NR_MAC_UE/mac_defs.h b/openair2/LAYER2/NR_MAC_UE/mac_defs.h
index ad86b1385df114294fbe2f131a9a568c75f06a38..99cbdf32927e44e5d2211370296454d4bca87fd0 100644
--- a/openair2/LAYER2/NR_MAC_UE/mac_defs.h
+++ b/openair2/LAYER2/NR_MAC_UE/mac_defs.h
@@ -369,7 +369,7 @@ typedef struct {
   NR_ControlResourceSet_t         *coreset[MAX_NUM_BWP][FAPI_NR_MAX_CORESET_PER_BWP];
   NR_SearchSpace_t                *SSpace[MAX_NUM_BWP][FAPI_NR_MAX_SS];
 
-  lte_frame_type_t frame_type;
+  frame_type_t frame_type;
 
   /*BWP*/
   // dedicated active DL BWP
@@ -432,7 +432,7 @@ typedef struct {
 
   // Defined for abstracted mode
   nr_downlink_indication_t dl_info;
-  NR_UE_HARQ_STATUS_t dl_harq_info[16];
+  NR_UE_HARQ_STATUS_t dl_harq_info[NR_MAX_HARQ_PROCESSES];
 
   nr_emulated_l1_t nr_ue_emul_l1;
 
diff --git a/openair2/LAYER2/NR_MAC_UE/mac_proto.h b/openair2/LAYER2/NR_MAC_UE/mac_proto.h
index 3e4d53b985be0ae4270287fed9ef0e5d7ec2e4e4..7ed99b92b5131d76740fb7b61b714a4759e05422 100644
--- a/openair2/LAYER2/NR_MAC_UE/mac_proto.h
+++ b/openair2/LAYER2/NR_MAC_UE/mac_proto.h
@@ -48,6 +48,7 @@ void nr_ue_init_mac(module_id_t module_idP);
    \param module_id      module id
    \param cc_id          component carrier id
    \param gNB_index      gNB index
+   \param phy_data       PHY structure to be filled in by the callee in the FAPI call (L1 caller -> indication to L2 -> FAPI call to L1 callee)
    \param extra_bits     extra bits for frame calculation
    \param l_ssb_equal_64 check if ssb number of candicate is equal 64, 1=equal; 0=non equal. Reference 38.212 7.1.1
    \param pduP           pointer to pdu
@@ -56,7 +57,8 @@ void nr_ue_init_mac(module_id_t module_idP);
 int8_t nr_ue_decode_mib(
     module_id_t module_id, 
     int cc_id, 
-    uint8_t gNB_index, 
+    uint8_t gNB_index,
+    void *phy_data, 
     uint8_t extra_bits, 
     uint32_t ssb_length, 
     uint32_t ssb_index,
@@ -132,7 +134,7 @@ NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_in
    @param int cc_id                    CC ID
    @param frame_t frame                frame number
    @param int slot                     reference number
-   @param UE_nr_rxtx_proc_t *proc      pointer to process context */
+   @param void *phy_pata               pointer to a PHY specific structure to be filled in the scheduler response (can be null) */
 void fill_scheduled_response(nr_scheduled_response_t *scheduled_response,
                              fapi_nr_dl_config_request_t *dl_config,
                              fapi_nr_ul_config_request_t *ul_config,
@@ -141,7 +143,8 @@ void fill_scheduled_response(nr_scheduled_response_t *scheduled_response,
                              int cc_id,
                              frame_t frame,
                              int slot,
-                             int thread_id);
+                             int thread_id,
+                             void *phy_data);
 
 /*! \fn int8_t nr_ue_get_SR(module_id_t module_idP, frame_t frameP, slot_t slotP);
    \brief Called by PHY to get sdu for PUSCH transmission.  It performs the following operations: Checks BSR for DCCH, DCCH1 and DTCH corresponding to previous values computed either in SR or BSR procedures.  It gets rlc status indications on DCCH,DCCH1 and DTCH and forms BSR elements and PHR in MAC header.  CRNTI element is not supported yet.  It computes transport block for up to 3 SDUs and generates header and forms the complete MAC SDU.
@@ -373,7 +376,8 @@ void nr_ue_sib1_scheduler(module_id_t module_idP,
                           uint8_t ssb_subcarrier_offset,
                           uint32_t ssb_index,
                           uint16_t ssb_start_subcarrier,
-                          frequency_range_t frequency_range);
+                          frequency_range_t frequency_range,
+                          void *phy_data);
 
 /* \brief Function called by PHY to process the received RAR and check that the preamble matches what was sent by the gNB. It provides the timing advance and t-CRNTI.
 @param Mod_id Index of UE instance
diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c
index c57736990c79425db127df3bad2ea5df72d5069b..79ebaea70ace7b82964b141988301fb974709d37 100644
--- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c
+++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c
@@ -281,13 +281,13 @@ int get_rnti_type(NR_UE_MAC_INST_t *mac, uint16_t rnti){
     LOG_D(MAC, "In %s: returning rnti_type %s \n", __FUNCTION__, rnti_types[rnti_type]);
 
     return rnti_type;
-
 }
 
 
 int8_t nr_ue_decode_mib(module_id_t module_id,
                         int cc_id,
                         uint8_t gNB_index,
+                        void *phy_data,
                         uint8_t extra_bits,	//	8bits 38.212 c7.1.1
                         uint32_t ssb_length,
                         uint32_t ssb_index,
@@ -363,7 +363,8 @@ int8_t nr_ue_decode_mib(module_id_t module_id,
                            ssb_subcarrier_offset,
                            ssb_index,
                            ssb_start_subcarrier,
-                           mac->frequency_range);
+                           mac->frequency_range,
+                           phy_data);
   }
   else {
     NR_ServingCellConfigCommon_t *scc = mac->scc;
@@ -874,14 +875,26 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fr
     if(pdsch_TimeDomainAllocationList && rnti!=SI_RNTI)
       mappingtype = pdsch_TimeDomainAllocationList->list.array[dci->time_domain_assignment.val]->mappingType;
 
+    struct NR_DMRS_DownlinkConfig *dl_dmrs_config = NULL;
+    if(mac->DLbwp[0])
+      dl_dmrs_config = (mappingtype == typeA) ?
+                       mac->DLbwp[0]->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup :
+                       mac->DLbwp[0]->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeB->choice.setup;
+
+    dlsch_config_pdu_1_0->nscid = 0;
+    if(dl_dmrs_config && dl_dmrs_config->scramblingID0)
+      dlsch_config_pdu_1_0->dlDmrsScramblingId = *dl_dmrs_config->scramblingID0;
+    else
+      dlsch_config_pdu_1_0->dlDmrsScramblingId = mac->physCellId;
+
     /* dmrs symbol positions*/
     dlsch_config_pdu_1_0->dlDmrsSymbPos = fill_dmrs_mask(pdsch_config,
                                                          (get_softmodem_params()->nsa) ? mac->scc->dmrs_TypeA_Position : mac->mib->dmrs_TypeA_Position,
                                                          dlsch_config_pdu_1_0->number_symbols,
                                                          dlsch_config_pdu_1_0->start_symbol,
                                                          mappingtype, 1);
-    dlsch_config_pdu_1_0->dmrsConfigType = (mac->DLbwp[0] != NULL) ?
-                                           (mac->DLbwp[0]->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_Type == NULL ? 0 : 1) : 0;
+    dlsch_config_pdu_1_0->dmrsConfigType = (dl_dmrs_config != NULL) ?
+                                           (dl_dmrs_config->dmrs_Type == NULL ? 0 : 1) : 0;
 
     /* number of DM-RS CDM groups without data according to subclause 5.1.6.2 of 3GPP TS 38.214 version 15.9.0 Release 15 */
     if (dlsch_config_pdu_1_0->number_symbols == 2)
@@ -1075,7 +1088,30 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fr
     if(pdsch_TimeDomainAllocationList)
       mappingtype = pdsch_TimeDomainAllocationList->list.array[dci->time_domain_assignment.val]->mappingType;
 
-    dlsch_config_pdu_1_1->dmrsConfigType = pdsch_Config->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_Type == NULL ? NFAPI_NR_DMRS_TYPE1 : NFAPI_NR_DMRS_TYPE2;
+    struct NR_DMRS_DownlinkConfig *dl_dmrs_config = (mappingtype == typeA) ?
+                                                    pdsch_Config->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup :
+                                                    pdsch_Config->dmrs_DownlinkForPDSCH_MappingTypeB->choice.setup;
+
+    switch (dci->dmrs_sequence_initialization.val) {
+      case 0:
+        dlsch_config_pdu_1_1->nscid = 0;
+        if(dl_dmrs_config->scramblingID0)
+          dlsch_config_pdu_1_1->dlDmrsScramblingId = *dl_dmrs_config->scramblingID0;
+        else
+          dlsch_config_pdu_1_1->dlDmrsScramblingId = mac->physCellId;
+        break;
+      case 1:
+        dlsch_config_pdu_1_1->nscid = 1;
+        if(dl_dmrs_config->scramblingID1)
+          dlsch_config_pdu_1_1->dlDmrsScramblingId = *dl_dmrs_config->scramblingID1;
+        else
+          dlsch_config_pdu_1_1->dlDmrsScramblingId = mac->physCellId;
+        break;
+      default:
+        AssertFatal(1==0,"Invalid dmrs sequence initialization value\n");
+    }
+
+    dlsch_config_pdu_1_1->dmrsConfigType = dl_dmrs_config->dmrs_Type == NULL ? NFAPI_NR_DMRS_TYPE1 : NFAPI_NR_DMRS_TYPE2;
 
     /* TODO: fix number of DM-RS CDM groups without data according to subclause 5.1.6.2 of 3GPP TS 38.214,
              using tables 7.3.1.2.2-1, 7.3.1.2.2-2, 7.3.1.2.2-3, 7.3.1.2.2-4 of 3GPP TS 38.212 */
@@ -1136,17 +1172,11 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fr
 
     /* ANTENNA_PORTS */
     uint8_t n_codewords = 1; // FIXME!!!
-    long *max_length = NULL;
-    long *dmrs_type = NULL;
+    long *max_length = dl_dmrs_config->maxLength;
+    long *dmrs_type = dl_dmrs_config->dmrs_Type;
+
     dlsch_config_pdu_1_1->n_front_load_symb = 1; // default value
-    if (pdsch_Config->dmrs_DownlinkForPDSCH_MappingTypeA) {
-      max_length = pdsch_Config->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->maxLength;
-      dmrs_type = pdsch_Config->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_Type;
-    }
-    if (pdsch_Config->dmrs_DownlinkForPDSCH_MappingTypeB) {
-      max_length = pdsch_Config->dmrs_DownlinkForPDSCH_MappingTypeB->choice.setup->maxLength;
-      dmrs_type = pdsch_Config->dmrs_DownlinkForPDSCH_MappingTypeB->choice.setup->dmrs_Type;
-    }
+
     if ((dmrs_type == NULL) && (max_length == NULL)){
       // Table 7.3.1.2.2-1: Antenna port(s) (1000 + DMRS port), dmrs-Type=1, maxLength=1
       dlsch_config_pdu_1_1->n_dmrs_cdm_groups = table_7_3_2_3_3_1[dci->antenna_ports.val][0];
@@ -1368,10 +1398,18 @@ void set_harq_status(NR_UE_MAC_INST_t *mac,
   // FIXME k0 != 0 currently not taken into consideration
   current_harq->dl_frame = frame;
   current_harq->dl_slot = slot;
-  mac->nr_ue_emul_l1.active_harq_sfn_slot = NFAPI_SFNSLOT2HEX(frame, (slot + data_toul_fb));
+  if (get_softmodem_params()->emulate_l1) {
+    int scs = get_softmodem_params()->numerology;
+    int slots_per_frame = nr_slots_per_frame[scs];
+    slot += data_toul_fb;
+    if (slot >= slots_per_frame) {
+      frame = (frame + 1) % 1024;
+      slot %= slots_per_frame;
+    }
+  }
 
   LOG_D(NR_PHY,"Setting harq_status for harq_id %d, dl %d.%d, sched ul %d.%d\n",
-        harq_id, frame, slot, frame, (slot + data_toul_fb));
+        harq_id, current_harq->dl_frame, current_harq->dl_slot, frame, slot);
 }
 
 
@@ -1853,7 +1891,8 @@ int find_pucch_resource_set(NR_UE_MAC_INST_t *mac, int uci_size) {
          mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP->pucch_Config->choice.setup &&
          mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP->pucch_Config->choice.setup->resourceSetToAddModList &&
          mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP->pucch_Config->choice.setup->resourceSetToAddModList->list.array[pucch_resource_set_id] != NULL)) {
-      if (uci_size <= 2) {
+      // PUCCH with format0 can be up to 3 bits (2 ack/nacks + 1 sr is 3 max bits)
+      if (uci_size <= 3) {
         pucch_resource_set_id = 0;
         return (pucch_resource_set_id);
         break;
@@ -2054,11 +2093,17 @@ uint8_t get_downlink_ack(NR_UE_MAC_INST_t *mac,
         sched_frame = current_harq->dl_frame;
         if (sched_slot>=slots_per_frame){
           sched_slot %= slots_per_frame;
-          sched_frame++;
+          sched_frame = (sched_frame + 1) % 1024;
         }
+        AssertFatal(sched_slot < slots_per_frame, "sched_slot was calculated incorrect %d\n", sched_slot);
         LOG_D(PHY,"HARQ pid %d is active for %d.%d (dl_slot %d, feedback_to_ul %d, is_common %d\n",dl_harq_pid, sched_frame,sched_slot,current_harq->dl_slot,current_harq->feedback_to_ul,current_harq->is_common);
         /* check if current tx slot should transmit downlink acknowlegment */
         if (sched_frame == frame && sched_slot == slot) {
+          if (get_softmodem_params()->emulate_l1) {
+            mac->nr_ue_emul_l1.harq[dl_harq_pid].active = true;
+            mac->nr_ue_emul_l1.harq[dl_harq_pid].active_dl_harq_sfn = frame;
+            mac->nr_ue_emul_l1.harq[dl_harq_pid].active_dl_harq_slot = slot;
+          }
 
           if (current_harq->dai > NR_DL_MAX_DAI) {
             LOG_E(MAC,"PUCCH Downlink DAI has an invalid value : at line %d in function %s of file %s \n", LINE_FILE , __func__, FILE_NAME);
@@ -2092,6 +2137,7 @@ uint8_t get_downlink_ack(NR_UE_MAC_INST_t *mac,
               pucch->is_common = current_harq->is_common;
               current_harq->active = false;
               current_harq->ack_received = false;
+	      LOG_D(PHY,"%4d.%2d Sent %d ack on harq pid %d\n", frame, slot, current_harq->ack, dl_harq_pid);
             }
           }
         }
@@ -3325,10 +3371,6 @@ void nr_ue_process_mac_pdu(nr_downlink_indication_t *dl_info,
                            NR_UL_TIME_ALIGNMENT_t *ul_time_alignment,
                            int pdu_id){
 
-  uint8_t rx_lcid;
-  uint16_t mac_ce_len;
-  uint16_t mac_subheader_len;
-  uint16_t mac_sdu_len;
   module_id_t module_idP = dl_info->module_id;
   frame_t frameP         = dl_info->frame;
   int slot               = dl_info->slot;
@@ -3347,139 +3389,100 @@ void nr_ue_process_mac_pdu(nr_downlink_indication_t *dl_info,
   LOG_D(MAC, "In %s [%d.%d]: processing PDU %d (with length %d) of %d total number of PDUs...\n", __FUNCTION__, frameP, slot, pdu_id, pdu_len, dl_info->rx_ind->number_pdus);
 
   while (!done && pdu_len > 0){
-    mac_ce_len = 0x0000;
-    mac_subheader_len = 0x0001; //  default to fixed-length subheader = 1-oct
-    mac_sdu_len = 0x0000;
-    rx_lcid = ((NR_MAC_SUBHEADER_FIXED *)pduP)->LCID;
+    uint16_t mac_len = 0x0000;
+    uint16_t mac_subheader_len = 0x0001; //  default to fixed-length subheader = 1-oct
+    uint8_t rx_lcid = ((NR_MAC_SUBHEADER_FIXED *)pduP)->LCID;
 
     LOG_D(MAC, "[UE] LCID %d, PDU length %d\n", rx_lcid, pdu_len);
+    bool ret;
     switch(rx_lcid){
       //  MAC CE
       case DL_SCH_LCID_CCCH:
         //  MSG4 RRC Setup 38.331
         //  variable length
-        if(((NR_MAC_SUBHEADER_SHORT *)pduP)->F){
-          mac_sdu_len = ((uint16_t)(((NR_MAC_SUBHEADER_LONG *) pduP)->L1 & 0x7f) << 8)
-                        | ((uint16_t)((NR_MAC_SUBHEADER_LONG *) pduP)->L2 & 0xff);
-          mac_subheader_len = 3;
-        } else {
-          mac_sdu_len = ((NR_MAC_SUBHEADER_SHORT *) pduP)->L;
-          mac_subheader_len = 2;
-        }
-
-        AssertFatal(pdu_len > mac_sdu_len, "The mac_sdu_len (%d) has an invalid size. PDU len = %d! \n",
-                    mac_sdu_len, pdu_len);
+        ret=get_mac_len(pduP, pdu_len, &mac_len, &mac_subheader_len);
+        AssertFatal(ret, "The mac_len (%d) has an invalid size. PDU len = %d! \n",
+                    mac_len, pdu_len);
 
         // Check if it is a valid CCCH message, we get all 00's messages very often
         int i = 0;
-        for(i=0; i<(mac_subheader_len+mac_sdu_len); i++) {
+        for(i=0; i<(mac_subheader_len+mac_len); i++) {
           if(pduP[i] != 0) {
             break;
           }
         }
-        if (i == (mac_subheader_len+mac_sdu_len)) {
+        if (i == (mac_subheader_len+mac_len)) {
           LOG_D(NR_MAC, "%s() Invalid CCCH message!, pdu_len: %d\n", __func__, pdu_len);
           done = 1;
           break;
         }
 
-        if ( mac_sdu_len > 0 ) {
-          LOG_D(NR_MAC,"DL_SCH_LCID_CCCH (e.g. RRCSetup) with payload len %d\n", mac_sdu_len);
+        if ( mac_len > 0 ) {
+          LOG_D(NR_MAC,"DL_SCH_LCID_CCCH (e.g. RRCSetup) with payload len %d\n", mac_len);
           for (int i = 0; i < mac_subheader_len; i++) {
             LOG_D(NR_MAC, "MAC header %d: 0x%x\n", i, pduP[i]);
           }
-          for (int i = 0; i < mac_sdu_len; i++) {
+          for (int i = 0; i < mac_len; i++) {
             LOG_D(NR_MAC, "%d: 0x%x\n", i, pduP[mac_subheader_len + i]);
           }
-          nr_mac_rrc_data_ind_ue(module_idP, CC_id, gNB_index, frameP, 0, mac->crnti, CCCH, pduP+mac_subheader_len, mac_sdu_len);
+          nr_mac_rrc_data_ind_ue(module_idP, CC_id, gNB_index, frameP, 0, mac->crnti, CCCH, pduP+mac_subheader_len, mac_len);
         }
         break;
       case DL_SCH_LCID_TCI_STATE_ACT_UE_SPEC_PDSCH:
-
-        //  38.321 Ch6.1.3.14
-        //  varialbe length
-        mac_ce_len |= (uint16_t)((NR_MAC_SUBHEADER_SHORT *)pduP)->L;
-        mac_subheader_len = 2;
-        if(((NR_MAC_SUBHEADER_SHORT *)pduP)->F){
-          mac_ce_len |= (uint16_t)(((NR_MAC_SUBHEADER_LONG *)pduP)->L2)<<8;
-          mac_subheader_len = 3;
-        }
-        break;
       case DL_SCH_LCID_APERIODIC_CSI_TRI_STATE_SUBSEL:
-        //  38.321 Ch6.1.3.13
-        //  varialbe length
-        mac_ce_len |= (uint16_t)((NR_MAC_SUBHEADER_SHORT *)pduP)->L;
-        mac_subheader_len = 2;
-        if(((NR_MAC_SUBHEADER_SHORT *)pduP)->F){
-          mac_ce_len |= (uint16_t)(((NR_MAC_SUBHEADER_LONG *)pduP)->L2)<<8;
-          mac_subheader_len = 3;
-        }
-        break;
       case DL_SCH_LCID_SP_CSI_RS_CSI_IM_RES_SET_ACT:
-        //  38.321 Ch6.1.3.12
-        //  varialbe length
-        mac_ce_len |= (uint16_t)((NR_MAC_SUBHEADER_SHORT *)pduP)->L;
-        mac_subheader_len = 2;
-        if(((NR_MAC_SUBHEADER_SHORT *)pduP)->F){
-          mac_ce_len |= (uint16_t)(((NR_MAC_SUBHEADER_LONG *)pduP)->L2)<<8;
-          mac_subheader_len = 3;
-        }
-        break;
       case DL_SCH_LCID_SP_SRS_ACTIVATION:
-        //  38.321 Ch6.1.3.17
+
+        //  38.321 Ch6.1.3.14
         //  varialbe length
-        mac_ce_len |= (uint16_t)((NR_MAC_SUBHEADER_SHORT *)pduP)->L;
-        mac_subheader_len = 2;
-        if(((NR_MAC_SUBHEADER_SHORT *)pduP)->F){
-          mac_ce_len |= (uint16_t)(((NR_MAC_SUBHEADER_LONG *)pduP)->L2)<<8;
-          mac_subheader_len = 3;
-        }
+        get_mac_len(pduP, pdu_len, &mac_len, &mac_subheader_len);
         break;
+
       case DL_SCH_LCID_RECOMMENDED_BITRATE:
         //  38.321 Ch6.1.3.20
-        mac_ce_len = 2;
+        mac_len = 2;
         break;
       case DL_SCH_LCID_SP_ZP_CSI_RS_RES_SET_ACT:
         //  38.321 Ch6.1.3.19
-        mac_ce_len = 2;
+        mac_len = 2;
         break;
       case DL_SCH_LCID_PUCCH_SPATIAL_RELATION_ACT:
         //  38.321 Ch6.1.3.18
-        mac_ce_len = 3;
+        mac_len = 3;
         break;
       case DL_SCH_LCID_SP_CSI_REP_PUCCH_ACT:
         //  38.321 Ch6.1.3.16
-        mac_ce_len = 2;
+        mac_len = 2;
         break;
       case DL_SCH_LCID_TCI_STATE_IND_UE_SPEC_PDCCH:
         //  38.321 Ch6.1.3.15
-        mac_ce_len = 2;
+        mac_len = 2;
         break;
       case DL_SCH_LCID_DUPLICATION_ACT:
         //  38.321 Ch6.1.3.11
-        mac_ce_len = 1;
+        mac_len = 1;
         break;
       case DL_SCH_LCID_SCell_ACT_4_OCT:
         //  38.321 Ch6.1.3.10
-        mac_ce_len = 4;
+        mac_len = 4;
         break;
       case DL_SCH_LCID_SCell_ACT_1_OCT:
         //  38.321 Ch6.1.3.10
-        mac_ce_len = 1;
+        mac_len = 1;
         break;
       case DL_SCH_LCID_L_DRX:
         //  38.321 Ch6.1.3.6
         //  fixed length but not yet specify.
-        mac_ce_len = 0;
+        mac_len = 0;
         break;
       case DL_SCH_LCID_DRX:
         //  38.321 Ch6.1.3.5
         //  fixed length but not yet specify.
-        mac_ce_len = 0;
+        mac_len = 0;
         break;
       case DL_SCH_LCID_TA_COMMAND:
         //  38.321 Ch6.1.3.4
-        mac_ce_len = 1;
+        mac_len = 1;
 
         /*uint8_t ta_command = ((NR_MAC_CE_TA *)pduP)[1].TA_COMMAND;
           uint8_t tag_id = ((NR_MAC_CE_TA *)pduP)[1].TAGID;*/
@@ -3501,14 +3504,14 @@ void nr_ue_process_mac_pdu(nr_downlink_indication_t *dl_info,
         //  Clause 5.1.5 and 6.1.3.3 of 3GPP TS 38.321 version 16.2.1 Release 16
         // MAC Header: 1 byte (R/R/LCID)
         // MAC SDU: 6 bytes (UE Contention Resolution Identity)
-        mac_ce_len = 6;
+        mac_len = 6;
 
         if(ra->ra_state == WAIT_CONTENTION_RESOLUTION) {
           LOG_I(MAC, "[UE %d][RAPROC] Frame %d : received contention resolution identity: 0x%02x%02x%02x%02x%02x%02x Terminating RA procedure\n",
                 module_idP, frameP, pduP[1], pduP[2], pduP[3], pduP[4], pduP[5], pduP[6]);
 
           bool ra_success = true;
-          for(int i = 0; i<mac_ce_len; i++) {
+          for(int i = 0; i<mac_len; i++) {
             if(ra->cont_res_id[i] != pduP[i+1]) {
               ra_success = false;
               break;
@@ -3536,25 +3539,9 @@ void nr_ue_process_mac_pdu(nr_downlink_indication_t *dl_info,
         //  check if LCID is valid at current time.
       default:
             {
-                //  check if LCID is valid at current time.
-                if (pdu_len < sizeof(NR_MAC_SUBHEADER_SHORT))
-                  return;
-                NR_MAC_SUBHEADER_SHORT *shs = (NR_MAC_SUBHEADER_SHORT *)pduP;
-                if (shs->F) {
-                    //mac_sdu_len |= (uint16_t)(((NR_MAC_SUBHEADER_LONG *)pduP)->L2)<<8;
-                    mac_subheader_len = 3;
-                    if (pdu_len < sizeof(NR_MAC_SUBHEADER_LONG))
-                      return;
-                    NR_MAC_SUBHEADER_LONG *shl = (NR_MAC_SUBHEADER_LONG *)pduP;
-                    mac_sdu_len = ((uint16_t)(shl->L1 & 0x7f) << 8) | (uint16_t)(shl->L2 & 0xff);
-                } else {
-                  if (pdu_len < sizeof(NR_MAC_SUBHEADER_SHORT))
-                    return;
-                  mac_sdu_len = (uint16_t)((NR_MAC_SUBHEADER_SHORT *)pduP)->L;
-                  mac_subheader_len = 2;
-                }
-
-                LOG_D(NR_MAC, "[UE %d] Frame %d : DLSCH -> DL-DTCH %d (gNB %d, %d bytes)\n", module_idP, frameP, rx_lcid, gNB_index, mac_sdu_len);
+	      if (!get_mac_len(pduP, pdu_len, &mac_len, &mac_subheader_len))
+		    return;
+                LOG_D(NR_MAC, "[UE %d] %4d.%2d : DLSCH -> DL-DTCH %d (gNB %d, %d bytes)\n", module_idP, frameP, slot, rx_lcid, gNB_index, mac_len);
 
                 #if defined(ENABLE_MAC_PAYLOAD_DEBUG)
                     LOG_T(MAC, "[UE %d] First 32 bytes of DLSCH : \n", module_idP);
@@ -3575,7 +3562,7 @@ void nr_ue_process_mac_pdu(nr_downlink_indication_t *dl_info,
                                 MBMS_FLAG_NO,
                                 rx_lcid,
                                 (char *) (pduP + mac_subheader_len),
-                                mac_sdu_len,
+                                mac_len,
                                 1,
                                 NULL);
                 } else {
@@ -3586,8 +3573,8 @@ void nr_ue_process_mac_pdu(nr_downlink_indication_t *dl_info,
             break;
             }
       }
-      pduP += ( mac_subheader_len + mac_ce_len + mac_sdu_len );
-      pdu_len -= ( mac_subheader_len + mac_ce_len + mac_sdu_len );
+      pduP += ( mac_subheader_len + mac_len );
+      pdu_len -= ( mac_subheader_len + mac_len );
       if (pdu_len < 0)
         LOG_E(MAC, "[UE %d][%d.%d] nr_ue_process_mac_pdu, residual mac pdu length %d < 0!\n", module_idP, frameP, slot, pdu_len);
     }
diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c
index bc9895ac2e2ccd50d40d0856157150640b96edb5..0afad893d750a4cc7a2c05ecf43ca9ba2e58004d 100644
--- a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c
+++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c
@@ -93,7 +93,8 @@ void fill_scheduled_response(nr_scheduled_response_t *scheduled_response,
                              int cc_id,
                              frame_t frame,
                              int slot,
-                             int thread_id){
+                             int thread_id,
+                             void *phy_data){
 
   scheduled_response->dl_config  = dl_config;
   scheduled_response->ul_config  = ul_config;
@@ -103,6 +104,7 @@ void fill_scheduled_response(nr_scheduled_response_t *scheduled_response,
   scheduled_response->frame      = frame;
   scheduled_response->slot       = slot;
   scheduled_response->thread_id  = thread_id;
+  scheduled_response->phy_data   = phy_data;
 
 }
 
@@ -734,6 +736,11 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac,
                          ? pusch_Config->dmrs_UplinkForPUSCH_MappingTypeA->choice.setup : pusch_Config->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup;
     }
 
+    pusch_config_pdu->scid = 0;
+    pusch_config_pdu->ul_dmrs_scrambling_id = mac->physCellId;
+    if(*dci_format == NR_UL_DCI_FORMAT_0_1)
+      pusch_config_pdu->scid = dci->dmrs_sequence_initialization.val;
+
     /* TRANSFORM PRECODING ------------------------------------------------------------------------------------------*/
 
     if (pusch_config_pdu->transform_precoding == NR_PUSCH_Config__transformPrecoder_enabled) {
@@ -759,6 +766,14 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac,
       LOG_D(NR_MAC,"TRANSFORM PRECODING IS ENABLED. CDM groups: %d, U: %d \n", pusch_config_pdu->num_dmrs_cdm_grps_no_data,
                 pusch_config_pdu->dfts_ofdm.low_papr_group_number);
     }
+    else {
+      if (pusch_config_pdu->scid == 0 &&
+          NR_DMRS_ulconfig->transformPrecodingDisabled->scramblingID0)
+        pusch_config_pdu->ul_dmrs_scrambling_id = *NR_DMRS_ulconfig->transformPrecodingDisabled->scramblingID0;
+      if (pusch_config_pdu->scid == 1 &&
+          NR_DMRS_ulconfig->transformPrecodingDisabled->scramblingID1)
+        pusch_config_pdu->ul_dmrs_scrambling_id = *NR_DMRS_ulconfig->transformPrecodingDisabled->scramblingID1;
+    }
 
     /* TRANSFORM PRECODING --------------------------------------------------------------------------------------------------------*/
 
@@ -1059,7 +1074,7 @@ NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_in
       nr_ue_dcireq(&dcireq); //to be replaced with function pointer later
       mac->dl_config_request = dcireq.dl_config_req;
 
-      fill_scheduled_response(&scheduled_response, &dcireq.dl_config_req, NULL, NULL, mod_id, cc_id, rx_frame, rx_slot, dl_info->thread_id);
+      fill_scheduled_response(&scheduled_response, &dcireq.dl_config_req, NULL, NULL, mod_id, cc_id, rx_frame, rx_slot, dl_info->thread_id, dl_info->phy_data);
       if(mac->if_module != NULL && mac->if_module->scheduled_response != NULL)
         mac->if_module->scheduled_response(&scheduled_response);
     }
@@ -1075,10 +1090,14 @@ NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_in
         fill_dci_search_candidates(mac->ra.ss, rel15);
         dl_config->number_pdus = 1;
         LOG_D(MAC,"mac->cg %p: Calling fill_scheduled_response rnti %x, type0_pdcch, num_pdus %d\n",mac->cg,rel15->rnti,dl_config->number_pdus);
-        fill_scheduled_response(&scheduled_response, dl_config, NULL, NULL, mod_id, cc_id, rx_frame, rx_slot, dl_info->thread_id);
+        fill_scheduled_response(&scheduled_response, dl_config, NULL, NULL, mod_id, cc_id, rx_frame, rx_slot, dl_info->thread_id, dl_info->phy_data);
         if(mac->if_module != NULL && mac->if_module->scheduled_response != NULL)
           mac->if_module->scheduled_response(&scheduled_response);
       }
+      else
+      {
+        dl_config->number_pdus = 0;
+      }
     }
   } else if (ul_info) {
 
@@ -1180,7 +1199,7 @@ NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_in
         }
         pthread_mutex_unlock(&ul_config->mutex_ul_config); // avoid double lock
 
-        fill_scheduled_response(&scheduled_response, NULL, ul_config, &tx_req, mod_id, cc_id, frame_tx, slot_tx, ul_info->thread_id);
+        fill_scheduled_response(&scheduled_response, NULL, ul_config, &tx_req, mod_id, cc_id, frame_tx, slot_tx, ul_info->thread_id, NULL);
         if(mac->if_module != NULL && mac->if_module->scheduled_response != NULL){
           mac->if_module->scheduled_response(&scheduled_response);
         }
@@ -2251,26 +2270,27 @@ void nr_ue_pucch_scheduler(module_id_t module_idP, frame_t frameP, int slotP, in
   int O_CSI = 0;
   int N_UCI = 0;
 
-  PUCCH_sched_t *pucch = calloc(1,sizeof(*pucch));
-  pucch->resource_indicator = -1;
-  pucch->initial_pucch_id = -1;
+  PUCCH_sched_t pucch = {
+    .resource_indicator = -1,
+    .initial_pucch_id = -1
+  };
   uint16_t rnti = mac->crnti;  //FIXME not sure this is valid for all pucch instances
 
   // SR
-  if(trigger_periodic_scheduling_request(mac, pucch, frameP, slotP)) {
+  if (trigger_periodic_scheduling_request(mac, &pucch, frameP, slotP)) {
     O_SR = 1;
     /* sr_payload = 1 means that this is a positive SR, sr_payload = 0 means that it is a negative SR */
-    pucch->sr_payload = nr_ue_get_SR(module_idP,
+    pucch.sr_payload = nr_ue_get_SR(module_idP,
                                      frameP,
                                      slotP);
   }
 
   // CSI
   if (mac->ra.ra_state == RA_SUCCEEDED || get_softmodem_params()->phy_test == 1)
-    O_CSI = nr_get_csi_measurements(mac, frameP, slotP, pucch);
+    O_CSI = nr_get_csi_measurements(mac, frameP, slotP, &pucch);
 
   // ACKNACK
-  O_ACK = get_downlink_ack(mac, frameP, slotP, pucch);
+  O_ACK = get_downlink_ack(mac, frameP, slotP, &pucch);
 
   NR_BWP_Id_t bwp_id = mac->UL_BWP_Id;
   NR_PUCCH_Config_t *pucch_Config = NULL;
@@ -2300,37 +2320,41 @@ void nr_ue_pucch_scheduler(module_id_t module_idP, frame_t frameP, int slotP, in
       pucch_Config->format2 &&
       (pucch_Config->format2->choice.setup->simultaneousHARQ_ACK_CSI == NULL)) {
     O_CSI = 0;
-    pucch->csi_part1_payload = 0;
-    pucch->csi_part2_payload = 0;
+    pucch.csi_part1_payload = 0;
+    pucch.csi_part2_payload = 0;
   }
 
   N_UCI = O_SR + O_ACK + O_CSI;
+  mac->nr_ue_emul_l1.num_srs = O_SR;
+  mac->nr_ue_emul_l1.num_harqs = O_ACK;
+  mac->nr_ue_emul_l1.num_csi_reports = O_CSI;
 
   // do no transmit pucch if only SR scheduled and it is negative
-  if ((O_ACK + O_CSI) == 0 && pucch->sr_payload == 0)
+  if ((O_ACK + O_CSI) == 0 && pucch.sr_payload == 0)
     return;
 
   if (N_UCI > 0) {
     LOG_D(NR_MAC,"%d.%d configure pucch, O_SR %d, O_ACK %d, O_CSI %d\n",frameP,slotP,O_SR,O_ACK,O_CSI);
-    pucch->resource_set_id = find_pucch_resource_set(mac, O_ACK + O_CSI);
-    select_pucch_resource(mac, pucch);
+    pucch.resource_set_id = find_pucch_resource_set(mac, O_ACK + O_CSI);
+    select_pucch_resource(mac, &pucch);
     fapi_nr_ul_config_request_t *ul_config = get_ul_config_request(mac, slotP);
     pthread_mutex_lock(&ul_config->mutex_ul_config);
     AssertFatal(ul_config->number_pdus<FAPI_NR_UL_CONFIG_LIST_NUM, "ul_config->number_pdus %d out of bounds\n",ul_config->number_pdus);
     fapi_nr_ul_config_pucch_pdu *pucch_pdu = &ul_config->ul_config_list[ul_config->number_pdus].pucch_config_pdu;
 
     fill_ul_config(ul_config, frameP, slotP, FAPI_NR_UL_CONFIG_TYPE_PUCCH);
+    mac->nr_ue_emul_l1.active_uci_sfn_slot = NFAPI_SFNSLOT2HEX(frameP, slotP);
     pthread_mutex_unlock(&ul_config->mutex_ul_config);
 
     nr_ue_configure_pucch(mac,
                           slotP,
                           rnti,
-                          pucch,
+                          &pucch,
                           pucch_pdu,
                           O_SR, O_ACK, O_CSI);
-    LOG_D(NR_MAC,"Configuring pucch, is_common = %d\n",pucch->is_common);
+    LOG_D(NR_MAC, "Configuring pucch, is_common = %d\n", pucch.is_common);
     nr_scheduled_response_t scheduled_response;
-    fill_scheduled_response(&scheduled_response, NULL, ul_config, NULL, module_idP, 0 /*TBR fix*/, frameP, slotP, thread_id);
+    fill_scheduled_response(&scheduled_response, NULL, ul_config, NULL, module_idP, 0 /*TBR fix*/, frameP, slotP, thread_id, NULL);
     if(mac->if_module != NULL && mac->if_module->scheduled_response != NULL)
       mac->if_module->scheduled_response(&scheduled_response);
   }
@@ -2677,7 +2701,7 @@ void nr_ue_prach_scheduler(module_id_t module_idP, frame_t frameP, sub_frame_t s
         }
       } // if format1
 
-      fill_scheduled_response(&scheduled_response, NULL, ul_config, NULL, module_idP, 0 /*TBR fix*/, frameP, slotP, thread_id);
+      fill_scheduled_response(&scheduled_response, NULL, ul_config, NULL, module_idP, 0 /*TBR fix*/, frameP, slotP, thread_id, NULL);
       if(mac->if_module != NULL && mac->if_module->scheduled_response != NULL)
         mac->if_module->scheduled_response(&scheduled_response);
     } // is_nr_prach_slot
@@ -2692,7 +2716,8 @@ void nr_ue_sib1_scheduler(module_id_t module_idP,
                           uint8_t ssb_subcarrier_offset,
                           uint32_t ssb_index,
                           uint16_t ssb_start_subcarrier,
-                          frequency_range_t frequency_range) {
+                          frequency_range_t frequency_range,
+                          void *phy_data) {
 
   NR_UE_MAC_INST_t *mac = get_mac_inst(module_idP);
   nr_scheduled_response_t scheduled_response;
@@ -2740,7 +2765,7 @@ void nr_ue_sib1_scheduler(module_id_t module_idP,
     slot_s = mac->type0_PDCCH_CSS_config.n_c;
   }
   LOG_D(MAC,"Calling fill_scheduled_response, type0_pdcch, num_pdus %d\n",dl_config->number_pdus);
-  fill_scheduled_response(&scheduled_response, dl_config, NULL, NULL, module_idP, cc_id, frame_s, slot_s, 0); // TODO fix thread_id, for now assumed 0
+  fill_scheduled_response(&scheduled_response, dl_config, NULL, NULL, module_idP, cc_id, frame_s, slot_s, 0, phy_data); // TODO fix thread_id, for now assumed 0
 
   if (dl_config->number_pdus) {
     if(mac->if_module != NULL && mac->if_module->scheduled_response != NULL)
@@ -3118,8 +3143,7 @@ uint8_t nr_ue_get_sdu(module_id_t module_idP,
         header->R = 0;
         header->F = 1;
         header->LCID = lcid;
-        header->L1 = ((unsigned short) sdu_length >> 8) & 0x7f;
-        header->L2 = (unsigned short) sdu_length & 0xff;
+        header->L = htons(sdu_length);
 
         #ifdef ENABLE_MAC_PAYLOAD_DEBUG
         LOG_I(NR_MAC, "In %s: dumping MAC sub-header with length %d: \n", __FUNCTION__, sh_size);
diff --git a/openair2/LAYER2/NR_MAC_gNB/config.c b/openair2/LAYER2/NR_MAC_gNB/config.c
index 737c11601104e38b2230030c017b2e7bed31f125..3359486db9421b357a2520caaeaa111e6222198d 100644
--- a/openair2/LAYER2/NR_MAC_gNB/config.c
+++ b/openair2/LAYER2/NR_MAC_gNB/config.c
@@ -232,7 +232,7 @@ void config_common(int Mod_idP, int ssb_SubcarrierOffset, int pdsch_AntennaPorts
   uint32_t band = *scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0];
   frequency_range_t frequency_range = band<100?FR1:FR2;
 
-  lte_frame_type_t frame_type = get_frame_type(*scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0], *scc->ssbSubcarrierSpacing);
+  frame_type_t frame_type = get_frame_type(*scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0], *scc->ssbSubcarrierSpacing);
   RC.nrmac[Mod_idP]->common_channels[0].frame_type = frame_type;
 
   // Cell configuration
diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c
index f8baf7d63235fff50fdd48def7cee27c05a72828..9a651293b220ed38d05af42ca1d91d258ea1aaa6 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c
@@ -300,6 +300,8 @@ void schedule_nr_prach(module_id_t module_idP, frame_t frameP, sub_frame_t slotP
                               (RA_sfn_index + slot_index) * N_t_slot * fdm + td_index * fdm + fdm_index;
 
           if((prach_occasion_id < cc->total_prach_occasions) && (td_index == 0)){
+            AssertFatal(UL_tti_req->n_pdus < sizeof(UL_tti_req->pdus_list) / sizeof(UL_tti_req->pdus_list[0]),
+                        "Invalid UL_tti_req->n_pdus %d\n", UL_tti_req->n_pdus);
 
             UL_tti_req->pdus_list[UL_tti_req->n_pdus].pdu_type = NFAPI_NR_UL_CONFIG_PRACH_PDU_TYPE;
             UL_tti_req->pdus_list[UL_tti_req->n_pdus].pdu_size = sizeof(nfapi_nr_prach_pdu_t);
@@ -397,7 +399,7 @@ void schedule_nr_prach(module_id_t module_idP, frame_t frameP, sub_frame_t slotP
 void nr_schedule_msg2(uint16_t rach_frame, uint16_t rach_slot,
                       uint16_t *msg2_frame, uint16_t *msg2_slot,
                       NR_ServingCellConfigCommon_t *scc,
-                      lte_frame_type_t frame_type,
+                      frame_type_t frame_type,
                       uint16_t monitoring_slot_period,
                       uint16_t monitoring_offset,uint8_t beam_index,
                       uint8_t num_active_ssb,
@@ -523,7 +525,7 @@ void nr_initiate_ra_proc(module_id_t module_idP,
   gNB_MAC_INST *nr_mac = RC.nrmac[module_idP];
   NR_COMMON_channels_t *cc = &nr_mac->common_channels[CC_id];
   NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon;
-  lte_frame_type_t frame_type = cc->frame_type;
+  frame_type_t frame_type = cc->frame_type;
 
   uint8_t total_RApreambles = MAX_NUM_NR_PRACH_PREAMBLES;
   uint8_t  num_ssb_per_RO = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->present;
@@ -803,6 +805,9 @@ void nr_generate_Msg3_retransmission(module_id_t module_idP, int CC_id, frame_t
                 future_ul_tti_req->Slot,
                 sched_frame,
                 sched_slot);
+    AssertFatal(future_ul_tti_req->n_pdus <
+                sizeof(future_ul_tti_req->pdus_list) / sizeof(future_ul_tti_req->pdus_list[0]),
+                "Invalid future_ul_tti_req->n_pdus %d\n", future_ul_tti_req->n_pdus);
     future_ul_tti_req->pdus_list[future_ul_tti_req->n_pdus].pdu_type = NFAPI_NR_UL_CONFIG_PUSCH_PDU_TYPE;
     future_ul_tti_req->pdus_list[future_ul_tti_req->n_pdus].pdu_size = sizeof(nfapi_nr_pusch_pdu_t);
     nfapi_nr_pusch_pdu_t *pusch_pdu = &future_ul_tti_req->pdus_list[future_ul_tti_req->n_pdus].pusch_pdu;
@@ -928,7 +933,7 @@ void nr_get_Msg3alloc(module_id_t module_id,
 
   uint16_t msg3_nb_rb = 8; // sdu has 6 or 8 bytes
 
-  lte_frame_type_t frame_type = RC.nrmac[module_id]->common_channels->frame_type;
+  frame_type_t frame_type = RC.nrmac[module_id]->common_channels->frame_type;
 
   int mu = ubwp ?
     ubwp->bwp_Common->genericParameters.subcarrierSpacing :
@@ -1617,7 +1622,7 @@ void nr_generate_Msg4(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra
     harq->feedback_slot = pucch->ul_slot;
     harq->feedback_frame = pucch->frame;
 
-    uint8_t *buf = (uint8_t *) harq->tb;
+    uint8_t *buf = (uint8_t *) harq->transportBlock;
     // Bytes to be transmitted
     if (harq->round == 0) {
       if (ra->msg3_dcch_dtch) {
@@ -1865,11 +1870,11 @@ void nr_generate_Msg4(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra
     }
 
     T(T_GNB_MAC_DL_PDU_WITH_DATA, T_INT(module_idP), T_INT(CC_id), T_INT(ra->rnti),
-      T_INT(frameP), T_INT(slotP), T_INT(current_harq_pid), T_BUFFER(harq->tb, harq->tb_size));
+      T_INT(frameP), T_INT(slotP), T_INT(current_harq_pid), T_BUFFER(harq->transportBlock, harq->tb_size));
 
     // DL TX request
     nfapi_nr_pdu_t *tx_req = &nr_mac->TX_req[CC_id].pdu_list[nr_mac->TX_req[CC_id].Number_of_PDUs];
-    memcpy(tx_req->TLVs[0].value.direct, harq->tb, sizeof(uint8_t) * harq->tb_size);
+    memcpy(tx_req->TLVs[0].value.direct, harq->transportBlock, sizeof(uint8_t) * harq->tb_size);
     tx_req->PDU_length =  harq->tb_size;
     tx_req->PDU_index = pduindex;
     tx_req->num_TLV = 1;
diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c
index 8c9d7e8bc8527f124d762b628da24e93b532f812..4b654e2ad18fe9285a924237e2d985b06feca362 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c
@@ -621,6 +621,8 @@ void schedule_nr_sib1(module_id_t module_idP, frame_t frameP, sub_frame_t slotP)
                                1, &is_typeA,
                                &startSymbolIndex, &nrOfSymbols);
 
+      AssertFatal((startSymbolIndex+nrOfSymbols)<14,"SIB1 TDA %d would cause overlap with CSI-RS. Please select a different SIB1 TDA.\n",time_domain_allocation);
+
       int mappingtype = is_typeA? typeA: typeB;
       uint16_t dlDmrsSymbPos = fill_dmrs_mask(NULL, gNB_mac->common_channels->ServingCellConfigCommon->dmrs_TypeA_Position, nrOfSymbols, startSymbolIndex, mappingtype, 1);
 
diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c
index b70d569d47e50b4eb1b7f0965398f5a122173b33..45cf0d276bdf86b2e926dd66d552ded6fecfd3db 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c
@@ -53,39 +53,39 @@
 #define WORD 32
 //#define SIZE_OF_POINTER sizeof (void *)
 
-void calculate_preferred_dl_tda(module_id_t module_id, const NR_BWP_Downlink_t *bwp)
-{
+void calculate_preferred_dl_tda(module_id_t module_id, const NR_BWP_Downlink_t *bwp) {
   gNB_MAC_INST *nrmac = RC.nrmac[module_id];
   const int bwp_id = bwp ? bwp->bwp_Id : 0;
+
   if (nrmac->preferred_dl_tda[bwp_id])
     return;
 
   /* there is a mixed slot only when in TDD */
   NR_ServingCellConfigCommon_t *scc = nrmac->common_channels->ServingCellConfigCommon;
-  lte_frame_type_t frame_type = nrmac->common_channels->frame_type;
+  frame_type_t frame_type = nrmac->common_channels->frame_type;
   const int n = nr_slots_per_frame[*scc->ssbSubcarrierSpacing];
   const NR_TDD_UL_DL_Pattern_t *tdd =
-      scc->tdd_UL_DL_ConfigurationCommon ? &scc->tdd_UL_DL_ConfigurationCommon->pattern1 : NULL;
-
+    scc->tdd_UL_DL_ConfigurationCommon ? &scc->tdd_UL_DL_ConfigurationCommon->pattern1 : NULL;
   int symb_dlMixed = 0;
   int nr_mix_slots = 0;
   int nr_slots_period = n;
+
   if (tdd) {
     symb_dlMixed = (1 << tdd->nrofDownlinkSymbols) - 1;
     nr_mix_slots = tdd->nrofDownlinkSymbols != 0 || tdd->nrofUplinkSymbols != 0;
     nr_slots_period /= get_nb_periods_per_frame(tdd->dl_UL_TransmissionPeriodicity);
-  }
-  else
+  } else
     // if TDD configuration is not present and the band is not FDD, it means it is a dynamic TDD configuration
     AssertFatal(nrmac->common_channels->frame_type == FDD,"Dynamic TDD not handled yet\n");
 
   int target_ss;
+
   if (bwp) {
     target_ss = NR_SearchSpace__searchSpaceType_PR_ue_Specific;
-  }
-  else {
+  } else {
     target_ss = NR_SearchSpace__searchSpaceType_PR_common;
   }
+
   const NR_SIB1_t *sib1 = nrmac->common_channels[0].sib1 ? nrmac->common_channels[0].sib1->message.choice.c1->choice.systemInformationBlockType1 : NULL;
   NR_SearchSpace_t *search_space = get_searchspace(sib1,
                                                    scc,
@@ -113,9 +113,9 @@ void calculate_preferred_dl_tda(module_id_t module_id, const NR_BWP_Downlink_t *
   // here we assume that the coreset is scheduled every slot (which it
   // currently is) and starting at symbol 0
   AssertFatal((symb_coreset & symb_tda) == 0, "TDA index 0 for DL overlaps with CORESET\n");
-
   /* check that TDA index 1 fits into DL part of mixed slot, if it exists */
   int tdaMi = -1;
+
   if (frame_type == TDD && tdaList->list.count > 1) {
     const NR_PDSCH_TimeDomainResourceAllocation_t *tdaP_Mi = tdaList->list.array[1];
     AssertFatal(!tdaP_Mi->k0 || *tdaP_Mi->k0 == 0,
@@ -124,6 +124,7 @@ void calculate_preferred_dl_tda(module_id_t module_id, const NR_BWP_Downlink_t *
     int start, len;
     SLIV2SL(tdaP_Mi->startSymbolAndLength, &start, &len);
     const uint16_t symb_tda = ((1 << len) - 1) << start;
+
     // check whether coreset and TDA overlap: then, we cannot use it. Also,
     // check whether TDA is entirely within mixed slot DL. Note that
     // here we assume that the coreset is scheduled every slot (which it
@@ -143,10 +144,12 @@ void calculate_preferred_dl_tda(module_id_t module_id, const NR_BWP_Downlink_t *
 
   for (int i = 0; i < n; ++i) {
     nrmac->preferred_dl_tda[bwp_id][i] = -1;
+
     if (frame_type == FDD || i % nr_slots_period < tdd->nrofDownlinkSlots)
       nrmac->preferred_dl_tda[bwp_id][i] = 0;
     else if (nr_mix_slots && i % nr_slots_period == tdd->nrofDownlinkSlots)
       nrmac->preferred_dl_tda[bwp_id][i] = tdaMi;
+
     LOG_D(MAC, "slot %d preferred_dl_tda %d\n", i, nrmac->preferred_dl_tda[bwp_id][i]);
   }
 }
@@ -157,8 +160,7 @@ int nr_write_ce_dlsch_pdu(module_id_t module_idP,
                           const NR_UE_sched_ctrl_t *ue_sched_ctl,
                           unsigned char *mac_pdu,
                           unsigned char drx_cmd,
-                          unsigned char *ue_cont_res_id)
-{
+                          unsigned char *ue_cont_res_id) {
   gNB_MAC_INST *gNB = RC.nrmac[module_idP];
   NR_MAC_SUBHEADER_FIXED *mac_pdu_ptr = (NR_MAC_SUBHEADER_FIXED *) mac_pdu;
   uint8_t last_size = 0;
@@ -201,8 +203,6 @@ int nr_write_ce_dlsch_pdu(module_id_t module_idP,
     memcpy((void *) mac_pdu_ptr, (void *) ce_ptr, mac_ce_size);
     ce_ptr += mac_ce_size;
     mac_pdu_ptr += (unsigned char) mac_ce_size;
-
-
   }
 
   // Contention resolution fixed subheader and MAC CE
@@ -399,18 +399,18 @@ int nr_write_ce_dlsch_pdu(module_id_t module_idP,
 
 #define BLER_UPDATE_FRAME 10
 #define BLER_FILTER 0.9f
-int get_mcs_from_bler(module_id_t mod_id, int CC_id, frame_t frame, sub_frame_t slot, int UE_id, int mcs_table)
-{
+int get_mcs_from_bler(module_id_t mod_id, int CC_id, frame_t frame, sub_frame_t slot, int UE_id, int mcs_table) {
   gNB_MAC_INST *nrmac = RC.nrmac[mod_id];
   const NR_ServingCellConfigCommon_t *scc = nrmac->common_channels[CC_id].ServingCellConfigCommon;
   const int n = nr_slots_per_frame[*scc->ssbSubcarrierSpacing];
-
   int max_allowed_mcs = (mcs_table == 1) ? 27 : 28;
   int max_mcs = nrmac->dl_max_mcs;
+
   if (nrmac->dl_max_mcs>max_allowed_mcs)
     max_mcs = max_allowed_mcs;
 
   NR_DL_bler_stats_t *bler_stats = &nrmac->UE_info.UE_sched_ctrl[UE_id].dl_bler_stats;
+
   /* first call: everything is zero. Initialize to sensible default */
   if (bler_stats->last_frame_slot == 0 && bler_stats->mcs == 0) {
     bler_stats->last_frame_slot = frame * n + slot;
@@ -418,13 +418,16 @@ int get_mcs_from_bler(module_id_t mod_id, int CC_id, frame_t frame, sub_frame_t
     bler_stats->bler = (nrmac->dl_bler_target_lower + nrmac->dl_bler_target_upper) / 2;
     bler_stats->rd2_bler = nrmac->dl_rd2_bler_threshold;
   }
+
   const int now = frame * n + slot;
   int diff = now - bler_stats->last_frame_slot;
+
   if (diff < 0) // wrap around
     diff += 1024 * n;
 
   const uint8_t old_mcs = bler_stats->mcs;
   const NR_mac_stats_t *stats = &nrmac->UE_info.mac_stats[UE_id];
+
   // TODO put back this condition when relevant
   /*const int dret3x = stats->dlsch_rounds[3] - bler_stats->dlsch_rounds[3];
   if (dret3x > 0) {
@@ -447,8 +450,8 @@ int get_mcs_from_bler(module_id_t mod_id, int CC_id, frame_t frame, sub_frame_t
   const float rd2_bler_wnd = dtx > 0 ? (float) dretx2 / dtx : bler_stats->rd2_bler;
   bler_stats->bler = BLER_FILTER * bler_stats->bler + (1 - BLER_FILTER) * bler_window;
   bler_stats->rd2_bler = BLER_FILTER / 4 * bler_stats->rd2_bler + (1 - BLER_FILTER / 4) * rd2_bler_wnd;
-
   int new_mcs = old_mcs;
+
   // TODO put back this condition when relevant
   /* first ensure that number of 2nd retx is below threshold. If this is the
    * case, use 1st retx to adjust faster
@@ -459,9 +462,8 @@ int get_mcs_from_bler(module_id_t mod_id, int CC_id, frame_t frame, sub_frame_t
     new_mcs += 1;
   else if (bler_stats->bler > nrmac->dl_bler_target_upper && old_mcs > 6)
     new_mcs -= 1;
-  // else we are within threshold boundaries
-
 
+  // else we are within threshold boundaries
   bler_stats->last_frame_slot = now;
   bler_stats->mcs = new_mcs;
   memcpy(bler_stats->dlsch_rounds, stats->dlsch_rounds, sizeof(stats->dlsch_rounds));
@@ -473,11 +475,9 @@ int get_mcs_from_bler(module_id_t mod_id, int CC_id, frame_t frame, sub_frame_t
 void nr_store_dlsch_buffer(module_id_t module_id,
                            frame_t frame,
                            sub_frame_t slot) {
-
   NR_UE_info_t *UE_info = &RC.nrmac[module_id]->UE_info;
 
   for (int UE_id = UE_info->list.head; UE_id >= 0; UE_id = UE_info->list.next[UE_id]) {
-
     NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
     sched_ctrl->num_total_bytes = 0;
     sched_ctrl->dl_pdus_total = 0;
@@ -485,21 +485,20 @@ void nr_store_dlsch_buffer(module_id_t module_id,
     /* loop over all activated logical channels */
     // Note: DL_SCH_LCID_DCCH, DL_SCH_LCID_DCCH1, DL_SCH_LCID_DTCH
     for (int i = 0; i < sched_ctrl->dl_lc_num; ++i) {
-
       const int lcid = sched_ctrl->dl_lc_ids[i];
       const uint16_t rnti = UE_info->rnti[UE_id];
       LOG_D(NR_MAC, "In %s: UE %d/%x: LCID %d\n", __FUNCTION__, UE_id, rnti, lcid);
       start_meas(&RC.nrmac[module_id]->rlc_status_ind);
       sched_ctrl->rlc_status[lcid] = mac_rlc_status_ind(module_id,
-                                                        rnti,
-                                                        module_id,
-                                                          frame,
-                                                        slot,
-                                                        ENB_FLAG_YES,
-                                                        MBMS_FLAG_NO,
-                                                        lcid,
-                                                        0,
-                                                        0);
+                                     rnti,
+                                     module_id,
+                                     frame,
+                                     slot,
+                                     ENB_FLAG_YES,
+                                     MBMS_FLAG_NO,
+                                     lcid,
+                                     0,
+                                     0);
       stop_meas(&RC.nrmac[module_id]->rlc_status_ind);
 
       if (sched_ctrl->rlc_status[lcid].bytes_in_buffer == 0)
@@ -531,6 +530,7 @@ bool allocate_dl_retransmission(module_id_t module_id,
                                 int UE_id,
                                 int current_harq_pid) {
 
+
   gNB_MAC_INST *nr_mac = RC.nrmac[module_id];
   const NR_ServingCellConfigCommon_t *scc = nr_mac->common_channels->ServingCellConfigCommon;
   NR_UE_info_t *UE_info = &nr_mac->UE_info;
@@ -558,30 +558,34 @@ bool allocate_dl_retransmission(module_id_t module_id,
 
   const int coresetid = (sched_ctrl->active_bwp||bwpd) ? sched_ctrl->coreset->controlResourceSetId : RC.nrmac[module_id]->sched_ctrlCommon->coreset->controlResourceSetId;
   const uint16_t bwpSize = coresetid == 0 ? RC.nrmac[module_id]->cset0_bwp_size : NRRIV2BW(genericParameters->locationAndBandwidth, MAX_BWP_SIZE);
-  int rbStart = 0; // start wrt BWPstart
 
+  int rbStart = 0; // start wrt BWPstart
   NR_pdsch_semi_static_t *ps = &sched_ctrl->pdsch_semi_static;
-
   int rbSize = 0;
   const int tda = RC.nrmac[module_id]->preferred_dl_tda[sched_ctrl->active_bwp ? sched_ctrl->active_bwp->bwp_Id : 0][slot];
   AssertFatal(tda>=0,"Unable to find PDSCH time domain allocation in list\n");
+
   if (tda == retInfo->time_domain_allocation) {
     /* Check that there are enough resources for retransmission */
     while (rbSize < retInfo->rbSize) {
       rbStart += rbSize; /* last iteration rbSize was not enough, skip it */
       rbSize = 0;
+
       while (rbStart < bwpSize &&
              !(rballoc_mask[rbStart]&SL_to_bitmap(ps->startSymbolIndex, ps->nrOfSymbols)))
         rbStart++;
+
       if (rbStart >= bwpSize) {
         LOG_D(NR_MAC, "cannot allocate retransmission for UE %d/RNTI %04x: no resources\n", UE_id, UE_info->rnti[UE_id]);
         return false;
       }
+
       while (rbStart + rbSize < bwpSize &&
              (rballoc_mask[rbStart + rbSize]&SL_to_bitmap(ps->startSymbolIndex, ps->nrOfSymbols)) &&
              rbSize < retInfo->rbSize)
         rbSize++;
     }
+
     /* check whether we need to switch the TDA allocation since the last
      * (re-)transmission */
     if (ps->time_domain_allocation != tda || sched_ctrl->update_pdsch_ps) {
@@ -599,8 +603,8 @@ bool allocate_dl_retransmission(module_id_t module_id,
   } else {
     /* the retransmission will use a different time domain allocation, check
      * that we have enough resources */
-
     NR_pdsch_semi_static_t temp_ps = *ps;
+
     nr_set_pdsch_semi_static(sib1,
                              scc,
                              UE_info->CellGroup[UE_id],
@@ -613,6 +617,7 @@ bool allocate_dl_retransmission(module_id_t module_id,
     while (rbStart < bwpSize &&
            !(rballoc_mask[rbStart]&SL_to_bitmap(temp_ps.startSymbolIndex, temp_ps.nrOfSymbols)))
       rbStart++;
+
     while (rbStart + rbSize < bwpSize &&
            (rballoc_mask[rbStart + rbSize]&SL_to_bitmap(temp_ps.startSymbolIndex, temp_ps.nrOfSymbols)))
       rbSize++;
@@ -629,10 +634,12 @@ bool allocate_dl_retransmission(module_id_t module_id,
                                  rbSize,
                                  &new_tbs,
                                  &new_rbSize);
+
     if (!success || new_tbs != retInfo->tb_size) {
-      LOG_D(MAC, "%s(): new TBsize %d of new TDA does not match old TBS %d\n", __func__, new_tbs, retInfo->tb_size);
+      LOG_D(MAC, "new TBsize %d of new TDA does not match old TBS %d\n", new_tbs, retInfo->tb_size);
       return false; /* the maximum TBsize we might have is smaller than what we need */
     }
+
     /* we can allocate it. Overwrite the time_domain_allocation, the number
      * of RBs, and the new TB size. The rest is done below */
     retInfo->tb_size = new_tbs;
@@ -645,12 +652,14 @@ bool allocate_dl_retransmission(module_id_t module_id,
   const int cid = sched_ctrl->coreset->controlResourceSetId;
   const uint16_t Y = get_Y(cid%3, slot, UE_info->rnti[UE_id]);
   uint8_t nr_of_candidates;
+
   for (int i=0; i<5; i++) {
     // for now taking the lowest value among the available aggregation levels
     find_aggregation_candidates(&sched_ctrl->aggregation_level,
                                 &nr_of_candidates,
                                 sched_ctrl->search_space,
                                 1<<i);
+
     if(nr_of_candidates>0) break;
   }
 
@@ -670,12 +679,12 @@ bool allocate_dl_retransmission(module_id_t module_id,
 
   /* Find PUCCH occasion: if it fails, undo CCE allocation (undoing PUCCH
    * allocation after CCE alloc fail would be more complex) */
+
   int r_pucch = nr_get_pucch_resource(sched_ctrl->coreset, sched_ctrl->active_ubwp, ubwpd, CCEIndex);
   const int alloc = nr_acknack_scheduling(module_id, UE_id, frame, slot, r_pucch, 0);
   if (alloc<0) {
     LOG_D(MAC,
-          "%s(): could not find PUCCH for UE %d/%04x@%d.%d\n",
-          __func__,
+          "could not find PUCCH for UE %d/%04x@%d.%d\n",
           UE_id,
           UE_info->rnti[UE_id],
           frame,
@@ -685,23 +694,21 @@ bool allocate_dl_retransmission(module_id_t module_id,
   }
 
   sched_ctrl->cce_index = CCEIndex;
-
   fill_pdcch_vrb_map(RC.nrmac[module_id],
                      /* CC_id = */ 0,
                      &sched_ctrl->sched_pdcch,
                      CCEIndex,
                      sched_ctrl->aggregation_level);
-
   /* just reuse from previous scheduling opportunity, set new start RB */
   sched_ctrl->sched_pdsch = *retInfo;
   sched_ctrl->sched_pdsch.rbStart = rbStart;
-
   sched_ctrl->sched_pdsch.pucch_allocation = alloc;
-
   /* retransmissions: directly allocate */
   *n_rb_sched -= sched_ctrl->sched_pdsch.rbSize;
+
   for (int rb = 0; rb < sched_ctrl->sched_pdsch.rbSize; rb++)
     rballoc_mask[rb + sched_ctrl->sched_pdsch.rbStart] ^= SL_to_bitmap(ps->startSymbolIndex, ps->nrOfSymbols);
+
   return true;
 }
 
@@ -715,7 +722,6 @@ void pf_dl(module_id_t module_id,
            int max_num_ue,
            int n_rb_sched,
            uint16_t *rballoc_mask) {
-
   gNB_MAC_INST *mac = RC.nrmac[module_id];
   NR_UE_info_t *UE_info = &mac->UE_info;
   NR_ServingCellConfigCommon_t *scc=mac->common_channels[0].ServingCellConfigCommon;
@@ -728,15 +734,16 @@ void pf_dl(module_id_t module_id,
   /* Loop UE_info->list to check retransmission */
   for (int UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) {
     if (UE_info->Msg4_ACKed[UE_id] != true) continue;
+
     NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
+
     if (sched_ctrl->ul_failure==1 && get_softmodem_params()->phy_test==0) continue;
+
     NR_sched_pdsch_t *sched_pdsch = &sched_ctrl->sched_pdsch;
     NR_pdsch_semi_static_t *ps = &sched_ctrl->pdsch_semi_static;
     /* get the PID of a HARQ process awaiting retrnasmission, or -1 otherwise */
     sched_pdsch->dl_harq_pid = sched_ctrl->retrans_dl_harq.head;
-
     layers[UE_id] = ps->nrOfLayers; // initialization of layers to the previous value in the strcuture
-
     /* Calculate Throughput */
     const float a = 0.0005f; // corresponds to 200ms window
     const uint32_t b = UE_info->mac_stats[UE_id].dlsch_current_bytes;
@@ -746,13 +753,16 @@ void pf_dl(module_id_t module_id,
     if (sched_pdsch->dl_harq_pid >= 0) {
       /* Allocate retransmission */
       bool r = allocate_dl_retransmission(
-          module_id, frame, slot, rballoc_mask, &n_rb_sched, UE_id, sched_pdsch->dl_harq_pid);
+                 module_id, frame, slot, rballoc_mask, &n_rb_sched, UE_id, sched_pdsch->dl_harq_pid);
+
       if (!r) {
         LOG_D(NR_MAC, "%4d.%2d retransmission can NOT be allocated\n", frame, slot);
         continue;
       }
+
       /* reduce max_num_ue once we are sure UE can be allocated, i.e., has CCE */
       max_num_ue--;
+
       if (max_num_ue < 0) return;
     } else {
       /* Check DL buffer and skip this UE if no bytes and no TA necessary */
@@ -782,18 +792,21 @@ void pf_dl(module_id_t module_id,
   }
 
   const int min_rbSize = 5;
+
   /* Loop UE_sched to find max coeff and allocate transmission */
   while (max_num_ue > 0 && n_rb_sched >= min_rbSize && UE_sched.head >= 0) {
-
     /* Find max coeff from UE_sched*/
     int *max = &UE_sched.head; /* assume head is max */
     int *p = &UE_sched.next[*max];
+
     while (*p >= 0) {
       /* if the current one has larger coeff, save for later */
       if (coeff_ue[*p] > coeff_ue[*max])
         max = p;
+
       p = &UE_sched.next[*p];
     }
+
     /* remove the max one: do not use remove_nr_list() it goes through the
      * whole list every time. Note that UE_sched.tail might not be set
      * correctly anymore */
@@ -803,6 +816,7 @@ void pf_dl(module_id_t module_id,
     *p = -1;
     NR_CellGroupConfig_t *cg = UE_info->CellGroup[UE_id];
 
+
     NR_BWP_DownlinkDedicated_t *bwpd =
         cg &&
         cg->spCellConfig &&
@@ -837,12 +851,14 @@ void pf_dl(module_id_t module_id,
     const int cid = sched_ctrl->coreset->controlResourceSetId;
     const uint16_t Y = get_Y(cid%3, slot, UE_info->rnti[UE_id]);
     uint8_t nr_of_candidates;
+
     for (int i=0; i<5; i++) {
       // for now taking the lowest value among the available aggregation levels
       find_aggregation_candidates(&sched_ctrl->aggregation_level,
                                   &nr_of_candidates,
                                   sched_ctrl->search_space,
                                   1<<i);
+
       if(nr_of_candidates>0) break;
     }
 
@@ -861,12 +877,13 @@ void pf_dl(module_id_t module_id,
 
     /* Find PUCCH occasion: if it fails, undo CCE allocation (undoing PUCCH
     * allocation after CCE alloc fail would be more complex) */
+
     int r_pucch = nr_get_pucch_resource(sched_ctrl->coreset, sched_ctrl->active_ubwp, ubwpd, CCEIndex);
     const int alloc = nr_acknack_scheduling(module_id, UE_id, frame, slot, r_pucch, 0);
+
     if (alloc<0) {
       LOG_D(NR_MAC,
-            "%s(): could not find PUCCH for UE %d/%04x@%d.%d\n",
-            __func__,
+            "could not find PUCCH for UE %d/%04x@%d.%d\n",
             UE_id,
             rnti,
             frame,
@@ -879,21 +896,18 @@ void pf_dl(module_id_t module_id,
      * and PUCCH */
     max_num_ue--;
     AssertFatal(max_num_ue >= 0, "Illegal max_num_ue %d\n", max_num_ue);
-
     sched_ctrl->cce_index = CCEIndex;
-
     fill_pdcch_vrb_map(mac,
                        /* CC_id = */ 0,
                        &sched_ctrl->sched_pdcch,
                        CCEIndex,
                        sched_ctrl->aggregation_level);
-
     /* reduce max_num_ue once we are sure UE can be allocated, i.e., has CCE */
     max_num_ue--;
+
     if (max_num_ue < 0) return;
 
     /* MCS has been set above */
-
     const int tda = RC.nrmac[module_id]->preferred_dl_tda[sched_ctrl->active_bwp ? sched_ctrl->active_bwp->bwp_Id : 0][slot];
     AssertFatal(tda>=0,"Unable to find PDSCH time domain allocation in list\n");
     NR_sched_pdsch_t *sched_pdsch = &sched_ctrl->sched_pdsch;
@@ -913,12 +927,14 @@ void pf_dl(module_id_t module_id,
     }
 
     const uint16_t slbitmap = SL_to_bitmap(ps->startSymbolIndex, ps->nrOfSymbols);
+
     // Freq-demain allocation
     while (rbStart < bwpSize &&
            !(rballoc_mask[rbStart]&slbitmap))
       rbStart++;
 
     uint16_t max_rbSize = 1;
+
     while (rbStart + max_rbSize < bwpSize &&
            (rballoc_mask[rbStart + max_rbSize]&slbitmap))
       max_rbSize++;
@@ -947,39 +963,41 @@ void pf_dl(module_id_t module_id,
     sched_pdsch->rbSize = rbSize;
     sched_pdsch->rbStart = rbStart;
     sched_pdsch->tb_size = TBS;
-
     /* transmissions: directly allocate */
     n_rb_sched -= sched_pdsch->rbSize;
+
     for (int rb = 0; rb < sched_pdsch->rbSize; rb++)
       rballoc_mask[rb + sched_pdsch->rbStart] ^= slbitmap;
   }
 }
 
-void nr_fr1_dlsch_preprocessor(module_id_t module_id, frame_t frame, sub_frame_t slot)
-{
+void nr_fr1_dlsch_preprocessor(module_id_t module_id, frame_t frame, sub_frame_t slot) {
   NR_UE_info_t *UE_info = &RC.nrmac[module_id]->UE_info;
+
   if (UE_info->num_UEs == 0)
     return;
 
   NR_ServingCellConfigCommon_t *scc = RC.nrmac[module_id]->common_channels[0].ServingCellConfigCommon;
   const int CC_id = 0;
-
   /* Get bwpSize and TDAfrom the first UE */
   /* This is temporary and it assumes all UEs have the same BWP and TDA*/
   int UE_id = UE_info->list.head;
   NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
   const int bwp_id = sched_ctrl->active_bwp ? sched_ctrl->active_bwp->bwp_Id : 0;
+
   if (!RC.nrmac[module_id]->preferred_dl_tda[bwp_id])
     return;
+
   const int tda = RC.nrmac[module_id]->preferred_dl_tda[bwp_id][slot];
   int startSymbolIndex, nrOfSymbols;
   const struct NR_PDSCH_TimeDomainResourceAllocationList *tdaList = sched_ctrl->active_bwp ?
-      sched_ctrl->active_bwp->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList :
-      scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList;
+        sched_ctrl->active_bwp->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList :
+        scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList;
   AssertFatal(tda < tdaList->list.count, "time_domain_allocation %d>=%d\n", tda, tdaList->list.count);
   const int startSymbolAndLength = tdaList->list.array[tda]->startSymbolAndLength;
   SLIV2SL(startSymbolAndLength, &startSymbolIndex, &nrOfSymbols);
 
+
   const NR_SIB1_t *sib1 = RC.nrmac[module_id]->common_channels[0].sib1 ? RC.nrmac[module_id]->common_channels[0].sib1->message.choice.c1->choice.systemInformationBlockType1 : NULL;
   NR_BWP_t *genericParameters = get_dl_bwp_genericParameters(sched_ctrl->active_bwp,
                                                              RC.nrmac[module_id]->common_channels[0].ServingCellConfigCommon,
@@ -1000,19 +1018,20 @@ void nr_fr1_dlsch_preprocessor(module_id_t module_id, frame_t frame, sub_frame_t
   uint16_t *vrb_map = RC.nrmac[module_id]->common_channels[CC_id].vrb_map;
   uint16_t rballoc_mask[bwpSize];
   int n_rb_sched = 0;
+
   for (int i = 0; i < bwpSize; i++) {
     // calculate mask: init with "NOT" vrb_map:
     // if any RB in vrb_map is blocked (1), the current RBG will be 0
     rballoc_mask[i] = (~vrb_map[i+BWPStart])&0x3fff; //bitwise not and 14 symbols
+
     // if all the pdsch symbols are free
     if((rballoc_mask[i]&slbitmap) ==
-       slbitmap)
+        slbitmap)
       n_rb_sched++;
   }
 
   /* Retrieve amount of data to send for this UE */
   nr_store_dlsch_buffer(module_id, frame, slot);
-
   /* proportional fair scheduling algorithm */
   pf_dl(module_id,
         frame,
@@ -1023,8 +1042,7 @@ void nr_fr1_dlsch_preprocessor(module_id_t module_id, frame_t frame, sub_frame_t
         rballoc_mask);
 }
 
-nr_pp_impl_dl nr_init_fr1_dlsch_preprocessor(module_id_t module_id, int CC_id)
-{
+nr_pp_impl_dl nr_init_fr1_dlsch_preprocessor(module_id_t module_id, int CC_id) {
   /* in the PF algorithm, we have to use the TBsize to compute the coefficient.
    * This would include the number of DMRS symbols, which in turn depends on
    * the time domain allocation. In case we are in a mixed slot, we do not want
@@ -1034,16 +1052,17 @@ nr_pp_impl_dl nr_init_fr1_dlsch_preprocessor(module_id_t module_id, int CC_id)
     for (int mcs = 0; mcs < 29; ++mcs) {
       if (mcs > 27 && mcsTableIdx == 1)
         continue;
+
       const uint8_t Qm = nr_get_Qm_dl(mcs, mcsTableIdx);
       const uint16_t R = nr_get_code_rate_dl(mcs, mcsTableIdx);
       pf_tbs[mcsTableIdx][mcs] = nr_compute_tbs(Qm,
-                                                R,
-                                                1, /* rbSize */
-                                                10, /* hypothetical number of slots */
-                                                0, /* N_PRB_DMRS * N_DMRS_SLOT */
-                                                0 /* N_PRB_oh, 0 for initialBWP */,
-                                                0 /* tb_scaling */,
-                                                1 /* nrOfLayers */)
+                                 R,
+                                 1, /* rbSize */
+                                 10, /* hypothetical number of slots */
+                                 0, /* N_PRB_DMRS * N_DMRS_SLOT */
+                                 0 /* N_PRB_oh, 0 for initialBWP */,
+                                 0 /* tb_scaling */,
+                                 1 /* nrOfLayers */)
                                  >> 3;
     }
   }
@@ -1055,22 +1074,23 @@ void nr_schedule_ue_spec(module_id_t module_id,
                          frame_t frame,
                          sub_frame_t slot) {
   gNB_MAC_INST *gNB_mac = RC.nrmac[module_id];
+
   if (!is_xlsch_in_slot(gNB_mac->dlsch_slot_bitmap[slot / 64], slot))
     return;
 
   /* PREPROCESSOR */
   gNB_mac->pre_processor_dl(module_id, frame, slot);
-
   const int CC_id = 0;
   NR_ServingCellConfigCommon_t *scc = gNB_mac->common_channels[CC_id].ServingCellConfigCommon;
   NR_UE_info_t *UE_info = &gNB_mac->UE_info;
-
   nfapi_nr_dl_tti_request_body_t *dl_req = &gNB_mac->DL_req[CC_id].dl_tti_request_body;
-
   NR_list_t *UE_list = &UE_info->list;
+
   for (int UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) {
     NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
+
     if (sched_ctrl->ul_failure==1 && get_softmodem_params()->phy_test==0) continue;
+
     NR_sched_pdsch_t *sched_pdsch = &sched_ctrl->sched_pdsch;
     UE_info->mac_stats[UE_id].dlsch_current_bytes = 0;
     NR_CellGroupConfig_t *cg = UE_info->CellGroup[UE_id];
@@ -1085,7 +1105,7 @@ void nr_schedule_ue_spec(module_id_t module_id,
      * Possible improvement: take the periodicity from input file.
      * If such UE is not scheduled now, it will be by the preprocessor later.
      * If we add the CE, ta_apply will be reset */
-    if (frame == (sched_ctrl->ta_frame + 10) % 1024){
+    if (frame == (sched_ctrl->ta_frame + 10) % 1024) {
       sched_ctrl->ta_apply = true; /* the timer is reset once TA CE is scheduled */
       LOG_D(NR_MAC, "[UE %d][%d.%d] UL timing alignment procedures: setting flag for Timing Advance command\n", UE_id, frame, slot);
     }
@@ -1094,19 +1114,17 @@ void nr_schedule_ue_spec(module_id_t module_id,
       continue;
 
     const rnti_t rnti = UE_info->rnti[UE_id];
-
     /* pre-computed PDSCH values that only change if time domain
      * allocation/DMRS parameters change. Updated in the preprocessor through
      * nr_set_pdsch_semi_static() */
     NR_pdsch_semi_static_t *ps = &sched_ctrl->pdsch_semi_static;
-
     /* POST processing */
     const uint8_t nrOfLayers = ps->nrOfLayers;
     const uint16_t R = sched_pdsch->R;
     const uint8_t Qm = sched_pdsch->Qm;
     const uint32_t TBS = sched_pdsch->tb_size;
-
     int8_t current_harq_pid = sched_pdsch->dl_harq_pid;
+
     if (current_harq_pid < 0) {
       /* PP has not selected a specific HARQ Process, get a new one */
       current_harq_pid = sched_ctrl->available_dl_harq.head;
@@ -1124,6 +1142,7 @@ void nr_schedule_ue_spec(module_id_t module_id,
       else
         remove_nr_list(&sched_ctrl->retrans_dl_harq, current_harq_pid);
     }
+
     NR_UE_harq_t *harq = &sched_ctrl->harq_processes[current_harq_pid];
     DevAssert(!harq->is_waiting);
     add_tail_nr_list(&sched_ctrl->feedback_dl_harq, current_harq_pid);
@@ -1132,8 +1151,8 @@ void nr_schedule_ue_spec(module_id_t module_id,
     harq->feedback_slot = pucch->ul_slot;
     harq->is_waiting = true;
     UE_info->mac_stats[UE_id].dlsch_rounds[harq->round]++;
-
-    LOG_D(NR_MAC,"%4d.%2d [DLSCH/PDSCH/PUCCH] UE %d RNTI %04x DCI L %d start %3d RBs %3d startSymbol %2d nb_symbol %2d dmrspos %x MCS %2d nrOfLayers %d TBS %4d HARQ PID %2d round %d RV %d NDI %d dl_data_to_ULACK %d (%d.%d) PUCCH allocation %d TPC %d\n",
+    LOG_D(NR_MAC,
+          "%4d.%2d [DLSCH/PDSCH/PUCCH] UE %d RNTI %04x DCI L %d start %3d RBs %3d startSymbol %2d nb_symbol %2d dmrspos %x MCS %2d nrOfLayers %d TBS %4d HARQ PID %2d round %d RV %d NDI %d dl_data_to_ULACK %d (%d.%d) PUCCH allocation %d TPC %d\n",
           frame,
           slot,
           UE_id,
@@ -1156,8 +1175,8 @@ void nr_schedule_ue_spec(module_id_t module_id,
           pucch->ul_slot,
           sched_pdsch->pucch_allocation,
           sched_ctrl->tpc1);
-
     NR_BWP_Downlink_t *bwp = sched_ctrl->active_bwp;
+
     const NR_SIB1_t *sib1 = RC.nrmac[module_id]->common_channels[0].sib1 ? RC.nrmac[module_id]->common_channels[0].sib1->message.choice.c1->choice.systemInformationBlockType1 : NULL;
     NR_BWP_t *genericParameters = get_dl_bwp_genericParameters(bwp,
                                                                RC.nrmac[module_id]->common_channels[0].ServingCellConfigCommon,
@@ -1170,6 +1189,7 @@ void nr_schedule_ue_spec(module_id_t module_id,
 
     /* look up the PDCCH PDU for this CC, BWP, and CORESET. If it does not exist, create it */
     nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu = gNB_mac->pdcch_pdu_idx[CC_id][coresetid];
+
     if (!pdcch_pdu) {
       LOG_D(NR_MAC, "creating pdcch pdu, pdcch_pdu = NULL. \n");
       nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdcch_pdu = &dl_req->dl_tti_pdu_list[dl_req->nPDUs];
@@ -1190,7 +1210,6 @@ void nr_schedule_ue_spec(module_id_t module_id,
     dl_tti_pdsch_pdu->PDUSize = (uint8_t)(2+sizeof(nfapi_nr_dl_tti_pdsch_pdu));
     dl_req->nPDUs += 1;
     nfapi_nr_dl_tti_pdsch_pdu_rel15_t *pdsch_pdu = &dl_tti_pdsch_pdu->pdsch_pdu.pdsch_pdu_rel15;
-
     pdsch_pdu->pduBitmap = 0;
     pdsch_pdu->rnti = rnti;
     /* SCF222: PDU index incremented for each PDSCH PDU sent in TX control
@@ -1208,9 +1227,7 @@ void nr_schedule_ue_spec(module_id_t module_id,
     }
 
     pdsch_pdu->SubcarrierSpacing = genericParameters->subcarrierSpacing;
-
     pdsch_pdu->CyclicPrefix = genericParameters->cyclicPrefix ? *genericParameters->cyclicPrefix : 0;
-
     // Codeword information
     pdsch_pdu->NrOfCodewords = 1;
     pdsch_pdu->targetCodeRate[0] = R;
@@ -1221,12 +1238,10 @@ void nr_schedule_ue_spec(module_id_t module_id,
     AssertFatal(harq->round<4,"%d",harq->round);
     pdsch_pdu->rvIndex[0] = nr_rv_round_map[harq->round];
     pdsch_pdu->TBSize[0] = TBS;
-
     pdsch_pdu->dataScramblingId = *scc->physCellId;
     pdsch_pdu->nrOfLayers = nrOfLayers;
     pdsch_pdu->transmissionScheme = 0;
     pdsch_pdu->refPoint = 0; // Point A
-
     // DMRS
     pdsch_pdu->dlDmrsSymbPos = ps->dl_dmrs_symb_pos;
     pdsch_pdu->dmrsConfigType = ps->dmrsConfigType;
@@ -1234,17 +1249,14 @@ void nr_schedule_ue_spec(module_id_t module_id,
     pdsch_pdu->SCID = 0;
     pdsch_pdu->numDmrsCdmGrpsNoData = ps->numDmrsCdmGrpsNoData;
     pdsch_pdu->dmrsPorts = (1<<nrOfLayers)-1;  // FIXME with a better implementation
-
     // Pdsch Allocation in frequency domain
     pdsch_pdu->resourceAlloc = 1;
     pdsch_pdu->rbStart = sched_pdsch->rbStart;
     pdsch_pdu->rbSize = sched_pdsch->rbSize;
     pdsch_pdu->VRBtoPRBMapping = 1; // non-interleaved, check if this is ok for initialBWP
-
     // Resource Allocation in time domain
     pdsch_pdu->StartSymbolIndex = ps->startSymbolIndex;
     pdsch_pdu->NrOfSymbols = ps->nrOfSymbols;
-
     // Precoding
     if (sched_ctrl->set_pmi) {
       int report_id = sched_ctrl->CSI_report.cri_ri_li_pmi_cqi_report.csi_report_id;
@@ -1259,6 +1271,7 @@ void nr_schedule_ue_spec(module_id_t module_id,
     }
 
     NR_PDSCH_Config_t *pdsch_Config=NULL;
+
     if (bwp &&
         bwp->bwp_Dedicated &&
         bwp->bwp_Dedicated->pdsch_Config &&
@@ -1267,18 +1280,20 @@ void nr_schedule_ue_spec(module_id_t module_id,
 
     /* Check and validate PTRS values */
     struct NR_SetupRelease_PTRS_DownlinkConfig *phaseTrackingRS =
-      pdsch_Config ? pdsch_Config->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->phaseTrackingRS : NULL;
+        pdsch_Config ? pdsch_Config->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->phaseTrackingRS : NULL;
+
     if (phaseTrackingRS) {
       bool valid_ptrs_setup = set_dl_ptrs_values(phaseTrackingRS->choice.setup,
-                                                 pdsch_pdu->rbSize,
-                                                 pdsch_pdu->mcsIndex[0],
-                                                 pdsch_pdu->mcsTable[0],
-                                                 &pdsch_pdu->PTRSFreqDensity,
-                                                 &pdsch_pdu->PTRSTimeDensity,
-                                                 &pdsch_pdu->PTRSPortIndex,
-                                                 &pdsch_pdu->nEpreRatioOfPDSCHToPTRS,
-                                                 &pdsch_pdu->PTRSReOffset,
-                                                 pdsch_pdu->NrOfSymbols);
+                              pdsch_pdu->rbSize,
+                              pdsch_pdu->mcsIndex[0],
+                              pdsch_pdu->mcsTable[0],
+                              &pdsch_pdu->PTRSFreqDensity,
+                              &pdsch_pdu->PTRSTimeDensity,
+                              &pdsch_pdu->PTRSPortIndex,
+                              &pdsch_pdu->nEpreRatioOfPDSCHToPTRS,
+                              &pdsch_pdu->PTRSReOffset,
+                              pdsch_pdu->NrOfSymbols);
+
       if (valid_ptrs_setup)
         pdsch_pdu->pduBitmap |= 0x1; // Bit 0: pdschPtrs - Indicates PTRS included (FR2)
     }
@@ -1288,6 +1303,7 @@ void nr_schedule_ue_spec(module_id_t module_id,
     nfapi_nr_dl_dci_pdu_t *dci_pdu = &pdcch_pdu->dci_pdu[pdcch_pdu->numDlDci];
     pdcch_pdu->numDlDci++;
     dci_pdu->RNTI = rnti;
+
     if (sched_ctrl->coreset &&
         sched_ctrl->search_space &&
         sched_ctrl->coreset->pdcch_DMRS_ScramblingID &&
@@ -1298,27 +1314,28 @@ void nr_schedule_ue_spec(module_id_t module_id,
       dci_pdu->ScramblingId = *scc->physCellId;
       dci_pdu->ScramblingRNTI = 0;
     }
+
     dci_pdu->AggregationLevel = sched_ctrl->aggregation_level;
     dci_pdu->CceIndex = sched_ctrl->cce_index;
     dci_pdu->beta_PDCCH_1_0 = 0;
     dci_pdu->powerControlOffsetSS = 1;
-
     /* DCI payload */
     dci_pdu_rel15_t dci_payload;
     memset(&dci_payload, 0, sizeof(dci_pdu_rel15_t));
     // bwp indicator
     const int n_dl_bwp = bwp ? UE_info->CellGroup[UE_id]->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count : 0;
     AssertFatal(n_dl_bwp <= 1, "downlinkBWP_ToAddModList has %d BWP!\n", n_dl_bwp);
-
     // as per table 7.3.1.1.2-1 in 38.212
     dci_payload.bwp_indicator.val = bwp ? (n_dl_bwp < 4 ? bwp->bwp_Id : bwp->bwp_Id - 1) : 0;
+
     if (bwp) AssertFatal(bwp->bwp_Dedicated->pdsch_Config->choice.setup->resourceAllocation == NR_PDSCH_Config__resourceAllocation_resourceAllocationType1,
-			 "Only frequency resource allocation type 1 is currently supported\n");
+                           "Only frequency resource allocation type 1 is currently supported\n");
+
     dci_payload.frequency_domain_assignment.val =
-        PRBalloc_to_locationandbandwidth0(
-            pdsch_pdu->rbSize,
-            pdsch_pdu->rbStart,
-            pdsch_pdu->BWPSize);
+      PRBalloc_to_locationandbandwidth0(
+        pdsch_pdu->rbSize,
+        pdsch_pdu->rbStart,
+        pdsch_pdu->BWPSize);
     dci_payload.format_indicator = 1;
     dci_payload.time_domain_assignment.val = ps->time_domain_allocation;
     dci_payload.mcs = sched_pdsch->mcs;
@@ -1349,11 +1366,11 @@ void nr_schedule_ue_spec(module_id_t module_id,
           dci_payload.tpc,
           pucch->timing_indicator);
 
+
     int dci_format = ss && ss->searchSpaceType && ss->searchSpaceType->present == NR_SearchSpace__searchSpaceType_PR_ue_Specific ?
                      NR_DL_DCI_FORMAT_1_1 : NR_DL_DCI_FORMAT_1_0;
 
     const int rnti_type = NR_RNTI_C;
-
     fill_dci_pdu_rel15(scc,
                        UE_info->CellGroup[UE_id],
                        dci_pdu,
@@ -1372,7 +1389,7 @@ void nr_schedule_ue_spec(module_id_t module_id,
 
     if (harq->round != 0) { /* retransmission */
       /* we do not have to do anything, since we do not require to get data
-       * from RLC or encode MAC CEs. The TX_req structure is filled below 
+       * from RLC or encode MAC CEs. The TX_req structure is filled below
        * or copy data to FAPI structures */
       LOG_D(NR_MAC,
             "%d.%2d DL retransmission UE %d/RNTI %04x HARQ PID %d round %d NDI %d\n",
@@ -1383,20 +1400,15 @@ void nr_schedule_ue_spec(module_id_t module_id,
             current_harq_pid,
             harq->round,
             harq->ndi);
-
       AssertFatal(harq->sched_pdsch.tb_size == TBS,
                   "UE %d mismatch between scheduled TBS and buffered TB for HARQ PID %d\n",
                   UE_id,
                   current_harq_pid);
-
       T(T_GNB_MAC_RETRANSMISSION_DL_PDU_WITH_DATA, T_INT(module_id), T_INT(CC_id), T_INT(rnti),
-        T_INT(frame), T_INT(slot), T_INT(current_harq_pid), T_INT(harq->round), T_BUFFER(harq->tb, TBS));
+        T_INT(frame), T_INT(slot), T_INT(current_harq_pid), T_INT(harq->round), T_BUFFER(harq->transportBlock, TBS));
     } else { /* initial transmission */
-
       LOG_D(NR_MAC, "[%s] Initial HARQ transmission in %d.%d\n", __FUNCTION__, frame, slot);
-
-      uint8_t *buf = (uint8_t *) harq->tb;
-
+      uint8_t *buf = (uint8_t *) harq->transportBlock;
       /* first, write all CEs that might be there */
       int written = nr_write_ce_dlsch_pdu(module_id,
                                           sched_ctrl,
@@ -1404,32 +1416,30 @@ void nr_schedule_ue_spec(module_id_t module_id,
                                           255, // no drx
                                           NULL); // contention res id
       buf += written;
-      int size = TBS - written;
-      DevAssert(size >= 0);
+      uint8_t *bufEnd = buf + TBS - written;
+      DevAssert(TBS > written);
+      int dlsch_total_bytes = 0;
       /* next, get RLC data */
-
       start_meas(&gNB_mac->rlc_data_req);
-      if (sched_ctrl->num_total_bytes > 0) {
 
+      if (sched_ctrl->num_total_bytes > 0) {
         /* loop over all activated logical channels */
         for (int i = 0; i < sched_ctrl->dl_lc_num; ++i) {
-
           const int lcid = sched_ctrl->dl_lc_ids[i];
+
           if (sched_ctrl->rlc_status[lcid].bytes_in_buffer == 0)
-            continue; // no data for this LC
+            continue; // no data for this LC        tbs_size_t len = 0;
 
-          int dlsch_total_bytes = 0;
-          while (size > 3) {
+          int lcid_bytes=0;
+          while (bufEnd-buf > sizeof(NR_MAC_SUBHEADER_LONG) + 1 ) {
             // we do not know how much data we will get from RLC, i.e., whether it
             // will be longer than 256B or not. Therefore, reserve space for long header, then
             // fetch data, then fill real length
             NR_MAC_SUBHEADER_LONG *header = (NR_MAC_SUBHEADER_LONG *) buf;
-            buf += 3;
-            size -= 3;
-
             /* limit requested number of bytes to what preprocessor specified, or
              * such that TBS is full */
-            const rlc_buffer_occupancy_t ndata = min(sched_ctrl->rlc_status[lcid].bytes_in_buffer, size);
+            const rlc_buffer_occupancy_t ndata = min(sched_ctrl->rlc_status[lcid].bytes_in_buffer,
+                                                 bufEnd-buf-sizeof(NR_MAC_SUBHEADER_LONG));
             tbs_size_t len = mac_rlc_data_req(module_id,
                                               rnti,
                                               module_id,
@@ -1438,12 +1448,11 @@ void nr_schedule_ue_spec(module_id_t module_id,
                                               MBMS_FLAG_NO,
                                               lcid,
                                               ndata,
-                                              (char *)buf,
+                                              (char *)buf+sizeof(NR_MAC_SUBHEADER_LONG),
                                               0,
                                               0);
-
             LOG_D(NR_MAC,
-                  "%4d.%2d RNTI %04x: %d bytes from %s %d (ndata %d, remaining size %d)\n",
+                  "%4d.%2d RNTI %04x: %d bytes from %s %d (ndata %d, remaining size %ld)\n",
                   frame,
                   slot,
                   rnti,
@@ -1451,64 +1460,56 @@ void nr_schedule_ue_spec(module_id_t module_id,
                   lcid < 4 ? "DCCH" : "DTCH",
                   lcid,
                   ndata,
-                  size);
-            if (len == 0) {
-              /* RLC did not have data anymore, mark buffer as unused */
-              buf -= 3;
-              size += 3;
+                  bufEnd-buf-+sizeof(NR_MAC_SUBHEADER_LONG));
+
+            if (len == 0)
               break;
-            }
 
             header->R = 0;
             header->F = 1;
             header->LCID = lcid;
-            header->L1 = (len >> 8) & 0xff;
-            header->L2 = len & 0xff;
-            size -= len;
-            buf += len;
+            header->L = htons(len);
+            buf += len+sizeof(NR_MAC_SUBHEADER_LONG);
             dlsch_total_bytes += len;
+            lcid_bytes += len;
           }
 
-          UE_info->mac_stats[UE_id].lc_bytes_tx[lcid] += dlsch_total_bytes;
+          UE_info->mac_stats[UE_id].lc_bytes_tx[lcid] += lcid_bytes;
         }
       } else if (get_softmodem_params()->phy_test || get_softmodem_params()->do_ra) {
         /* we will need the large header, phy-test typically allocates all
          * resources and fills to the last byte below */
-        NR_MAC_SUBHEADER_LONG *header = (NR_MAC_SUBHEADER_LONG *) buf;
-        buf += 3;
-        size -= 3;
-        DevAssert(size > 0);
-        LOG_D(NR_MAC, "Configuring DL_TX in %d.%d: TBS %d with %d B of random data\n", frame, slot, TBS, size);
-        // fill dlsch_buffer with random data
-        for (int i = 0; i < size; i++)
-          buf[i] = lrand48() & 0xff;
-        header->R = 0;
-        header->F = 1;
-        header->LCID = DL_SCH_LCID_PADDING;
-        header->L1 = (size >> 8) & 0xff;
-        header->L2 = size & 0xff;
-        size -= size;
-        buf += size;
+        LOG_D(NR_MAC, "Configuring DL_TX in %d.%d: TBS %d of random data\n", frame, slot, TBS);
+
+        if (bufEnd-buf > sizeof(NR_MAC_SUBHEADER_LONG) ) {
+          NR_MAC_SUBHEADER_LONG *header = (NR_MAC_SUBHEADER_LONG *) buf;
+          // fill dlsch_buffer with random data
+          header->R = 0;
+          header->F = 1;
+          header->LCID = DL_SCH_LCID_PADDING;
+          buf += sizeof(NR_MAC_SUBHEADER_LONG);
+          header->L = htons(bufEnd-buf);
+          dlsch_total_bytes += bufEnd-buf;
+
+          for (; buf < bufEnd; buf++)
+            *buf = lrand48() & 0xff;
+        }
       }
+
       stop_meas(&gNB_mac->rlc_data_req);
 
       // Add padding header and zero rest out if there is space left
-      if (size > 0) {
+      if (bufEnd-buf > 0) {
         NR_MAC_SUBHEADER_FIXED *padding = (NR_MAC_SUBHEADER_FIXED *) buf;
         padding->R = 0;
         padding->LCID = DL_SCH_LCID_PADDING;
-        size -= 1;
         buf += 1;
-        while (size > 0) {
-          *buf = 0;
-          buf += 1;
-          size -= 1;
-        }
+        memset(buf,0,bufEnd-buf);
+        buf=bufEnd;
       }
 
       UE_info->mac_stats[UE_id].dlsch_total_bytes += TBS;
       UE_info->mac_stats[UE_id].dlsch_current_bytes = TBS;
-
       /* save retransmission information */
       harq->sched_pdsch = *sched_pdsch;
       /* save which time allocation has been used, to be used on
@@ -1527,7 +1528,7 @@ void nr_schedule_ue_spec(module_id_t module_id,
       }
 
       T(T_GNB_MAC_DL_PDU_WITH_DATA, T_INT(module_id), T_INT(CC_id), T_INT(rnti),
-        T_INT(frame), T_INT(slot), T_INT(current_harq_pid), T_BUFFER(harq->tb, TBS));
+        T_INT(frame), T_INT(slot), T_INT(current_harq_pid), T_BUFFER(harq->transportBlock, TBS));
     }
 
     const int ntx_req = gNB_mac->TX_req[CC_id].Number_of_PDUs;
@@ -1536,11 +1537,10 @@ void nr_schedule_ue_spec(module_id_t module_id,
     tx_req->PDU_index  = pduindex;
     tx_req->num_TLV = 1;
     tx_req->TLVs[0].length = TBS + 2;
-    memcpy(tx_req->TLVs[0].value.direct, harq->tb, TBS);
+    memcpy(tx_req->TLVs[0].value.direct, harq->transportBlock, TBS);
     gNB_mac->TX_req[CC_id].Number_of_PDUs++;
     gNB_mac->TX_req[CC_id].SFN = frame;
     gNB_mac->TX_req[CC_id].Slot = slot;
-
     /* mark UE as scheduled */
     sched_pdsch->rbSize = 0;
   }
diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_srs.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_srs.c
index a2b27357dd99dbee1883860d753e7a512986bf28..bf2af3b388f19ad92fd13976c99fef86a72e7fd0 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_srs.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_srs.c
@@ -85,7 +85,9 @@ void nr_configure_srs(nfapi_nr_srs_pdu_t *srs_pdu, int module_id, int CC_id, int
 void nr_fill_nfapi_srs(int module_id, int CC_id, int UE_id, sub_frame_t slot, NR_SRS_Resource_t *srs_resource) {
 
   nfapi_nr_ul_tti_request_t *future_ul_tti_req = &RC.nrmac[module_id]->UL_tti_req_ahead[0][slot];
-
+  AssertFatal(future_ul_tti_req->n_pdus <
+              sizeof(future_ul_tti_req->pdus_list) / sizeof(future_ul_tti_req->pdus_list[0]),
+              "Invalid future_ul_tti_req->n_pdus %d\n", future_ul_tti_req->n_pdus);
   future_ul_tti_req->pdus_list[future_ul_tti_req->n_pdus].pdu_type = NFAPI_NR_UL_CONFIG_SRS_PDU_TYPE;
   future_ul_tti_req->pdus_list[future_ul_tti_req->n_pdus].pdu_size = sizeof(nfapi_nr_srs_pdu_t);
   nfapi_nr_srs_pdu_t *srs_pdu = &future_ul_tti_req->pdus_list[future_ul_tti_req->n_pdus].srs_pdu;
diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c
index dccd0042acfdf9fc86fb7853d618ce81f5d8b547..9655ce5f57a6accc1ada5d0b079271ccc9e22a3e 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c
@@ -51,11 +51,14 @@ void nr_fill_nfapi_pucch(module_id_t mod_id,
       &RC.nrmac[mod_id]->UL_tti_req_ahead[0][pucch->ul_slot];
   AssertFatal(future_ul_tti_req->SFN == pucch->frame
               && future_ul_tti_req->Slot == pucch->ul_slot,
-              "future UL_tti_req's frame.slot %d.%d does not match PUCCH %d.%d\n",
+              "future UL_tti_req's frame.slot %4d.%2d does not match PUCCH %4d.%2d\n",
               future_ul_tti_req->SFN,
               future_ul_tti_req->Slot,
               pucch->frame,
               pucch->ul_slot);
+  AssertFatal(future_ul_tti_req->n_pdus <
+              sizeof(future_ul_tti_req->pdus_list) / sizeof(future_ul_tti_req->pdus_list[0]),
+              "Invalid future_ul_tti_req->n_pdus %d\n", future_ul_tti_req->n_pdus);
   future_ul_tti_req->pdus_list[future_ul_tti_req->n_pdus].pdu_type = NFAPI_NR_UL_CONFIG_PUCCH_PDU_TYPE;
   future_ul_tti_req->pdus_list[future_ul_tti_req->n_pdus].pdu_size = sizeof(nfapi_nr_pucch_pdu_t);
   nfapi_nr_pucch_pdu_t *pucch_pdu = &future_ul_tti_req->pdus_list[future_ul_tti_req->n_pdus].pucch_pdu;
@@ -81,7 +84,7 @@ void nr_fill_nfapi_pucch(module_id_t mod_id,
                                     cg->spCellConfig->spCellConfigDedicated->uplinkConfig ?
                                     cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP : NULL;
 
-  LOG_D(NR_MAC,"%d.%d Calling nr_configure_pucch (ubwpd %p,r_pucch %d) pucch to be scheduled in %d.%d\n",
+  LOG_D(NR_MAC,"%4d.%2d Calling nr_configure_pucch (ubwpd %p,r_pucch %d) pucch to be scheduled in %4d.%2d\n",
         frame,slot,ubwpd,pucch->r_pucch,pucch->frame,pucch->ul_slot);
 
   const NR_SIB1_t *sib1 = nr_mac->common_channels[0].sib1 ? nr_mac->common_channels[0].sib1->message.choice.c1->choice.systemInformationBlockType1 : NULL;
@@ -158,7 +161,7 @@ void nr_schedule_pucch(int Mod_idP,
           || frameP != curr_pucch->frame
           || slotP != curr_pucch->ul_slot)
         continue;
-      LOG_D(NR_MAC,"Scheduling PUCCH[%d] RX for UE %d in %d.%d O_ack %d\n",i,UE_id,curr_pucch->frame,curr_pucch->ul_slot,O_ack);
+      LOG_D(NR_MAC,"Scheduling PUCCH[%d] RX for UE %d in %4d.%2d O_ack %d\n",i,UE_id,curr_pucch->frame,curr_pucch->ul_slot,O_ack);
       nr_fill_nfapi_pucch(Mod_idP, frameP, slotP, curr_pucch, UE_id);
       memset(curr_pucch, 0, sizeof(*curr_pucch));
     }
@@ -820,6 +823,7 @@ static void handle_dl_harq(module_id_t mod_id,
     stats->dlsch_errors++;
     LOG_D(NR_MAC, "retransmission error for UE %d (total %"PRIu64")\n", UE_id, stats->dlsch_errors);
   } else {
+    LOG_D(PHY,"NACK for: pid %d, ue %x\n",harq_pid, UE_id);
     add_tail_nr_list(&UE_info->UE_sched_ctrl[UE_id].retrans_dl_harq, harq_pid);
     harq->round++;
   }
@@ -1401,7 +1405,7 @@ static NR_UE_harq_t *find_harq(module_id_t mod_id, frame_t frame, sub_frame_t sl
   while (harq->feedback_frame != frame
          || (harq->feedback_frame == frame && harq->feedback_slot < slot)) {
     LOG_W(NR_MAC,
-          "expected HARQ pid %d feedback at %d.%d, but is at %d.%d instead (HARQ feedback is in the past)\n",
+          "expected HARQ pid %d feedback at %4d.%2d, but is at %4d.%2d instead (HARQ feedback is in the past)\n",
           pid,
           harq->feedback_frame,
           harq->feedback_slot,
@@ -1417,7 +1421,7 @@ static NR_UE_harq_t *find_harq(module_id_t mod_id, frame_t frame, sub_frame_t sl
   /* feedbacks that we wait for in the future: don't do anything */
   if (harq->feedback_slot > slot) {
     LOG_W(NR_MAC,
-          "expected HARQ pid %d feedback at %d.%d, but is at %d.%d instead (HARQ feedback is in the future)\n",
+          "expected HARQ pid %d feedback at %4d.%2d, but is at %4d.%2d instead (HARQ feedback is in the future)\n",
           pid,
           harq->feedback_frame,
           harq->feedback_slot,
@@ -1454,7 +1458,7 @@ void handle_nr_uci_pucch_0_1(module_id_t mod_id,
       DevAssert(harq->is_waiting);
       const int8_t pid = sched_ctrl->feedback_dl_harq.head;
       remove_front_nr_list(&sched_ctrl->feedback_dl_harq);
-      LOG_D(NR_MAC,"bit %d pid %d ack/nack %d\n",harq_bit,pid,harq_value);
+      LOG_D(NR_MAC,"%4d.%2d bit %d pid %d ack/nack %d\n",frame, slot, harq_bit,pid,harq_value);
       handle_dl_harq(mod_id, UE_id, pid, harq_value == 0 && harq_confidence == 0);
       if (harq_confidence == 1)  UE_info->mac_stats[UE_id].pucch0_DTX++;
     }
@@ -1496,10 +1500,11 @@ void handle_nr_uci_pucch_2_3_4(module_id_t mod_id,
   NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
 
   // tpc (power control)
-  sched_ctrl->tpc1 = nr_get_tpc(RC.nrmac[mod_id]->pucch_target_snrx10,
-                                uci_234->ul_cqi,
-                                30);
-  sched_ctrl->pucch_snrx10 = uci_234->ul_cqi * 5 - 640;
+  // TODO PUCCH2 SNR computation is not correct -> ignore the following
+  //sched_ctrl->tpc1 = nr_get_tpc(RC.nrmac[mod_id]->pucch_target_snrx10,
+  //                              uci_234->ul_cqi,
+  //                              30);
+  //sched_ctrl->pucch_snrx10 = uci_234->ul_cqi * 5 - 640;
 
   if ((uci_234->pduBitmap >> 1) & 0x01) {
     // iterate over received harq bits
@@ -1638,7 +1643,7 @@ int nr_acknack_scheduling(int mod_id,
   int bwp_size = NRRIV2BW(genericParameters->locationAndBandwidth, MAX_BWP_SIZE);
 
   NR_sched_pucch_t *pucch = &sched_ctrl->sched_pucch[0];
-  LOG_D(NR_MAC, "In %s: %d.%d Trying to allocate pucch, current DAI %d\n", __FUNCTION__, frame, slot, pucch->dai_c);
+  LOG_D(NR_MAC, "In %s: %4d.%2d Trying to allocate pucch, current DAI %d\n", __FUNCTION__, frame, slot, pucch->dai_c);
 
   pucch->r_pucch=r_pucch;
   AssertFatal(pucch->csi_bits == 0,
@@ -1652,7 +1657,7 @@ int nr_acknack_scheduling(int mod_id,
      * the same slot again */
     const int f = pucch->frame;
     const int s = pucch->ul_slot;
-    LOG_D(NR_MAC, "In %s: %d.%d DAI = 2 pucch currently in %d.%d, advancing by 1 slot\n", __FUNCTION__, frame, slot, f, s);
+    LOG_D(NR_MAC, "In %s: %4d.%2d DAI = 2 pucch currently in %4d.%2d, advancing by 1 slot\n", __FUNCTION__, frame, slot, f, s);
     nr_fill_nfapi_pucch(mod_id, frame, slot, pucch, UE_id);
     memset(pucch, 0, sizeof(*pucch));
     pucch->frame = s == n_slots_frame - 1 ? (f + 1) % 1024 : f;
@@ -1679,7 +1684,7 @@ int nr_acknack_scheduling(int mod_id,
     }
   }
 
-  LOG_D(NR_MAC, "In %s: pucch_acknak 1. DL %d.%d, UL_ACK %d.%d, DAI_C %d\n", __FUNCTION__, frame, slot, pucch->frame, pucch->ul_slot, pucch->dai_c);
+  LOG_D(NR_MAC, "In %s: pucch_acknak 1. DL %4d.%2d, UL_ACK %4d.%2d, DAI_C %d\n", __FUNCTION__, frame, slot, pucch->frame, pucch->ul_slot, pucch->dai_c);
 
   // this is hardcoded for now as ue specific only if we are not on the initialBWP (to be fixed to allow ue_Specific also on initialBWP
   NR_BWP_UplinkDedicated_t *ubwpd=NULL;
@@ -1699,7 +1704,7 @@ int nr_acknack_scheduling(int mod_id,
   int max_fb_time = 0;
   get_pdsch_to_harq_feedback(mod_id, UE_id, bwp_Id, ss_type, &max_fb_time, pdsch_to_harq_feedback);
 
-  LOG_D(NR_MAC, "In %s: 1b. DL %d.%d, UL_ACK %d.%d, DAI_C %d\n", __FUNCTION__, frame,slot,pucch->frame,pucch->ul_slot,pucch->dai_c);
+  LOG_D(NR_MAC, "In %s: 1b. DL %4d.%2d, UL_ACK %4d.%2d, DAI_C %d\n", __FUNCTION__, frame,slot,pucch->frame,pucch->ul_slot,pucch->dai_c);
   /* there is a HARQ. Check whether we can use it for this ACKNACK */
   if (pucch->dai_c > 0) {
     /* this UE already has a PUCCH occasion */
@@ -1719,7 +1724,7 @@ int nr_acknack_scheduling(int mod_id,
       const int f = pucch->frame;
       const int s = pucch->ul_slot;
       const int n_slots_frame = nr_slots_per_frame[*scc->ssbSubcarrierSpacing];
-      LOG_D(NR_MAC, "In %s: %d.%d DAI > 0, cannot reach timing for pucch in %d.%d, advancing slot by 1 and trying again\n", __FUNCTION__, frame, slot, f, s);
+      LOG_D(NR_MAC, "In %s: %4d.%2d DAI > 0, cannot reach timing for pucch in %4d.%2d, advancing slot by 1 and trying again\n", __FUNCTION__, frame, slot, f, s);
       nr_fill_nfapi_pucch(mod_id, frame, slot, pucch, UE_id);
       memset(pucch, 0, sizeof(*pucch));
       pucch->frame = s == n_slots_frame - 1 ? (f + 1) % 1024 : f;
@@ -1733,11 +1738,11 @@ int nr_acknack_scheduling(int mod_id,
     pucch->timing_indicator = i;
     pucch->dai_c++;
     // retain old resource indicator, and we are good
-    LOG_D(NR_MAC, "In %s: %d.%d. DAI > 0, pucch allocated for %d.%d (index %d)\n", __FUNCTION__, frame,slot,pucch->frame,pucch->ul_slot,pucch->timing_indicator);
+    LOG_D(NR_MAC, "In %s: %4d.%2d. DAI > 0, pucch allocated for %4d.%2d (index %d)\n", __FUNCTION__, frame,slot,pucch->frame,pucch->ul_slot,pucch->timing_indicator);
     return 0;
   }
 
-  LOG_D(NR_MAC, "In %s: %d.%d DAI = 0, looking for new pucch occasion\n", __FUNCTION__, frame, slot);
+  LOG_D(NR_MAC, "In %s: %4d.%2d DAI = 0, looking for new pucch occasion\n", __FUNCTION__, frame, slot);
   /* we need to find a new PUCCH occasion */
 
   /*(Re)Inizialization of timing information*/
@@ -1840,7 +1845,7 @@ int nr_acknack_scheduling(int mod_id,
 
   pucch->timing_indicator = ind_found; // index in the list of timing indicators
 
-  LOG_D(NR_MAC, "In %s: 2. DAI 0 DL %d.%d, UL_ACK %d.%d (index %d)\n", __FUNCTION__, frame,slot,pucch->frame,pucch->ul_slot,pucch->timing_indicator);
+  LOG_D(NR_MAC, "In %s: 2. DAI 0 DL %4d.%2d, UL_ACK %4d.%2d (index %d)\n", __FUNCTION__, frame,slot,pucch->frame,pucch->ul_slot,pucch->timing_indicator);
 
   pucch->dai_c++;
   pucch->resource_indicator = 0; // each UE has dedicated PUCCH resources
diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c
index a60bd9abb5dc0fa796a3deaabcaeb6d90c0c5ca8..72061bb9ba867cbba44f9777f74b95abfe666f24 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c
@@ -55,7 +55,7 @@ void calculate_preferred_ul_tda(module_id_t module_id, const NR_BWP_Uplink_t *ub
 
   /* there is a mixed slot only when in TDD */
   NR_ServingCellConfigCommon_t *scc = nrmac->common_channels->ServingCellConfigCommon;
-  lte_frame_type_t frame_type = nrmac->common_channels->frame_type;
+  frame_type_t frame_type = nrmac->common_channels->frame_type;
   const int n = nr_slots_per_frame[*scc->ssbSubcarrierSpacing];
 
   NR_ServingCellConfigCommonSIB_t *scc_sib1 = get_softmodem_params()->sa ?
@@ -213,11 +213,8 @@ int nr_process_mac_pdu(module_id_t module_idP,
                         int pdu_len)
 {
 
-    uint8_t rx_lcid;
+
     uint8_t done = 0;
-    uint16_t mac_ce_len;
-    uint16_t mac_subheader_len;
-    uint16_t mac_sdu_len;
 
     NR_UE_info_t *UE_info = &RC.nrmac[module_idP]->UE_info;
     NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
@@ -231,10 +228,9 @@ int nr_process_mac_pdu(module_id_t module_idP,
     #endif
 
     while (!done && pdu_len > 0){
-        mac_ce_len = 0;
-        mac_subheader_len = sizeof(NR_MAC_SUBHEADER_FIXED);
-        mac_sdu_len = 0;
-        rx_lcid = ((NR_MAC_SUBHEADER_FIXED *)pduP)->LCID;
+      uint16_t mac_len=0;
+      uint16_t mac_subheader_len=sizeof(NR_MAC_SUBHEADER_FIXED);
+      uint8_t rx_lcid = ((NR_MAC_SUBHEADER_FIXED *)pduP)->LCID;
 
         LOG_D(NR_MAC, "In %s: received UL-SCH sub-PDU with LCID 0x%x in %d.%d (remaining PDU length %d)\n", __func__, rx_lcid, frameP, slot, pdu_len);
 
@@ -249,7 +245,7 @@ int nr_process_mac_pdu(module_id_t module_idP,
             #endif*/
         case UL_SCH_LCID_RECOMMENDED_BITRATE_QUERY:
               // 38.321 Ch6.1.3.20
-              mac_ce_len = 2;
+              mac_len = 2;
               break;
         case UL_SCH_LCID_CONFIGURED_GRANT_CONFIRMATION:
                 // 38.321 Ch6.1.3.7
@@ -259,7 +255,7 @@ int nr_process_mac_pdu(module_id_t module_idP,
         case UL_SCH_LCID_S_TRUNCATED_BSR:
                //38.321 section 6.1.3.1
                //fixed length
-               mac_ce_len =1;
+               mac_len =1;
                /* Extract short BSR value */
                ce_ptr = &pduP[mac_subheader_len];
                NR_BSR_SHORT *bsr_s = (NR_BSR_SHORT *) ce_ptr;
@@ -279,12 +275,13 @@ int nr_process_mac_pdu(module_id_t module_idP,
         case UL_SCH_LCID_L_TRUNCATED_BSR:
         	//38.321 section 6.1.3.1
         	//variable length
-        	mac_ce_len |= (uint16_t)((NR_MAC_SUBHEADER_SHORT *)pduP)->L;
-        	mac_subheader_len = 2;
-        	if(((NR_MAC_SUBHEADER_SHORT *)pduP)->F){
-        		mac_ce_len |= (uint16_t)(((NR_MAC_SUBHEADER_LONG *)pduP)->L2)<<8;
-        		mac_subheader_len = 3;
-        	}
+                /* Several checks have been added to this function to
+                   ensure that the casting of the pduP is possible. There seems
+                   to be a partial PDU at the end of this buffer, so here
+                   we gracefully ignore that by returning 0. See:
+                   https://gitlab.eurecom.fr/oai/openairinterface5g/-/issues/534 */
+	  if (!get_mac_len(pduP, pdu_len, &mac_len, &mac_subheader_len))
+		  return 0;
         	/* Extract long BSR value */
                ce_ptr = &pduP[mac_subheader_len];
                NR_BSR_LONG *bsr_l = (NR_BSR_LONG *) ce_ptr;
@@ -330,14 +327,14 @@ int nr_process_mac_pdu(module_id_t module_idP,
 
         	//38.321 section 6.1.3.2
         	//fixed length
-        	mac_ce_len = 2;
+        	mac_len = 2;
         	/* Extract CRNTI value */
         	break;
 
         case UL_SCH_LCID_SINGLE_ENTRY_PHR:
         	//38.321 section 6.1.3.8
         	//fixed length
-        	mac_ce_len = 2;
+        	mac_len = 2;
         	/* Extract SINGLE ENTRY PHR elements for PHR calculation */
         	ce_ptr = &pduP[mac_subheader_len];
         	NR_SINGLE_ENTRY_PHR_MAC_CE *phr = (NR_SINGLE_ENTRY_PHR_MAC_CE *) ce_ptr;
@@ -358,24 +355,16 @@ int nr_process_mac_pdu(module_id_t module_idP,
         case UL_SCH_LCID_MULTI_ENTRY_PHR_1_OCT:
         	//38.321 section 6.1.3.9
         	//  varialbe length
-        	mac_ce_len |= (uint16_t)((NR_MAC_SUBHEADER_SHORT *)pduP)->L;
-        	mac_subheader_len = 2;
-        	if(((NR_MAC_SUBHEADER_SHORT *)pduP)->F){
-        		mac_ce_len |= (uint16_t)(((NR_MAC_SUBHEADER_LONG *)pduP)->L2)<<8;
-        		mac_subheader_len = 3;
-        	}
+	  if (!get_mac_len(pduP, pdu_len, &mac_len, &mac_subheader_len))
+	    return 0;
         	/* Extract MULTI ENTRY PHR elements from single octet bitmap for PHR calculation */
         	break;
 
         case UL_SCH_LCID_MULTI_ENTRY_PHR_4_OCT:
         	//38.321 section 6.1.3.9
         	//  varialbe length
-        	mac_ce_len |= (uint16_t)((NR_MAC_SUBHEADER_SHORT *)pduP)->L;
-        	mac_subheader_len = 2;
-        	if(((NR_MAC_SUBHEADER_SHORT *)pduP)->F){
-        		mac_ce_len |= (uint16_t)(((NR_MAC_SUBHEADER_LONG *)pduP)->L2)<<8;
-        		mac_subheader_len = 3;
-        	}
+	  if (!get_mac_len(pduP, pdu_len, &mac_len, &mac_subheader_len))
+	    return 0;
         	/* Extract MULTI ENTRY PHR elements from four octets bitmap for PHR calculation */
         	break;
 
@@ -386,23 +375,16 @@ int nr_process_mac_pdu(module_id_t module_idP,
 
         case UL_SCH_LCID_SRB1:
         case UL_SCH_LCID_SRB2:
-          if(((NR_MAC_SUBHEADER_SHORT *)pduP)->F){
-            //mac_sdu_len |= (uint16_t)(((NR_MAC_SUBHEADER_LONG *)pduP)->L2)<<8;
-            mac_subheader_len = 3;
-            mac_sdu_len = ((uint16_t)(((NR_MAC_SUBHEADER_LONG *) pduP)->L1 & 0x7f) << 8)
-                | ((uint16_t)((NR_MAC_SUBHEADER_LONG *) pduP)->L2 & 0xff);
-          } else {
-            mac_sdu_len = (uint16_t)((NR_MAC_SUBHEADER_SHORT *)pduP)->L;
-            mac_subheader_len = 2;
-          }
+	  if (!get_mac_len(pduP, pdu_len, &mac_len, &mac_subheader_len))
+	    return 0;
 
           rnti_t crnti = UE_info->rnti[UE_id];
           int UE_idx = UE_id;
           for (int i = 0; i < NR_NB_RA_PROC_MAX; i++) {
             NR_RA_t *ra = &RC.nrmac[module_idP]->common_channels[CC_id].ra[i];
             if (ra->state >= WAIT_Msg3 && ra->rnti == UE_info->rnti[UE_id]) {
-              uint8_t *next_subpduP = pduP + mac_subheader_len + mac_sdu_len;
-              if ((pduP[mac_subheader_len+mac_sdu_len] & 0x3F) == UL_SCH_LCID_C_RNTI) {
+              uint8_t *next_subpduP = pduP + mac_subheader_len + mac_len;
+              if ((pduP[mac_subheader_len+mac_len] & 0x3F) == UL_SCH_LCID_C_RNTI) {
                 crnti = ((next_subpduP[1]&0xFF)<<8)|(next_subpduP[2]&0xFF);
                 UE_idx = find_nr_UE_id(module_idP, crnti);
                 break;
@@ -411,7 +393,7 @@ int nr_process_mac_pdu(module_id_t module_idP,
           }
 
           if (UE_info->CellGroup[UE_idx]) {
-            LOG_D(NR_MAC, "[UE %d] Frame %d : ULSCH -> UL-DCCH %d (gNB %d, %d bytes), rnti: 0x%04x \n", module_idP, frameP, rx_lcid, module_idP, mac_sdu_len, crnti);
+            LOG_D(NR_MAC, "[UE %d] Frame %d : ULSCH -> UL-DCCH %d (gNB %d, %d bytes), rnti: 0x%04x \n", module_idP, frameP, rx_lcid, module_idP, mac_len, crnti);
             mac_rlc_data_ind(module_idP,
                              crnti,
                              module_idP,
@@ -420,7 +402,7 @@ int nr_process_mac_pdu(module_id_t module_idP,
                              MBMS_FLAG_NO,
                              rx_lcid,
                              (char *) (pduP + mac_subheader_len),
-                             mac_sdu_len,
+                             mac_len,
                              1,
                              NULL);
           } else {
@@ -438,23 +420,23 @@ int nr_process_mac_pdu(module_id_t module_idP,
 
           if ( rx_lcid == UL_SCH_LCID_CCCH1 ) {
             // RRCResumeRequest1 message includes the full I-RNTI and has a size of 8 bytes
-            mac_sdu_len = 8;
+            mac_len = 8;
 
             // Check if it is a valid CCCH1 message, we get all 00's messages very often
             int i = 0;
-            for(i=0; i<(mac_subheader_len+mac_sdu_len); i++) {
+            for(i=0; i<(mac_subheader_len+mac_len); i++) {
               if(pduP[i] != 0) {
                 break;
               }
             }
-            if (i == (mac_subheader_len+mac_sdu_len)) {
+            if (i == (mac_subheader_len+mac_len)) {
               LOG_D(NR_MAC, "%s() Invalid CCCH1 message!, pdu_len: %d\n", __func__, pdu_len);
               done = 1;
               break;
             }
           } else {
             // fixed length of 6 bytes
-            mac_sdu_len = 6;
+            mac_len = 6;
           }
 
           nr_mac_rrc_data_ind(module_idP,
@@ -465,22 +447,14 @@ int nr_process_mac_pdu(module_id_t module_idP,
                               UE_info->rnti[UE_id],
                               CCCH,
                               pduP + mac_subheader_len,
-                              mac_sdu_len,
+                              mac_len,
                               0);
           break;
 
         case UL_SCH_LCID_DTCH:
           //  check if LCID is valid at current time.
-          if (((NR_MAC_SUBHEADER_SHORT *)pduP)->F) {
-            // mac_sdu_len |= (uint16_t)(((NR_MAC_SUBHEADER_LONG *)pduP)->L2)<<8;
-            mac_subheader_len = 3;
-            mac_sdu_len = ((uint16_t)(((NR_MAC_SUBHEADER_LONG *)pduP)->L1 & 0x7f) << 8)
-                          | ((uint16_t)((NR_MAC_SUBHEADER_LONG *)pduP)->L2 & 0xff);
-
-          } else {
-            mac_sdu_len = (uint16_t)((NR_MAC_SUBHEADER_SHORT *)pduP)->L;
-            mac_subheader_len = 2;
-          }
+	  if (!get_mac_len(pduP, pdu_len, &mac_len, &mac_subheader_len))
+	    return 0;
 
           LOG_D(NR_MAC, "In %s: [UE %d] %d.%d : ULSCH -> UL-%s %d (gNB %d, %d bytes)\n",
                 __func__,
@@ -490,8 +464,8 @@ int nr_process_mac_pdu(module_id_t module_idP,
                 rx_lcid<4?"DCCH":"DTCH",
                 rx_lcid,
                 module_idP,
-                mac_sdu_len);
-          UE_info->mac_stats[UE_id].lc_bytes_rx[rx_lcid] += mac_sdu_len;
+                mac_len);
+          UE_info->mac_stats[UE_id].lc_bytes_rx[rx_lcid] += mac_len;
 
           mac_rlc_data_ind(module_idP,
                            UE_info->rnti[UE_id],
@@ -501,13 +475,13 @@ int nr_process_mac_pdu(module_id_t module_idP,
                            MBMS_FLAG_NO,
                            rx_lcid,
                            (char *)(pduP + mac_subheader_len),
-                           mac_sdu_len,
+                           mac_len,
                            1,
                            NULL);
 
           /* Updated estimated buffer when receiving data */
-          if (sched_ctrl->estimated_ul_buffer >= mac_sdu_len)
-            sched_ctrl->estimated_ul_buffer -= mac_sdu_len;
+          if (sched_ctrl->estimated_ul_buffer >= mac_len)
+            sched_ctrl->estimated_ul_buffer -= mac_len;
           else
             sched_ctrl->estimated_ul_buffer = 0;
           break;
@@ -522,16 +496,16 @@ int nr_process_mac_pdu(module_id_t module_idP,
         if (rx_lcid < 45 || rx_lcid == 52 || rx_lcid == 63) {
           LOG_I(NR_MAC, "In %s: dumping UL MAC SDU sub-header with length %d (LCID = 0x%02x):\n", __func__, mac_subheader_len, rx_lcid);
           log_dump(NR_MAC, pduP, mac_subheader_len, LOG_DUMP_CHAR, "\n");
-          LOG_I(NR_MAC, "In %s: dumping UL MAC SDU with length %d (LCID = 0x%02x):\n", __func__, mac_sdu_len, rx_lcid);
-          log_dump(NR_MAC, pduP + mac_subheader_len, mac_sdu_len, LOG_DUMP_CHAR, "\n");
+          LOG_I(NR_MAC, "In %s: dumping UL MAC SDU with length %d (LCID = 0x%02x):\n", __func__, mac_len, rx_lcid);
+          log_dump(NR_MAC, pduP + mac_subheader_len, mac_len, LOG_DUMP_CHAR, "\n");
         } else {
-          LOG_I(NR_MAC, "In %s: dumping UL MAC CE with length %d (LCID = 0x%02x):\n", __func__, mac_ce_len, rx_lcid);
-          log_dump(NR_MAC, pduP + mac_subheader_len + mac_sdu_len, mac_ce_len, LOG_DUMP_CHAR, "\n");
+          LOG_I(NR_MAC, "In %s: dumping UL MAC CE with length %d (LCID = 0x%02x):\n", __func__, mac_len, rx_lcid);
+          log_dump(NR_MAC, pduP + mac_subheader_len + mac_len, mac_len, LOG_DUMP_CHAR, "\n");
         }
         #endif
 
-        pduP += ( mac_subheader_len + mac_ce_len + mac_sdu_len );
-        pdu_len -= ( mac_subheader_len + mac_ce_len + mac_sdu_len );
+        pduP += ( mac_subheader_len + mac_len );
+        pdu_len -= ( mac_subheader_len + mac_len );
 
         if (pdu_len < 0) {
           LOG_E(NR_MAC, "In %s: residual UL MAC PDU in %d.%d with length < 0!, pdu_len %d \n", __func__, frameP, slot, pdu_len);
@@ -1777,6 +1751,9 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot)
                 future_ul_tti_req->Slot,
                 sched_pusch->frame,
                 sched_pusch->slot);
+    AssertFatal(future_ul_tti_req->n_pdus <
+                sizeof(future_ul_tti_req->pdus_list) / sizeof(future_ul_tti_req->pdus_list[0]),
+                "Invalid future_ul_tti_req->n_pdus %d\n", future_ul_tti_req->n_pdus);
     future_ul_tti_req->pdus_list[future_ul_tti_req->n_pdus].pdu_type = NFAPI_NR_UL_CONFIG_PUSCH_PDU_TYPE;
     future_ul_tti_req->pdus_list[future_ul_tti_req->n_pdus].pdu_size = sizeof(nfapi_nr_pusch_pdu_t);
     nfapi_nr_pusch_pdu_t *pusch_pdu = &future_ul_tti_req->pdus_list[future_ul_tti_req->n_pdus].pusch_pdu;
diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h
index fd4f3a44520b1e7101f2f82ba67e6926f30df96f..34b144609a4eb7788d06d2a7ef9d5c65475850bb 100644
--- a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h
+++ b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h
@@ -525,4 +525,7 @@ bool nr_find_nb_rb(uint16_t Qm,
 void nr_sr_reporting(int Mod_idP, frame_t frameP, sub_frame_t slotP);
 
 void dump_mac_stats(gNB_MAC_INST *gNB, char *output, int strlen, bool reset_rsrp);
+
+void process_CellGroup(NR_CellGroupConfig_t *CellGroup, NR_UE_sched_ctrl_t *sched_ctrl);
+
 #endif /*__LAYER2_NR_MAC_PROTO_H__*/
diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h
index 4e4a7df7fa2c7f330a40d2ea2043c0c0305f1812..8d59cf42a571a535af4298d3ba97240e451d9246 100644
--- a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h
+++ b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h
@@ -202,7 +202,7 @@ typedef struct {
   int p_gNB;
   int Ncp;
   int nr_band;
-  lte_frame_type_t frame_type;
+  frame_type_t frame_type;
   uint64_t dl_CarrierFreq;
   NR_BCCH_BCH_Message_t *mib;
   NR_BCCH_DL_SCH_Message_t *sib1;
@@ -445,7 +445,7 @@ typedef struct NR_UE_harq {
 
   /* Transport block to be sent using this HARQ process, its size is in
    * sched_pdsch */
-  uint32_t tb[16384];
+  uint32_t transportBlock[16384];
   uint32_t tb_size;
 
   /// sched_pdsch keeps information on MCS etc used for the initial transmission
diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.c
index 62aa101a500534a1837579157b0825f0ee321cb4..c20871f6c0422c13a0193c1b7f83a1919d9e3172 100644
--- a/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.c
+++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.c
@@ -51,7 +51,12 @@ static void nr_pdcp_entity_recv_pdu(nr_pdcp_entity_t *entity,
 
   if (entity->type != NR_PDCP_SRB && !(buffer[0] & 0x80)) {
     LOG_E(PDCP, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__);
-    exit(1);
+    /* TODO: This is something of a hack. The most significant bit
+       in buffer[0] should be 1 if the packet is a data packet. We are
+       processing malformed data packets if the most significant bit
+       is 0. Rather than exit(1), this hack allows us to continue for now.
+       We need to investigate why this hack is neccessary. */
+    buffer[0] |= 128;
   }
 
   if (entity->sn_size == 12) {
@@ -368,8 +373,8 @@ nr_pdcp_entity_t *new_nr_pdcp_entity(
   ret->set_security = nr_pdcp_entity_set_security;
   ret->set_time     = nr_pdcp_entity_set_time;
 
-  ret->delete = nr_pdcp_entity_delete;
-
+  ret->delete_entity = nr_pdcp_entity_delete;
+  
   ret->deliver_sdu = deliver_sdu;
   ret->deliver_sdu_data = deliver_sdu_data;
 
diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.h b/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.h
index fbcc2b96cd37d31cb35a02277721b4da6dee85d0..49e9c4142b5da3885d18e9bb2c809e23d3cd7164 100644
--- a/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.h
+++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.h
@@ -39,7 +39,7 @@ typedef struct nr_pdcp_entity_t {
   void (*recv_pdu)(struct nr_pdcp_entity_t *entity, char *buffer, int size);
   void (*recv_sdu)(struct nr_pdcp_entity_t *entity, char *buffer, int size,
                    int sdu_id);
-  void (*delete)(struct nr_pdcp_entity_t *entity);
+  void (*delete_entity)(struct nr_pdcp_entity_t *entity);
 
   /* set_security: pass -1 to integrity_algorithm / ciphering_algorithm
    *               to keep the current algorithm
diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c
index 7d1e2f493184ae675882b8f2aeaa900506b6b37e..74ca77a9c53c34ab8a11153b148a245cd4a520e1 100644
--- a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c
+++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c
@@ -36,7 +36,7 @@
 #include "pdcp.h"
 #include "LAYER2/nr_rlc/nr_rlc_oai_api.h"
 #include <openair3/ocp-gtpu/gtp_itf.h>
-#include "openair2/SDAP/nr_sdap/nr_sdap_gnb.h"
+#include "openair2/SDAP/nr_sdap/nr_sdap.h"
 
 #define TODO do { \
     printf("%s:%d:%s: todo\n", __FILE__, __LINE__, __FUNCTION__); \
@@ -438,9 +438,13 @@ static void *enb_tun_read_thread(void *_)
 
     ctxt.rnti = rnti;
 
-    pdcp_data_req(&ctxt, SRB_FLAG_NO, rb_id, RLC_MUI_UNDEFINED,
+    uint8_t qfi = 7;
+    boolean_t rqi = 0;
+    int pdusession_id = 10;
+
+    sdap_data_req(&ctxt, SRB_FLAG_NO, rb_id, RLC_MUI_UNDEFINED,
                   RLC_SDU_CONFIRM_NO, len, (unsigned char *)rx_buf,
-                  PDCP_TRANSMISSION_MODE_DATA, NULL, NULL);
+                  PDCP_TRANSMISSION_MODE_DATA, NULL, NULL, qfi, rqi, pdusession_id);
   }
 
   return NULL;
@@ -481,9 +485,13 @@ static void *ue_tun_read_thread(void *_)
 
     ctxt.rnti = rnti;
 
-    pdcp_data_req(&ctxt, SRB_FLAG_NO, rb_id, RLC_MUI_UNDEFINED,
+    boolean_t dc = SDAP_HDR_UL_DATA_PDU;
+    uint8_t qfi = 7;
+    int pdusession_id = 10;
+
+    sdap_data_req(&ctxt, SRB_FLAG_NO, rb_id, RLC_MUI_UNDEFINED,
                   RLC_SDU_CONFIRM_NO, len, (unsigned char *)rx_buf,
-                  PDCP_TRANSMISSION_MODE_DATA, NULL, NULL);
+                  PDCP_TRANSMISSION_MODE_DATA, NULL, NULL, qfi, dc, pdusession_id);
   }
 
   return NULL;
@@ -607,28 +615,20 @@ uint64_t nr_pdcp_module_init(uint64_t _pdcp_optmask, int id)
 static void deliver_sdu_drb(void *_ue, nr_pdcp_entity_t *entity,
                             char *buf, int size)
 {
-  extern int nas_sock_fd[];
-  int len;
   nr_pdcp_ue_t *ue = _ue;
-  MessageDef  *message_p;
-  uint8_t     *gtpu_buffer_p;
   int rb_id;
   int i;
 
   if (IS_SOFTMODEM_NOS1 || UE_NAS_USE_TUN) {
-    LOG_D(PDCP, "IP packet received, to be sent to TUN interface");
-
-    if(entity->has_sdapDLheader){
-      size -= SDAP_HDR_LENGTH;
-      len = write(nas_sock_fd[0], &buf[SDAP_HDR_LENGTH], size);
-    } else {
-      len = write(nas_sock_fd[0], buf, size);
-    }
-
-    if (len != size) {
-      LOG_E(PDCP, "%s:%d:%s: fatal error %d: %s\n", __FILE__, __LINE__, __FUNCTION__, errno, strerror(errno));
-    }
-    
+    LOG_D(PDCP, "IP packet received with size %d, to be sent to SDAP interface, UE rnti: %d\n", size, ue->rnti);
+    sdap_data_ind(entity->rb_id,
+                  entity->is_gnb,
+                  entity->has_sdap,
+                  entity->has_sdapULheader,
+                  entity->pdusession_id,
+                  ue->rnti,
+                  buf,
+                  size);
   }
   else{
     for (i = 0; i < 5; i++) {
@@ -644,31 +644,16 @@ static void deliver_sdu_drb(void *_ue, nr_pdcp_entity_t *entity,
 
     rb_found:
     {
-      int offset=0;
-      if (entity->has_sdap == 1 && entity->has_sdapULheader == 1)
-	offset = 1; // this is the offset of the SDAP header in bytes
-
-      message_p = itti_alloc_new_message_sized(TASK_PDCP_ENB, 0,
-					       GTPV1U_GNB_TUNNEL_DATA_REQ,
-					       sizeof(gtpv1u_gnb_tunnel_data_req_t) + size
-					       + GTPU_HEADER_OVERHEAD_MAX - offset);
-      AssertFatal(message_p != NULL, "OUT OF MEMORY");
-
-      gtpv1u_gnb_tunnel_data_req_t *req=&GTPV1U_GNB_TUNNEL_DATA_REQ(message_p);
-      gtpu_buffer_p = (uint8_t*)(req+1);
-      memcpy(gtpu_buffer_p+GTPU_HEADER_OVERHEAD_MAX, buf+offset, size-offset);
-      req->buffer              = gtpu_buffer_p;
-      req->length              = size-offset;
-      req->offset              = GTPU_HEADER_OVERHEAD_MAX;
-      req->rnti                = ue->rnti;
-      req->pdusession_id       = entity->pdusession_id;
-      if (offset==1) {
-        LOG_I(PDCP, "%s() (drb %d) SDAP header %2x\n",__func__, rb_id, buf[0]);
-        sdap_gnb_ul_header_handler(buf[0]); // Handler for the UL gNB SDAP Header
-      }
-      LOG_D(PDCP, "%s() (drb %d) sending message to gtp size %d\n", __func__, rb_id, size-offset);
-      itti_send_msg_to_task(TASK_GTPV1_U, INSTANCE_DEFAULT, message_p);
-   }
+      LOG_D(PDCP, "%s() (drb %d) sending message to SDAP size %d\n", __func__, rb_id, size);
+      sdap_data_ind(rb_id,
+                    ue->drb[rb_id-1]->is_gnb,
+                    ue->drb[rb_id-1]->has_sdap,
+                    ue->drb[rb_id-1]->has_sdapULheader,
+                    ue->drb[rb_id-1]->pdusession_id,
+                    ue->rnti,
+                    buf,
+                    size);
+    }
   }
 }
 
@@ -967,6 +952,9 @@ static void add_drb_am(int is_gnb, int rnti, struct NR_DRB_ToAddMod *s,
   int has_sdap = 0;
   int has_sdapULheader=0;
   int has_sdapDLheader=0;
+  boolean_t is_sdap_DefaultDRB = false;
+  NR_QFI_t *mappedQFIs2Add = NULL;
+  uint8_t mappedQFIs2AddCount=0;
   if (s->cnAssociation->present == NR_DRB_ToAddMod__cnAssociation_PR_eps_BearerIdentity)
      pdusession_id = s->cnAssociation->choice.eps_BearerIdentity;
   else {
@@ -975,9 +963,13 @@ static void add_drb_am(int is_gnb, int rnti, struct NR_DRB_ToAddMod *s,
       exit(-1);
     }
     pdusession_id = s->cnAssociation->choice.sdap_Config->pdu_Session;
-    has_sdap = 1;
     has_sdapULheader = s->cnAssociation->choice.sdap_Config->sdap_HeaderUL == NR_SDAP_Config__sdap_HeaderUL_present ? 1 : 0;
     has_sdapDLheader = s->cnAssociation->choice.sdap_Config->sdap_HeaderDL == NR_SDAP_Config__sdap_HeaderDL_present ? 1 : 0;
+    has_sdap = has_sdapULheader | has_sdapDLheader;
+    is_sdap_DefaultDRB = s->cnAssociation->choice.sdap_Config->defaultDRB == true ? 1 : 0;
+    mappedQFIs2Add = (NR_QFI_t*)s->cnAssociation->choice.sdap_Config->mappedQoS_FlowsToAdd->list.array[0]; 
+    mappedQFIs2AddCount = s->cnAssociation->choice.sdap_Config->mappedQoS_FlowsToAdd->list.count;
+    LOG_D(SDAP, "Captured mappedQoS_FlowsToAdd from RRC: %ld \n", *mappedQFIs2Add);
   }
   /* TODO(?): accept different UL and DL SN sizes? */
   if (sn_size_ul != sn_size_dl) {
@@ -1009,6 +1001,15 @@ static void add_drb_am(int is_gnb, int rnti, struct NR_DRB_ToAddMod *s,
     nr_pdcp_ue_add_drb_pdcp_entity(ue, drb_id, pdcp_drb);
 
     LOG_D(PDCP, "%s:%d:%s: added drb %d to ue rnti %x\n", __FILE__, __LINE__, __FUNCTION__, drb_id, rnti);
+
+    new_nr_sdap_entity(has_sdap,
+                       rnti,
+                       pdusession_id,
+                       is_sdap_DefaultDRB,
+                       drb_id,
+                       mappedQFIs2Add,
+                       mappedQFIs2AddCount);
+    LOG_D(SDAP, "Added SDAP entity to ue rnti %x with pdusession_id %d\n", rnti, pdusession_id);
   }
   nr_pdcp_manager_unlock(nr_pdcp_ue_manager);
 }
@@ -1140,7 +1141,7 @@ void nr_DRB_preconfiguration(uint16_t crnti)
   NR_DRB_ToAddMod_t *drb_ToAddMod = calloc(1,sizeof(*drb_ToAddMod));
   drb_ToAddMod->cnAssociation = calloc(1,sizeof(*drb_ToAddMod->cnAssociation));
   drb_ToAddMod->cnAssociation->present = NR_DRB_ToAddMod__cnAssociation_PR_eps_BearerIdentity;
-  drb_ToAddMod->cnAssociation->choice.eps_BearerIdentity= 5;
+  drb_ToAddMod->cnAssociation->choice.eps_BearerIdentity= 10;
   drb_ToAddMod->drb_Identity = 1;
   drb_ToAddMod->reestablishPDCP = NULL;
   drb_ToAddMod->recoverPDCP = NULL;
@@ -1450,3 +1451,10 @@ void nr_pdcp_tick(int frame, int subframe)
     nr_pdcp_wakeup_timer_thread(nr_pdcp_current_time);
   }
 }
+
+/*
+ * For the SDAP API
+ */
+nr_pdcp_ue_manager_t *nr_pdcp_sdap_get_ue_manager(){
+    return nr_pdcp_ue_manager;
+}
diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_ue_manager.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_ue_manager.c
index 160c5ebb22697c70ee2b16685a97bbdd71834fb5..1f21593c630387bcfbe2620acca8a4e5132d8fad 100644
--- a/openair2/LAYER2/nr_pdcp/nr_pdcp_ue_manager.c
+++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_ue_manager.c
@@ -127,11 +127,11 @@ void nr_pdcp_manager_remove_ue(nr_pdcp_ue_manager_t *_m, int rnti)
 
   for (j = 0; j < 2; j++)
     if (ue->srb[j] != NULL)
-      ue->srb[j]->delete(ue->srb[j]);
+      ue->srb[j]->delete_entity(ue->srb[j]);
 
   for (j = 0; j < 5; j++)
     if (ue->drb[j] != NULL)
-      ue->drb[j]->delete(ue->drb[j]);
+      ue->drb[j]->delete_entity(ue->drb[j]);
 
   free(ue);
 
diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_entity_am.c b/openair2/LAYER2/nr_rlc/nr_rlc_entity_am.c
index af8cb5715adbb67ab2ca37d47bf4e5d46853ad64..2382db267fe68283e8ba2c251ec7d49966246daa 100644
--- a/openair2/LAYER2/nr_rlc/nr_rlc_entity_am.c
+++ b/openair2/LAYER2/nr_rlc/nr_rlc_entity_am.c
@@ -103,36 +103,6 @@ static int segment_already_received(nr_rlc_entity_am_t *entity,
   return size <= 0;
 }
 
-static void consider_retransmission(nr_rlc_entity_am_t *entity,
-    nr_rlc_sdu_segment_t *cur, int update_retx)
-{
-  if (update_retx)
-    cur->sdu->retx_count++;
-
-  /* let's report max RETX reached for all retx_count >= max_retx_threshold
-   * (specs say to report if retx_count == max_retx_threshold).
-   * Upper layers should react (radio link failure), so no big deal actually.
-   */
-  if (update_retx && cur->sdu->retx_count >= entity->max_retx_threshold) {
-    entity->common.max_retx_reached(entity->common.max_retx_reached_data,
-                                    (nr_rlc_entity_t *)entity);
-  }
-
-  /* let's put in retransmit list even if we are over max_retx_threshold.
-   * upper layers should deal with this condition, internally it's better
-   * for the RLC code to keep going with this segment (we only remove
-   * a segment that was ACKed)
-   */ 
-  LOG_D(RLC, "RLC segment to be added at the ReTx list \n"); 
-  nr_rlc_sdu_segment_list_append(&entity->retransmit_list,
-                                 &entity->retransmit_end,
-                                 cur);
-
-  /* update buffer status */
-  entity->common.bstatus.retx_size += compute_pdu_header_size(entity, cur)
-                                      + cur->size;
-}
-
 /* checks that all the bytes of the SDU sn have been received (but SDU
  * has not been already processed)
  */
@@ -315,81 +285,6 @@ static void reception_actions(nr_rlc_entity_am_t *entity, nr_rlc_pdu_t *pdu)
   }
 }
 
-static void process_received_ack(nr_rlc_entity_am_t *entity, int ack_sn)
-{
-  nr_rlc_sdu_segment_t head;
-  nr_rlc_sdu_segment_t *cur;
-  nr_rlc_sdu_segment_t *prev;
-  unsigned char sn_set[32768];  /* used to dec retx_count only once per sdu */
-
-  memset(sn_set, 0, 32768);
-
-#define IS_SN_SET(b) (sn_set[(b)/8] & (1 << ((b) % 8)))
-#define SET_SN(b) do { sn_set[(b)/8] |= (1 << ((b) % 8)); } while (0)
-
-  /* put SDUs from wait and retransmit lists with SN < 'ack_sn' to ack_list */
-
-  /* process wait list */
-  head.next = entity->wait_list;
-  prev = &head;
-  cur = entity->wait_list;
-  while (cur != NULL) {
-    if (sn_compare_tx(entity, cur->sdu->sn, ack_sn) < 0) {
-      /* remove from wait list */
-      prev->next = cur->next;
-      /* put the PDU in the ack list */
-      entity->ack_list = nr_rlc_sdu_segment_list_add(sn_compare_tx, entity,
-                                                     entity->ack_list, cur);
-      entity->wait_end = prev;
-      cur = prev->next;
-    } else {
-      entity->wait_end = cur;
-      prev = cur;
-      cur = cur->next;
-    }
-  }
-  entity->wait_list = head.next;
-  if (entity->wait_list == NULL)
-    entity->wait_end = NULL;
-
-  /* process retransmit list */
-  head.next = entity->retransmit_list;
-  prev = &head;
-  cur = entity->retransmit_list;
-  while (cur != NULL) {
-    if (sn_compare_tx(entity, cur->sdu->sn, ack_sn) < 0) {
-      /* dec. retx_count in case we put this segment back in retransmit list
-       * in 'process_received_nack'
-       * do it only once per SDU
-       */
-      if (!IS_SN_SET(cur->sdu->sn)) {
-        cur->sdu->retx_count--;
-        SET_SN(cur->sdu->sn);
-      }
-      /* remove from retransmit list */
-      prev->next = cur->next;
-      /* update buffer status */
-      entity->common.bstatus.retx_size -= compute_pdu_header_size(entity, cur)
-                                          + cur->size;
-      /* put the PDU in the ack list */
-      entity->ack_list = nr_rlc_sdu_segment_list_add(sn_compare_tx, entity,
-                                                     entity->ack_list, cur);
-      entity->retransmit_end = prev;
-      cur = prev->next;
-    } else {
-      entity->retransmit_end = cur;
-      prev = cur;
-      cur = cur->next;
-    }
-  }
-  entity->retransmit_list = head.next;
-  if (entity->retransmit_list == NULL)
-    entity->retransmit_end = NULL;
-
-#undef IS_BIT_SET
-#undef SET_BIT
-}
-
 static int so_overlap(int s1, int e1, int s2, int e2)
 {
   if (s1 < s2) {
@@ -402,136 +297,375 @@ static int so_overlap(int s1, int e1, int s2, int e2)
   return 0;
 }
 
-static void process_nack_sn(nr_rlc_entity_am_t *entity, int nack_sn,
-                            int so_start, int so_end, unsigned char *sn_set)
+static void process_control_pdu(nr_rlc_entity_am_t *entity,
+                                char *buffer, int size)
 {
-  /* put all SDU segments with SN == 'sn' and with an overlapping so start/end
-   * to the retransmit list
-   * source lists are ack list and wait list.
-   * Not sure if we should consider wait list, isn't the other end supposed
-   * to only NACK SNs lower than the ACK SN sent in the status PDU, in which
-   * case all potential SDU segments should all be in ack list when calling
-   * the current function? in doubt let's accept anything and thus process
-   * also wait list.
-   */
-  nr_rlc_sdu_segment_t head;
-  nr_rlc_sdu_segment_t *cur;
-  nr_rlc_sdu_segment_t *prev;
+#define R(d) do { if (nr_rlc_pdu_decoder_in_error(&d)) goto err; } while (0)
+  nr_rlc_pdu_decoder_t decoder;
+  int i;
+  int cpt;
+  int ack_sn;
+  int nack_sn;
+  int e1;
+  int e2;
+  int e3;
+  int so_start;
+  int so_end;
+  int range;
+  int prev_nack_sn = -1;
+  int prev_so_start;
+  int prev_so_end;
+  int tx_next_ack;
+  nr_rlc_sdu_segment_t *cur_wait_list;
+  nr_rlc_sdu_segment_t *prev_wait_list;
+  nr_rlc_sdu_segment_t *end_wait_list = NULL;
+  nr_rlc_sdu_segment_t head_wait_list;
+  nr_rlc_sdu_segment_t *cur_retransmit_list;
+  nr_rlc_sdu_segment_t *new_retransmit_list;
+  nr_rlc_sdu_segment_t head_retransmit_list;
+
+  head_wait_list.next = entity->wait_list;
+  cur_wait_list       = entity->wait_list;
+  prev_wait_list      = &head_wait_list;
+
+  head_retransmit_list.next = NULL;
+  cur_retransmit_list = entity->retransmit_list;
+  new_retransmit_list = &head_retransmit_list;
 
-#define IS_SN_SET(b) (sn_set[(b)/8] & (1 << ((b) % 8)))
-#define SET_SN(b) do { sn_set[(b)/8] |= (1 << ((b) % 8)); } while (0)
+  nr_rlc_pdu_decoder_init(&decoder, buffer, size);
+  nr_rlc_pdu_decoder_get_bits(&decoder, 1); R(decoder); /* dc */
 
-  /* check that tx_next_ack <= sn < tx_next */
-  if (!(sn_compare_tx(entity, entity->tx_next_ack, nack_sn) <= 0 &&
-        sn_compare_tx(entity, nack_sn, entity->tx_next) < 0))
-    return;
+  cpt = nr_rlc_pdu_decoder_get_bits(&decoder, 3); R(decoder);
+  if (cpt != 0) {
+    LOG_E(RLC, "%s:%d:%s: warning: discard PDU, CPT not 0 (%d)\n",
+          __FILE__, __LINE__, __FUNCTION__, cpt);
+    goto err;
+  }
+  ack_sn = nr_rlc_pdu_decoder_get_bits(&decoder, entity->sn_field_length); R(decoder);
+  e1 = nr_rlc_pdu_decoder_get_bits(&decoder, 1); R(decoder);
+  /* r bits */
+  if (entity->sn_field_length == 18) {
+    nr_rlc_pdu_decoder_get_bits(&decoder, 1); R(decoder);
+  } else {
+    nr_rlc_pdu_decoder_get_bits(&decoder, 7); R(decoder);
+  }
 
-  /* process wait list */
-  head.next = entity->wait_list;
-  prev = &head;
-  cur = entity->wait_list;
-  while (cur != NULL) {
-    if (cur->sdu->sn == nack_sn &&
-        so_overlap(so_start, so_end, cur->so, cur->so + cur->size - 1)) {
-      /* remove from wait list */
-      prev->next = cur->next;
-      cur->next = NULL;
-      /* consider the SDU segment for retransmission */
-      consider_retransmission(entity, cur, !IS_SN_SET(cur->sdu->sn));
-      SET_SN(cur->sdu->sn);
-      entity->wait_end = prev;
-      cur = prev->next;
+  /* 38.322 5.3.3.3 says to stop t_poll_retransmit if a ACK or NACK is
+   * received for the SN 'poll_sn' - check ACK case (NACK done below)
+   */
+  if (sn_compare_tx(entity, entity->poll_sn, ack_sn) < 0)
+    entity->t_poll_retransmit_start = 0;
+
+  while (e1) {
+    nack_sn = nr_rlc_pdu_decoder_get_bits(&decoder, entity->sn_field_length); R(decoder);
+    e1 = nr_rlc_pdu_decoder_get_bits(&decoder, 1); R(decoder);
+    e2 = nr_rlc_pdu_decoder_get_bits(&decoder, 1); R(decoder);
+    e3 = nr_rlc_pdu_decoder_get_bits(&decoder, 1); R(decoder);
+    /* r bits */
+    if (entity->sn_field_length == 18) {
+      nr_rlc_pdu_decoder_get_bits(&decoder, 3); R(decoder);
     } else {
-      entity->wait_end = cur;
-      prev = cur;
-      cur = cur->next;
+      nr_rlc_pdu_decoder_get_bits(&decoder, 1); R(decoder);
     }
-  }
-  entity->wait_list = head.next;
-  if (entity->wait_list == NULL)
-    entity->wait_end = NULL;
-
-  /* process ack list */
-  head.next = entity->ack_list;
-  prev = &head;
-  cur = entity->ack_list;
-  while (cur != NULL) {
-    if (cur->sdu->sn == nack_sn &&
-        so_overlap(so_start, so_end, cur->so, cur->so + cur->size - 1)) {
-      /* remove from ack list */
-      prev->next = cur->next;
-      cur->next = NULL;
-      /* consider the SDU segment for retransmission */
-      consider_retransmission(entity, cur, !IS_SN_SET(cur->sdu->sn));
-      SET_SN(cur->sdu->sn);
-      cur = prev->next;
+    if (e2) {
+      so_start = nr_rlc_pdu_decoder_get_bits(&decoder, 16); R(decoder);
+      so_end = nr_rlc_pdu_decoder_get_bits(&decoder, 16); R(decoder);
     } else {
-      prev = cur;
-      cur = cur->next;
+      so_start = 0;
+      so_end = 0xffff;
     }
-  }
-  entity->ack_list = head.next;
+    if (e3) {
+      range = nr_rlc_pdu_decoder_get_bits(&decoder, 8); R(decoder);
+    } else {
+      range = 1;
+    }
+    /* special value 0xffff indicates 'all bytes to the end' */
+    if (so_end == 0xffff)
+      so_end = -1;
 
-#undef IS_BIT_SET
-#undef SET_BIT
-}
+    /* process nacks */
+    for (i = 0; i < range; i++) {
+      int cur_nack_sn  = (nack_sn + i) % entity->sn_modulus;
+      int cur_so_start = i == 0 ?         so_start : 0;
+      int cur_so_end   = i == range - 1 ? so_end : -1;
 
-static void process_received_nack(nr_rlc_entity_am_t *entity, int nack_sn,
-                                  int so_start, int so_end, int range,
-                                  unsigned char *sn_set)
-{
-  int i;
+      /* check that current nack is > previous nack and <= ack
+       * if not then skip it and all following nacks, and
+       * do not touch t_poll_retransmit
+       */
+      if (prev_nack_sn != -1) {
+        int cmp = sn_compare_tx(entity, cur_nack_sn, prev_nack_sn);
+        if (cmp < 0
+            || (cmp == 0
+                && (prev_so_end == -1
+                    || cur_so_start <= prev_so_end))) {
+          LOG_E(RLC, "%s:%d:%s: bad NACK (nack sn %d so start/end %d/%d, previous nack sn %d so start/end %d/%d), skip it and all following NACKs\n",
+                __FILE__, __LINE__, __FUNCTION__,
+                cur_nack_sn, cur_so_start, cur_so_end,
+                prev_nack_sn, prev_so_start, prev_so_end);
+          goto nacks_done;
+        }
+      }
+      if (sn_compare_tx(entity, cur_nack_sn, ack_sn) > 0) {
+        LOG_E(RLC, "%s:%d:%s: bad NACK (nack %d ack %d), skip it and all following NACKs\n",
+              __FILE__, __LINE__, __FUNCTION__,
+              cur_nack_sn, ack_sn);
+        goto nacks_done;
+      }
 
-  for (i = 0; i < range; i++)
-    process_nack_sn(entity, (nack_sn + i) % entity->sn_modulus,
-                    i == 0 ?         so_start : 0,
-                    i == range - 1 ? so_end : -1,
-                    sn_set);
-}
+process_next_pdu:
+      /* process smallest SN either from wait_list or retransmit list */
+      if (cur_wait_list == NULL && cur_retransmit_list == NULL)
+        goto lists_over;
+      if (cur_wait_list == NULL)
+        goto process_retransmit_list_head;
+      if (cur_retransmit_list == NULL)
+        goto process_wait_list_head;
+      if (cur_wait_list->sdu->sn < cur_retransmit_list->sdu->sn
+          || (cur_wait_list->sdu->sn == cur_retransmit_list->sdu->sn &&
+              cur_wait_list->so < cur_retransmit_list->so))
+        goto process_wait_list_head;
+      goto process_retransmit_list_head;
+
+process_wait_list_head:
+      /* if nack overlaps with current segment, put it in retransmit list */
+      if (cur_wait_list->sdu->sn == cur_nack_sn
+          && so_overlap(cur_so_start, cur_so_end,
+                        cur_wait_list->so,
+                        cur_wait_list->so + cur_wait_list->size - 1)) {
+        prev_wait_list->next = cur_wait_list->next;
+        if (cur_wait_list == entity->wait_end)
+          end_wait_list = prev_wait_list;
+        cur_wait_list->next = NULL;
+        new_retransmit_list->next = cur_wait_list;
+        new_retransmit_list = cur_wait_list;
+        /* increase retx count. Don't care about segmentation, so maybe we
+         * increase too much.
+         */
+        cur_wait_list->sdu->retx_count++;
+        /* report max RETX reached for all retx_count >= max_retx_threshold
+         * (specs say to report if retx_count == max_retx_threshold).
+         * Upper layers should react (radio link failure), so no big deal.
+         * We deal with segmentation by requiring
+         * retx_count >= max_retx_threshold * number of segments.
+         * We may report max RETX reached too late/early. To be refined if
+         * this is a problem.
+         */
+        if (cur_wait_list->sdu->retx_count
+              >= entity->max_retx_threshold * cur_wait_list->sdu->ref_count)
+          entity->common.max_retx_reached(entity->common.max_retx_reached_data,
+                                          (nr_rlc_entity_t *)entity);
+        /* update buffer status */
+        entity->common.bstatus.retx_size += compute_pdu_header_size(entity, cur_wait_list)
+                                            + cur_wait_list->size;
+        /* and go process the next pdu, still for the current nack */
+        cur_wait_list = prev_wait_list->next;
+        goto process_next_pdu;
+      }
 
-static int sdu_segment_in_ack_list_full(nr_rlc_sdu_segment_t *sdu)
-{
-  int target_count = sdu->sdu->ref_count;
-  int actual_count = 0;
-  int sn = sdu->sdu->sn;
+      /* if current segment SN > current NACK, we can't classify it yet */
+      if (sn_compare_tx(entity, cur_wait_list->sdu->sn, cur_nack_sn) > 0
+          || (cur_wait_list->sdu->sn == cur_nack_sn
+              && cur_wait_list->so > cur_so_start))
+        goto done_nack;
 
-  while (sdu != NULL && sdu->sdu->sn == sn) {
-    actual_count++;
-    sdu = sdu->next;
-  }
+      /* if current segment is acked, free it, indicate successful delivery
+       * if fully acked
+       */
+      if (sn_compare_tx(entity, cur_wait_list->sdu->sn, ack_sn) < 0) {
+        nr_rlc_sdu_segment_t *cur = cur_wait_list;
+        int upper_layer_id = cur->sdu->upper_layer_id;
+        int sdu_size = cur->sdu->size;
+        cur_wait_list = cur_wait_list->next;
+        prev_wait_list->next = cur_wait_list;
+        if (cur_wait_list == entity->wait_end)
+          end_wait_list = prev_wait_list;
+        if (nr_rlc_free_sdu_segment(cur)) {
+          entity->tx_size -= sdu_size;
+          entity->common.sdu_successful_delivery(
+              entity->common.sdu_successful_delivery_data,
+              (nr_rlc_entity_t *)entity, upper_layer_id);
+        }
+        goto process_next_pdu;
+      }
 
-  return actual_count == target_count;
-}
+      /* if current segment SN > ack_sn, we're done with this list */
+      if (sn_compare_tx(entity, cur_wait_list->sdu->sn, ack_sn) > 0) {
+        cur_wait_list = NULL;
+        goto process_next_pdu;
+      }
 
-static void finalize_ack_nack_processing(nr_rlc_entity_am_t *entity)
-{
-  nr_rlc_sdu_segment_t *cur = entity->ack_list;
-  int sn;
+      /* current segment SN == ack_sn, skip this segment and move to the next.
+       * Not sure if correct, can we get a nack_sn == ack_sn? 38.322 5.3.4 says
+       * "set the ACK_SN to the SN of the next not received RLC SDU which is
+       * not indicated as missing in the resulting STATUS PDU." Is it okay to
+       * receive some NACK for a given SN and an ACK == this SN? I can see a
+       * case where it's possible (only parts of an SN were received and the
+       * TB is too small to report the several NACKs for this SN, then we
+       * can't set ACK = SN+1 but in this case, shouldn't we skip sending
+       * NACKs for this SN and only send ACK = SN? our current implementation
+       * does send both NACKs and ACK, see function generate_status()).
+       */
+      prev_wait_list = cur_wait_list;
+      cur_wait_list = cur_wait_list->next;
+      goto process_next_pdu;
+
+process_retransmit_list_head:
+      /* if nack overlaps with current segment, leave it in retransmit list */
+      if (cur_retransmit_list->sdu->sn == cur_nack_sn
+          && so_overlap(cur_so_start, cur_so_end,
+                        cur_retransmit_list->so,
+                        cur_retransmit_list->so + cur_retransmit_list->size - 1)) {
+        new_retransmit_list->next = cur_retransmit_list;
+        cur_retransmit_list = cur_retransmit_list->next;
+        new_retransmit_list = new_retransmit_list->next;
+        new_retransmit_list->next = NULL;
+        /* go process the next pdu, still for the current nack */
+        goto process_next_pdu;
+      }
 
-  /* - send indication of successful delivery for all consecutive acked SDUs
-   *   starting from tx_next_ack. Also free them.
-   * - update tx_next_ack to the next SN not acked yet
-   */
-  /* todo: send indication of successful delivery as soon as possible as
-   *       the specs say (38.322 5.2.3.1.1). As the code is, if we receive
-   *       ack for SN+2 we won't indicate successful delivery before
-   *       SN+1 has been indicated.
+      /* if current segment SN > current NACK, we can't classify it yet */
+      if (sn_compare_tx(entity, cur_retransmit_list->sdu->sn, cur_nack_sn) > 0
+          || (cur_retransmit_list->sdu->sn == cur_nack_sn
+              && cur_retransmit_list->so > cur_so_start))
+        goto done_nack;
+
+      /* if current segment is acked, free it, indicate successful delivery
+       * if fully acked
+       */
+      if (sn_compare_tx(entity, cur_retransmit_list->sdu->sn, ack_sn) < 0) {
+        nr_rlc_sdu_segment_t *cur = cur_retransmit_list;
+        int upper_layer_id = cur->sdu->upper_layer_id;
+        int sdu_size = cur->sdu->size;
+        cur_retransmit_list = cur_retransmit_list->next;
+        /* update buffer status */
+        entity->common.bstatus.retx_size -= compute_pdu_header_size(entity, cur)
+                                            + cur->size;
+        if (nr_rlc_free_sdu_segment(cur)) {
+          entity->tx_size -= sdu_size;
+          entity->common.sdu_successful_delivery(
+              entity->common.sdu_successful_delivery_data,
+              (nr_rlc_entity_t *)entity, upper_layer_id);
+        }
+        goto process_next_pdu;
+      }
+
+      /* current segment SN >= ack_sn
+       * if the wait list is empty, then put the remaining retransmit list at
+       * the end of the new retransmit list (just a speedup)
+       * if not, put only this segment
+       */
+      if (cur_wait_list == NULL) {
+        new_retransmit_list->next = cur_retransmit_list;
+        cur_retransmit_list = NULL;
+        goto lists_over;
+      }
+      new_retransmit_list->next = cur_retransmit_list;
+      cur_retransmit_list = cur_retransmit_list->next;
+      new_retransmit_list = new_retransmit_list->next;
+      new_retransmit_list->next = NULL;
+      goto process_next_pdu;
+
+done_nack:
+      prev_nack_sn  = cur_nack_sn;
+      prev_so_start = cur_so_start;
+      prev_so_end   = cur_so_end;
+    } /* for (i = 0; i < range; i++) */
+
+lists_over:
+    /* 38.322 5.3.3.3 says to stop t_poll_retransmit if a ACK or NACK is
+     * received for the SN 'poll_sn' - check NACK case (ACK done above)
+     */
+    if (sn_compare_tx(entity, nack_sn, entity->poll_sn) <= 0 &&
+        sn_compare_tx(entity, entity->poll_sn, (nack_sn + range) % entity->sn_modulus) < 0)
+      entity->t_poll_retransmit_start = 0;
+  } /* while (e1) */
+
+nacks_done:
+  /* nacks done, finish with ack */
+  /* we may report successful delivery out of order, if it's a problem
+   * then we can have a single loop and deal with the smallest sn of
+   * the current head of wait list and the current head of retransmit list.
+   * (It's simpler to process those two lists the one after the other.)
    */
-  while (cur != NULL && cur->sdu->sn == entity->tx_next_ack &&
-         sdu_segment_in_ack_list_full(cur)) {
-    entity->tx_size -= cur->sdu->size;
-    sn = cur->sdu->sn;
-    entity->common.sdu_successful_delivery(
-        entity->common.sdu_successful_delivery_data,
-        (nr_rlc_entity_t *)entity, cur->sdu->upper_layer_id);
-    while (cur != NULL && cur->sdu->sn == sn) {
-      nr_rlc_sdu_segment_t *s = cur;
-      cur = cur->next;
-      nr_rlc_free_sdu_segment(s);
+  /* deal with wait list */
+  while (cur_wait_list != NULL
+         && sn_compare_tx(entity, cur_wait_list->sdu->sn, ack_sn) < 0) {
+    /* current segment is acked, free it, indicate successful delivery
+     * if fully acked
+     */
+    nr_rlc_sdu_segment_t *cur = cur_wait_list;
+    int upper_layer_id = cur->sdu->upper_layer_id;
+    int sdu_size = cur->sdu->size;
+    prev_wait_list->next = cur_wait_list->next;
+    if (cur_wait_list == entity->wait_end)
+      end_wait_list = prev_wait_list;
+    cur_wait_list = cur_wait_list->next;
+    if (nr_rlc_free_sdu_segment(cur)) {
+      entity->tx_size -= sdu_size;
+      entity->common.sdu_successful_delivery(
+          entity->common.sdu_successful_delivery_data,
+          (nr_rlc_entity_t *)entity, upper_layer_id);
+    }
+  }
+  /* deal with retransmit list */
+  while (cur_retransmit_list != NULL
+         && sn_compare_tx(entity, cur_retransmit_list->sdu->sn, ack_sn) < 0) {
+    /* current segment is acked, free it, indicate successful delivery
+     * if fully acked
+     */
+    nr_rlc_sdu_segment_t *cur = cur_retransmit_list;
+    int upper_layer_id = cur->sdu->upper_layer_id;
+    int sdu_size = cur->sdu->size;
+    cur_retransmit_list = cur_retransmit_list->next;
+    /* update buffer status */
+    entity->common.bstatus.retx_size -= compute_pdu_header_size(entity, cur)
+                                        + cur->size;
+    if (nr_rlc_free_sdu_segment(cur)) {
+      entity->tx_size -= sdu_size;
+      entity->common.sdu_successful_delivery(
+          entity->common.sdu_successful_delivery_data,
+          (nr_rlc_entity_t *)entity, upper_layer_id);
     }
-    entity->ack_list = cur;
-    entity->tx_next_ack = (entity->tx_next_ack + 1) % entity->sn_modulus;
   }
+
+  new_retransmit_list->next = cur_retransmit_list;
+
+  entity->wait_list       = head_wait_list.next;
+  entity->retransmit_list = head_retransmit_list.next;
+
+  if (end_wait_list != NULL) {
+    if (end_wait_list == &head_wait_list)
+      entity->wait_end = NULL;
+    else
+      entity->wait_end = end_wait_list;
+  }
+
+  /* update tx_next_ack */
+  /* 38.322 5.2.3.1.1 says "set TX_Next_Ack equal to the SN of the RLC SDU
+   * with the smallest SN, whose SN falls within the range
+   * TX_Next_Ack <= SN <= TX_Next and for which a positive acknowledgment
+   * has not been received yet.
+   */
+  /* let's start from highest possible value and go down as needed */
+  tx_next_ack = entity->tx_next;
+  if (entity->wait_list != NULL
+      && sn_compare_tx(entity, entity->wait_list->sdu->sn, tx_next_ack) < 0)
+    tx_next_ack = entity->wait_list->sdu->sn;
+  if (entity->retransmit_list != NULL
+      && sn_compare_tx(entity, entity->retransmit_list->sdu->sn, tx_next_ack) < 0)
+    tx_next_ack = entity->retransmit_list->sdu->sn;
+  if (sn_compare_tx(entity, ack_sn, tx_next_ack) < 0)
+    tx_next_ack = ack_sn;
+  entity->tx_next_ack = tx_next_ack;
+
+  return;
+
+err:
+  LOG_E(RLC, "%s:%d:%s: error decoding PDU, NR RLC entity in inconsistent state\n",
+        __FILE__, __LINE__, __FUNCTION__);
+
+#undef R
 }
 
 void nr_rlc_entity_am_recv_pdu(nr_rlc_entity_t *_entity,
@@ -540,7 +674,6 @@ void nr_rlc_entity_am_recv_pdu(nr_rlc_entity_t *_entity,
 #define R(d) do { if (nr_rlc_pdu_decoder_in_error(&d)) goto err; } while (0)
   nr_rlc_entity_am_t *entity = (nr_rlc_entity_am_t *)_entity;
   nr_rlc_pdu_decoder_t decoder;
-  nr_rlc_pdu_decoder_t control_decoder;
   nr_rlc_pdu_t *pdu;
   int dc;
   int p = 0;
@@ -551,23 +684,11 @@ void nr_rlc_entity_am_recv_pdu(nr_rlc_entity_t *_entity,
   int is_first;
   int is_last;
 
-  int cpt;
-  int e1;
-  int e2;
-  int e3;
-  int ack_sn;
-  int nack_sn;
-  int so_start;
-  int so_end;
-  int range;
-  int control_e1;
-  int control_e2;
-  int control_e3;
-  unsigned char sn_set[32768];  /* used to dec retx_count only once per sdu */
-
   nr_rlc_pdu_decoder_init(&decoder, buffer, size);
   dc = nr_rlc_pdu_decoder_get_bits(&decoder, 1); R(decoder);
-  if (dc == 0) goto control;
+
+  if (dc == 0)
+    return process_control_pdu(entity, buffer, size);
 
   /* data PDU */
   p  = nr_rlc_pdu_decoder_get_bits(&decoder, 1); R(decoder);
@@ -596,20 +717,20 @@ void nr_rlc_entity_am_recv_pdu(nr_rlc_entity_t *_entity,
 
   /* dicard PDU if no data */
   if (data_size <= 0) {
-    LOG_W(RLC, "%s:%d:%s: warning: discard PDU, no data\n",
+    LOG_D(RLC, "%s:%d:%s: warning: discard PDU, no data\n",
           __FILE__, __LINE__, __FUNCTION__);
     goto discard;
   }
 
   /* dicard PDU if rx buffer is full */
   if (entity->rx_size + data_size > entity->rx_maxsize) {
-    LOG_W(RLC, "%s:%d:%s: warning: discard PDU, RX buffer full\n",
+    LOG_D(RLC, "%s:%d:%s: warning: discard PDU, RX buffer full\n",
           __FILE__, __LINE__, __FUNCTION__);
     goto discard;
   }
 
   if (!sn_in_recv_window(entity, sn)) {
-    LOG_W(RLC, "%s:%d:%s: warning: discard PDU, sn out of window (sn %d rx_next %d)\n",
+    LOG_D(RLC, "%s:%d:%s: warning: discard PDU, sn out of window (sn %d rx_next %d)\n",
           __FILE__, __LINE__, __FUNCTION__,
            sn, entity->rx_next);
     goto discard;
@@ -617,7 +738,7 @@ void nr_rlc_entity_am_recv_pdu(nr_rlc_entity_t *_entity,
 
   /* discard segment if all the bytes of the segment are already there */
   if (segment_already_received(entity, sn, so, data_size)) {
-    LOG_W(RLC, "%s:%d:%s: warning: discard PDU, already received\n",
+    LOG_D(RLC, "%s:%d:%s: warning: discard PDU, already received\n",
           __FILE__, __LINE__, __FUNCTION__);
     goto discard;
   }
@@ -650,118 +771,6 @@ void nr_rlc_entity_am_recv_pdu(nr_rlc_entity_t *_entity,
 
   return;
 
-control:
-  cpt = nr_rlc_pdu_decoder_get_bits(&decoder, 3); R(decoder);
-  if (cpt != 0) {
-    LOG_W(RLC, "%s:%d:%s: warning: discard PDU, CPT not 0 (%d)\n",
-          __FILE__, __LINE__, __FUNCTION__, cpt);
-    goto discard;
-  }
-  ack_sn = nr_rlc_pdu_decoder_get_bits(&decoder, entity->sn_field_length); R(decoder);
-  e1 = nr_rlc_pdu_decoder_get_bits(&decoder, 1); R(decoder);
-  /* r bits */
-  if (entity->sn_field_length == 18) {
-    nr_rlc_pdu_decoder_get_bits(&decoder, 1); R(decoder);
-  } else {
-    nr_rlc_pdu_decoder_get_bits(&decoder, 7); R(decoder);
-  }
-
-  /* let's try to parse the control PDU once to check consistency */
-  control_decoder = decoder;
-  control_e1 = e1;
-  while (control_e1) {
-    nack_sn = nr_rlc_pdu_decoder_get_bits(&control_decoder, entity->sn_field_length); R(control_decoder);
-    control_e1 = nr_rlc_pdu_decoder_get_bits(&control_decoder, 1); R(control_decoder);
-    control_e2 = nr_rlc_pdu_decoder_get_bits(&control_decoder, 1); R(control_decoder);
-    control_e3 = nr_rlc_pdu_decoder_get_bits(&control_decoder, 1); R(control_decoder);
-    /* r bits */
-    if (entity->sn_field_length == 18) {
-      nr_rlc_pdu_decoder_get_bits(&control_decoder, 3); R(control_decoder);
-    } else {
-      nr_rlc_pdu_decoder_get_bits(&control_decoder, 1); R(control_decoder);
-    }
-    /* check range and so_start/so_end consistency */
-    if (control_e2) {
-      so_start = nr_rlc_pdu_decoder_get_bits(&control_decoder, 16); R(control_decoder);
-      so_end = nr_rlc_pdu_decoder_get_bits(&control_decoder, 16); R(control_decoder);
-    } else {
-      so_start = 0;
-      so_end = 0xffff;
-    }
-    if (control_e3) {
-      range = nr_rlc_pdu_decoder_get_bits(&control_decoder, 8); R(control_decoder);
-    } else {
-      range = 1;
-    }
-    if (range < 1) {
-      LOG_E(RLC, "%s:%d:%s: error, bad 'range' in RLC NACK (sn %d)\n",
-            __FILE__, __LINE__, __FUNCTION__, nack_sn);
-      goto err;
-    }
-    /* so_start can be > so_end if more than one range; they don't refer
-     * to the same PDU then
-     */
-    if (range == 1 && so_end < so_start) {
-      LOG_E(RLC, "%s:%d:%s: error, bad so start/end (sn %d)\n",
-            __FILE__, __LINE__, __FUNCTION__, nack_sn);
-      goto err;
-    }
-  }
-
-  /* 38.322 5.3.3.3 says to stop t_poll_retransmit if a ACK or NACK is
-   * received for the SN 'poll_sn' - check ACK case (NACK done below)
-   */
-  if (sn_compare_tx(entity, entity->poll_sn, ack_sn) < 0)
-    entity->t_poll_retransmit_start = 0;
-
-  /* at this point, accept the PDU even if the actual values
-   * may be incorrect (eg. if so_start > so_end)
-   */
-  process_received_ack(entity, ack_sn);
-
-  if (e1)
-    memset(sn_set, 0, 32768);
-
-  while (e1) {
-    nack_sn = nr_rlc_pdu_decoder_get_bits(&decoder, entity->sn_field_length); R(decoder);
-    e1 = nr_rlc_pdu_decoder_get_bits(&decoder, 1); R(decoder);
-    e2 = nr_rlc_pdu_decoder_get_bits(&decoder, 1); R(decoder);
-    e3 = nr_rlc_pdu_decoder_get_bits(&decoder, 1); R(decoder);
-    /* r bits */
-    if (entity->sn_field_length == 18) {
-      nr_rlc_pdu_decoder_get_bits(&decoder, 3); R(decoder);
-    } else {
-      nr_rlc_pdu_decoder_get_bits(&decoder, 1); R(decoder);
-    }
-    if (e2) {
-      so_start = nr_rlc_pdu_decoder_get_bits(&decoder, 16); R(decoder);
-      so_end = nr_rlc_pdu_decoder_get_bits(&decoder, 16); R(decoder);
-    } else {
-      so_start = 0;
-      so_end = 0xffff;
-    }
-    if (e3) {
-      range = nr_rlc_pdu_decoder_get_bits(&decoder, 8); R(decoder);
-    } else {
-      range = 1;
-    }
-    /* special value 0xffff indicates 'all bytes to the end' */
-    if (so_end == 0xffff)
-      so_end = -1;
-    process_received_nack(entity, nack_sn, so_start, so_end, range, sn_set);
-
-    /* 38.322 5.3.3.3 says to stop t_poll_retransmit if a ACK or NACK is
-     * received for the SN 'poll_sn' - check NACK case (ACK done above)
-     */
-    if (sn_compare_tx(entity, nack_sn, entity->poll_sn) <= 0 &&
-        sn_compare_tx(entity, entity->poll_sn, (nack_sn + range) % entity->sn_modulus) < 0)
-      entity->t_poll_retransmit_start = 0;
-  }
-
-  finalize_ack_nack_processing(entity);
-
-  return;
-
 err:
   LOG_W(RLC, "%s:%d:%s: error decoding PDU, discarding\n", __FILE__, __LINE__, __FUNCTION__);
   goto discard;
@@ -908,8 +917,6 @@ typedef struct {
   int so_start;
   int sn_end;
   int so_end;
-  /* data for maximum ack */
-  int ack_sn;                               /* -1 if not to be used */
   /* pdu to use for next call to 'next_missing' */
   nr_rlc_pdu_t *next;
 } missing_data_t;
@@ -924,13 +931,12 @@ static missing_data_t next_missing(nr_rlc_entity_am_t *entity,
   int max_so       = 0;
   int last_reached = 0;
 
-  ret.ack_sn = -1;
-
   /* special case: missing part before the head of RX list */
   if (check_head) {
     if (cur->sn != entity->rx_next || !cur->is_first) {
       /* don't report if out of reporting window */
-      if (sn_compare_rx(entity, entity->rx_highest_status, cur->sn) <= 0) {
+      if (sn_compare_rx(entity, entity->rx_highest_status,
+                        entity->rx_next) <= 0) {
         ret.sn_start = -1;
         return ret;
       }
@@ -954,10 +960,6 @@ next_pdu:
     max_so = cur_max_so;
   last_reached = last_reached | cur->is_last;
 
-  /* if cur already processed, it can be the acked SDU */
-  if (cur->data == NULL)
-    ret.ack_sn = (cur->sn + 1) % entity->sn_modulus;
-
   /* no next? */
   if (cur->next == NULL) {
     /* inform the caller that work is over */
@@ -1033,32 +1035,36 @@ next_pdu:
   }
 
   /* discontinuity between different SDUs */
-  ret.sn_start = sn;
+  if (last_reached) {
+    ret.sn_start = (sn + 1) % entity->sn_modulus;
+    ret.so_start = 0;
+  } else {
+    ret.sn_start = sn;
+    ret.so_start = max_so + 1;
+  }
   /* don't report if out of reporting window */
   if (sn_compare_rx(entity, entity->rx_highest_status, ret.sn_start) <= 0) {
     ret.sn_start = -1;
     return ret;
   }
-  ret.so_start = max_so + 1;
 
 set_end_different_sdu:
-  /* don't go more than rx_highest_status - 1 */
-  if (sn_compare_rx(entity, entity->rx_highest_status, cur->sn) <= 0) {
-    ret.sn_end = (entity->rx_highest_status - 1 + entity->sn_modulus) %
-                      entity->sn_modulus;
-    ret.so_end   = 0xffff;
-    return ret;
-  }
-
   /* if cur is the head of a SDU, then use cur-1 */
   if (cur->is_first) {
     ret.sn_end = (cur->sn - 1 + entity->sn_modulus) % entity->sn_modulus;
     ret.so_end = 0xffff;
-    return ret;
+  } else {
+    ret.sn_end = cur->sn;
+    ret.so_end = cur->so - 1;
+  }
+  /* don't go more than rx_highest_status - 1 */
+  if (sn_compare_rx(entity, entity->rx_highest_status, ret.sn_end) <= 0) {
+    ret.sn_end = (entity->rx_highest_status - 1 + entity->sn_modulus) %
+                      entity->sn_modulus;
+    ret.so_end   = 0xffff;
+    ret.next = NULL;
   }
 
-  ret.sn_end = cur->sn;
-  ret.so_end = cur->so - 1;
   return ret;
 }
 
@@ -1098,21 +1104,20 @@ static void get_e1_position(nr_rlc_entity_am_t *entity,
   }
 }
 
-/* returns the number of nacks serialized.
- * In most cases it is 1, it can be more if the
- * missing data consists of a range that is more
- * than 255 SNs in which case it has to be cut in
- * smaller ranges.
+/* returns the last nack SN generated, -1 if nothing generated.
  * If there is no more room in the status buffer,
  * will set m->next = NULL (and may serialize
- * less nacks than required by 'm').
+ * less nacks than required by 'm'), also
+ * sets *generation_truncated to 1.
  */
 static int generate_missing(nr_rlc_entity_am_t *entity,
                             nr_rlc_pdu_encoder_t *encoder,
-                            missing_data_t *m, int *e1_byte, int *e1_bit)
+                            missing_data_t *m, int *e1_byte, int *e1_bit,
+                            int *generation_truncated,
+                            unsigned char **so_end_address)
 {
   int r_bits = entity->sn_field_length == 18 ? 3 : 1;
-  int range_count = 0;
+  int last_nack_generated = -1;
   int sn_start;
   int so_start;
   int sn_end;
@@ -1164,6 +1169,7 @@ static int generate_missing(nr_rlc_entity_am_t *entity,
     m_nack.so_end = so_end;
     if (encoder->byte + nack_size(entity, &m_nack) > encoder->size) {
       m->next = NULL;
+      *generation_truncated = 1;
       break;
     }
 
@@ -1197,6 +1203,7 @@ static int generate_missing(nr_rlc_entity_am_t *entity,
     /* nack_sn */
     nr_rlc_pdu_encoder_put_bits(encoder, sn_start,
                                 entity->sn_field_length);
+    last_nack_generated = sn_start;
     /* e1 = 0 (set later if needed) */
     nr_rlc_pdu_encoder_put_bits(encoder, 0, 1);
     /* e2 */
@@ -1208,34 +1215,44 @@ static int generate_missing(nr_rlc_entity_am_t *entity,
     /* so_start/so_end */
     if (e2) {
       nr_rlc_pdu_encoder_put_bits(encoder, so_start, 16);
+      *so_end_address = (unsigned char *)encoder->buffer + encoder->byte;
       nr_rlc_pdu_encoder_put_bits(encoder, so_end, 16);
-    }
+    } else
+      *so_end_address = NULL;
     /* nack range */
-    if (e3)
+    if (e3) {
       nr_rlc_pdu_encoder_put_bits(encoder, cur_sn_count, 8);
+      last_nack_generated += cur_sn_count - 1;
+    }
 
     sn_count -= cur_sn_count;
     sn_start = (sn_start + cur_sn_count) % entity->sn_modulus;
-    range_count++;
   }
 
-  return range_count;
+  return last_nack_generated;
 }
 
 static int generate_status(nr_rlc_entity_am_t *entity, char *buffer, int size)
 {
-  int                  ack_sn = entity->rx_next;
-  missing_data_t  m;
+  int                  last_nack;
+  int                  ack_sn;
+  missing_data_t       m;
   nr_rlc_pdu_t         *cur;
-  int                  nack_count = 0;
+  int                  check_head = 1;
   nr_rlc_pdu_encoder_t encoder;
   int                  e1_byte;
   int                  e1_bit;
+  int                  generation_truncated;
+  int                  ln;
+  unsigned char        *so_end_address = NULL;
 
   /* if not enough room, do nothing */
   if (size < 3)
     return 0;
 
+  /* initial last_nack is rx_next - 1 */
+  last_nack = (entity->rx_next - 1 + entity->sn_modulus) % entity->sn_modulus;
+
   nr_rlc_pdu_encoder_init(&encoder, buffer, size);
 
   /* first 3 bytes, ack_sn and e1 will be set later */
@@ -1250,22 +1267,33 @@ static int generate_status(nr_rlc_entity_am_t *entity, char *buffer, int size)
   e1_bit = entity->sn_field_length == 18 ? 1 : 7;
 
   while (cur != NULL) {
-    m = next_missing(entity, cur, nack_count == 0);
-
-    /* update ack_sn if the returned value is valid */
-    if (m.ack_sn != -1)
-      ack_sn = m.ack_sn;
+    m = next_missing(entity, cur, check_head);
+    check_head = 0;
 
     /* stop here if no more nack to report */
     if (m.sn_start == -1)
       break;
 
-    nack_count += generate_missing(entity, &encoder, &m, &e1_byte, &e1_bit);
+    generation_truncated = 0;
+    ln = generate_missing(entity, &encoder, &m, &e1_byte, &e1_bit,
+                          &generation_truncated, &so_end_address);
+    /* remember the last nack put, if any */
+    if (ln != -1)
+      last_nack = ln;
+    /* if generation was truncated and so_end was put, we force its value to
+     * 0xffff (end of SDU) because we don't know what missing nack information
+     * was supposed to be put, so we nack until the end of the PDU to be sure
+     */
+    if (generation_truncated && so_end_address != NULL) {
+      so_end_address[0] = 0xff;
+      so_end_address[1] = 0xff;
+    }
 
     cur = m.next;
   }
 
-  /* put ack_sn */
+  /* put ack_sn, which is last_nack + 1 */
+  ack_sn = (last_nack + 1) % entity->sn_modulus;
   if (entity->sn_field_length == 12) {
     buffer[0] = ack_sn >> 8;
     buffer[1] = ack_sn & 255;
@@ -1427,8 +1455,6 @@ static int generate_retx_pdu(nr_rlc_entity_am_t *entity, char *buffer,
     return 0;
 
   entity->retransmit_list = entity->retransmit_list->next;
-  if (entity->retransmit_list == NULL)
-    entity->retransmit_end = NULL;
 
   sdu->next = NULL;
 
@@ -1444,15 +1470,24 @@ static int generate_retx_pdu(nr_rlc_entity_am_t *entity, char *buffer,
     /* put the second SDU back at the head of the retransmit list */
     next_sdu->next = entity->retransmit_list;
     entity->retransmit_list = next_sdu;
-    if (entity->retransmit_end == NULL)
-      entity->retransmit_end = entity->retransmit_list;
     /* update buffer status */
     entity->common.bstatus.retx_size += compute_pdu_header_size(entity, next_sdu)
                                         + next_sdu->size;
   }
 
   /* put SDU/SDU segment in the wait list */
-  nr_rlc_sdu_segment_list_append(&entity->wait_list, &entity->wait_end, sdu);
+  /* speedup: check end of wait list, maybe the new sdu comes after */
+  if (entity->wait_end == NULL
+      || sn_compare_tx(entity, sdu->sdu->sn, entity->wait_end->sdu->sn) > 0
+      || (sn_compare_tx(entity, sdu->sdu->sn, entity->wait_end->sdu->sn) == 0
+          && sdu->so > entity->wait_end->so))
+    nr_rlc_sdu_segment_list_append(&entity->wait_list, &entity->wait_end, sdu);
+  else {
+    entity->wait_list = nr_rlc_sdu_segment_list_add(sn_compare_tx, entity,
+                            entity->wait_list, sdu);
+    if (entity->wait_list->next == NULL)
+      entity->wait_end = entity->wait_list;
+  }
 
   p = check_poll_after_pdu_assembly(entity);
 
@@ -1519,7 +1554,18 @@ static int generate_tx_pdu(nr_rlc_entity_am_t *entity, char *buffer, int size)
     entity->tx_next = (entity->tx_next + 1) % entity->sn_modulus;
 
   /* put SDU/SDU segment in the wait list */
-  nr_rlc_sdu_segment_list_append(&entity->wait_list, &entity->wait_end, sdu);
+  /* speedup: check end of wait list, probably the new sdu comes after */
+  if (entity->wait_end == NULL
+      || sn_compare_tx(entity, sdu->sdu->sn, entity->wait_end->sdu->sn) > 0
+      || (sn_compare_tx(entity, sdu->sdu->sn, entity->wait_end->sdu->sn) == 0
+          && sdu->so > entity->wait_end->so))
+    nr_rlc_sdu_segment_list_append(&entity->wait_list, &entity->wait_end, sdu);
+  else {
+    entity->wait_list = nr_rlc_sdu_segment_list_add(sn_compare_tx, entity,
+                            entity->wait_list, sdu);
+    if (entity->wait_list->next == NULL)
+      entity->wait_end = entity->wait_list;
+  }
 
   /* polling actions for a new PDU */
   entity->pdu_without_poll++;
@@ -1629,11 +1675,7 @@ void nr_rlc_entity_am_recv_sdu(nr_rlc_entity_t *_entity,
 
 static void check_t_poll_retransmit(nr_rlc_entity_am_t *entity)
 {
-  nr_rlc_sdu_segment_t head;
   nr_rlc_sdu_segment_t *cur;
-  nr_rlc_sdu_segment_t *prev;
-  int sn;
-  int old_retx_count;
 
   /* 38.322 5.3.3.4 */
   /* did t_poll_retransmit expire? */
@@ -1659,74 +1701,58 @@ static void check_t_poll_retransmit(nr_rlc_entity_am_t *entity)
    */
   entity->force_poll = 1;
 
-  LOG_W(RLC, "%s:%d:%s: warning: t_poll_retransmit expired\n",
+  LOG_D(RLC, "%s:%d:%s: warning: t_poll_retransmit expired\n",
         __FILE__, __LINE__, __FUNCTION__);
 
   /* do we meet conditions of 38.322 5.3.3.4? */
   if (!check_poll_after_pdu_assembly(entity))
     return;
 
-  /* search wait list for SDU with highest SN */
-  /* this code may be incorrect: in LTE we had to look for PDU
-   * with SN = VT(S) - 1, but for NR the specs say "highest SN among the
-   * ones submitted to lower layers" not 'tx_next - 1'. So we should look
-   * for the highest SN in the wait list. But that's no big deal. If the
-   * program runs this code, then the connection is in a bad state and we
-   * can retransmit whatever we want. At some point we will receive a status
-   * report and retransmit what we really have to. Actually we could just
-   * retransmit the head of wait list (the specs have this 'or').
-   * (Actually, maybe this interpretation is not correct and what the code
-   * does is correct. The specs are confusing.)
+  /* retransmit the head of wait list, this is the case
+   * "consider any RLC SDU which has not been positively acknowledged for
+   * retransmission" of 36.322 5.3.3.4.
+   * We don't search for the highest SN, it's simpler to just take the head
+   * of wait list. This can be changed if needed.
    */
-  sn = (entity->tx_next - 1 + entity->sn_modulus) % entity->sn_modulus;
-
-  head.next = entity->wait_list;
   cur = entity->wait_list;
-  prev = &head;
-
-  while (cur != NULL) {
-    if (cur->sdu->sn == sn)
-      break;
-    prev = cur;
-    cur = cur->next;
-  }
-
-  /* SDU with highest SN not found? take the head of wait list */
-  if (cur == NULL) {
-    cur = entity->wait_list;
-    prev = &head;
-    sn = cur->sdu->sn;
-  }
 
   /* todo: do we need to for check cur == NULL?
    * It seems that no, the wait list should not be empty here, but not sure.
    */
 
-  old_retx_count = cur->sdu->retx_count;
+  entity->wait_list = cur->next;
+  if (entity->wait_list == NULL)
+     entity->wait_end = NULL;
 
-  /* 38.322 says "SDU", not "SDU segment", so let's retransmit all
-   * SDU segments with this SN
+  /* 38.322 says "SDU", not "SDU segment", but let's retransmit only
+   * the 'cur' SDU segment. To be changed if needed. (Maybe we have
+   * to retransmit all SDU segments with the same SN that are in the
+   * wait list.)
    */
-  /* todo: maybe we could simply retransmit the current SDU segment,
-   * so that we don't have to run through the full wait list.
+
+  /* increase retx count. Don't care about segmentation, so maybe we
+   * increase too much.
    */
-  while (cur != NULL) {
-    if (cur->sdu->sn == sn) {
-      prev->next = cur->next;
-      cur->next = NULL;
-      /* put in retransmit list */
-      consider_retransmission(entity, cur,
-                              old_retx_count == cur->sdu->retx_count);
-    } else {
-      prev = cur;
-    }
-    cur = prev->next;
-  }
-  entity->wait_list = head.next;
-  /* reset wait_end (todo: optimize?) */
-  entity->wait_end = entity->wait_list;
-  while (entity->wait_end != NULL && entity->wait_end->next != NULL)
-    entity->wait_end = entity->wait_end->next;
+  cur->sdu->retx_count++;
+  /* report max RETX reached for all retx_count >= max_retx_threshold
+   * (specs say to report if retx_count == max_retx_threshold).
+   * Upper layers should react (radio link failure), so no big deal.
+   * We deal with segmentation by requiring
+   * retx_count >= max_retx_threshold * number of segments.
+   * We may report max RETX reached too late/early. To be refined if
+   * this is a problem.
+   */
+  if (cur->sdu->retx_count
+        >= entity->max_retx_threshold * cur->sdu->ref_count)
+    entity->common.max_retx_reached(entity->common.max_retx_reached_data,
+                                    (nr_rlc_entity_t *)entity);
+  /* update buffer status */
+  entity->common.bstatus.retx_size += compute_pdu_header_size(entity, cur)
+                                      + cur->size;
+
+  /* put in retransmit list */
+  entity->retransmit_list = nr_rlc_sdu_segment_list_add(sn_compare_tx, entity,
+                                entity->retransmit_list, cur);
 }
 
 static void check_t_reassembly(nr_rlc_entity_am_t *entity)
@@ -1815,6 +1841,7 @@ void nr_rlc_entity_am_discard_sdu(nr_rlc_entity_t *_entity, int sdu_id)
   entity->common.bstatus.tx_size -= compute_pdu_header_size(entity, cur)
                                     + cur->size;
 
+  entity->tx_size -= cur->sdu->size;
   nr_rlc_free_sdu_segment(cur);
 }
 
@@ -1857,7 +1884,6 @@ static void clear_entity(nr_rlc_entity_am_t *entity)
   nr_rlc_free_sdu_segment_list(entity->tx_list);
   nr_rlc_free_sdu_segment_list(entity->wait_list);
   nr_rlc_free_sdu_segment_list(entity->retransmit_list);
-  nr_rlc_free_sdu_segment_list(entity->ack_list);
 
   entity->tx_list         = NULL;
   entity->tx_end          = NULL;
@@ -1867,9 +1893,6 @@ static void clear_entity(nr_rlc_entity_am_t *entity)
   entity->wait_end        = NULL;
 
   entity->retransmit_list = NULL;
-  entity->retransmit_end  = NULL;
-
-  entity->ack_list        = NULL;
 
   entity->common.bstatus.tx_size   = 0;
   entity->common.bstatus.retx_size = 0;
diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_entity_am.h b/openair2/LAYER2/nr_rlc/nr_rlc_entity_am.h
index 453fe870265ac8e8fce2d104672d6ef213e11471..57ae1a3485698dd7056e87d97b01b51f35ac001d 100644
--- a/openair2/LAYER2/nr_rlc/nr_rlc_entity_am.h
+++ b/openair2/LAYER2/nr_rlc/nr_rlc_entity_am.h
@@ -84,9 +84,6 @@ typedef struct {
   nr_rlc_sdu_segment_t *wait_end;
 
   nr_rlc_sdu_segment_t *retransmit_list;
-  nr_rlc_sdu_segment_t *retransmit_end;
-
-  nr_rlc_sdu_segment_t *ack_list;
 } nr_rlc_entity_am_t;
 
 void nr_rlc_entity_am_recv_sdu(nr_rlc_entity_t *entity,
diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_sdu.c b/openair2/LAYER2/nr_rlc/nr_rlc_sdu.c
index ef0d52558aa402c3701d72ab9f8e0d2a492a6d57..ef64389ac559c8554fcc21a0c6c042b9c7067a86 100644
--- a/openair2/LAYER2/nr_rlc/nr_rlc_sdu.c
+++ b/openair2/LAYER2/nr_rlc/nr_rlc_sdu.c
@@ -58,14 +58,19 @@ oom:
   exit(1);
 }
 
-void nr_rlc_free_sdu_segment(nr_rlc_sdu_segment_t *sdu)
+int nr_rlc_free_sdu_segment(nr_rlc_sdu_segment_t *sdu)
 {
-  sdu->sdu->ref_count--;
-  if (sdu->sdu->ref_count == 0) {
+  int ret = 0;
+
+  sdu->sdu->free_count++;
+  if (sdu->sdu->free_count == sdu->sdu->ref_count) {
     free(sdu->sdu->data);
     free(sdu->sdu);
+    ret = 1;
   }
   free(sdu);
+
+  return ret;
 }
 
 void nr_rlc_sdu_segment_list_append(nr_rlc_sdu_segment_t **list,
diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_sdu.h b/openair2/LAYER2/nr_rlc/nr_rlc_sdu.h
index f4585fb7d62342f4b5a5065c1c778d05c27ff063..20cc90f185aadc9f3993c85aaa24eaef87bf3359 100644
--- a/openair2/LAYER2/nr_rlc/nr_rlc_sdu.h
+++ b/openair2/LAYER2/nr_rlc/nr_rlc_sdu.h
@@ -30,6 +30,10 @@ typedef struct nr_rlc_sdu_t {
   int retx_count;
 
   int ref_count;      /* incremented each time the SDU is segmented */
+  int free_count;     /* incremented each time a segment is freed
+                       * when it equals ref_count we can free the SDU
+                       * completely
+                       */
 } nr_rlc_sdu_t;
 
 typedef struct nr_rlc_sdu_segment_t {
@@ -44,7 +48,8 @@ typedef struct nr_rlc_sdu_segment_t {
 nr_rlc_sdu_segment_t *nr_rlc_new_sdu(
     char *buffer, int size,
     int upper_layer_id);
-void nr_rlc_free_sdu_segment(nr_rlc_sdu_segment_t *sdu);
+/* return 1 if the SDU has been freed too, 0 if not (more segments to free) */
+int nr_rlc_free_sdu_segment(nr_rlc_sdu_segment_t *sdu);
 void nr_rlc_sdu_segment_list_append(nr_rlc_sdu_segment_t **list,
                                     nr_rlc_sdu_segment_t **end,
                                     nr_rlc_sdu_segment_t *sdu);
diff --git a/openair2/LAYER2/nr_rlc/tests/test14.txt.gz b/openair2/LAYER2/nr_rlc/tests/test14.txt.gz
index 53616dae3d10b71375cea41ca9061d4304f64dcf..45e54651eb317c3b7695cfcab7428fe43172227b 100644
Binary files a/openair2/LAYER2/nr_rlc/tests/test14.txt.gz and b/openair2/LAYER2/nr_rlc/tests/test14.txt.gz differ
diff --git a/openair2/LAYER2/nr_rlc/tests/test15.txt.gz b/openair2/LAYER2/nr_rlc/tests/test15.txt.gz
index 2619436c2d4740017eb6b620d8fd0c7b919d3d84..ddb895d56f0fe88f0ceffb9a100359413292f2b7 100644
Binary files a/openair2/LAYER2/nr_rlc/tests/test15.txt.gz and b/openair2/LAYER2/nr_rlc/tests/test15.txt.gz differ
diff --git a/openair2/M2AP/m2ap_MCE_defs.h b/openair2/M2AP/m2ap_MCE_defs.h
index 5267232d69f5482ae6cab17371d0629aadbdc0e4..73183e89c2a9e3e8fdc38351d52d79d81328db09 100644
--- a/openair2/M2AP/m2ap_MCE_defs.h
+++ b/openair2/M2AP/m2ap_MCE_defs.h
@@ -170,7 +170,7 @@ typedef struct m2ap_MCE_instance_s {
   int32_t                 uplink_frequency_offset[MAX_NUM_CCs];
   uint32_t                Nid_cell[MAX_NUM_CCs];
   int16_t                 N_RB_DL[MAX_NUM_CCs];
-  lte_frame_type_t        frame_type[MAX_NUM_CCs];
+  frame_type_t            frame_type[MAX_NUM_CCs];
   uint32_t                fdd_earfcn_DL[MAX_NUM_CCs];
   uint32_t                fdd_earfcn_UL[MAX_NUM_CCs];
   int                     num_cc;
diff --git a/openair2/M2AP/m2ap_eNB_defs.h b/openair2/M2AP/m2ap_eNB_defs.h
index b8f7e4b3c61600651e2b2f0ceeb520d23b8357a7..0b30c33d80253381b56e62658bc32a38f5e46776 100644
--- a/openair2/M2AP/m2ap_eNB_defs.h
+++ b/openair2/M2AP/m2ap_eNB_defs.h
@@ -181,7 +181,7 @@ typedef struct m2ap_eNB_instance_s {
   int32_t                 uplink_frequency_offset[MAX_NUM_CCs];
   uint32_t                Nid_cell[MAX_NUM_CCs];
   int16_t                 N_RB_DL[MAX_NUM_CCs];
-  lte_frame_type_t        frame_type[MAX_NUM_CCs];
+  frame_type_t            frame_type[MAX_NUM_CCs];
   uint32_t                fdd_earfcn_DL[MAX_NUM_CCs];
   uint32_t                fdd_earfcn_UL[MAX_NUM_CCs];
   int                     num_cc;
diff --git a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c
index f7323010cb05fcdbe3c9cdbac2ee97ba03aa2333..b8b79f8399f10a5908f5b558aeea52e300a0c7ac 100644
--- a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c
+++ b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c
@@ -42,6 +42,7 @@
 #include "SCHED_NR_UE/fapi_nr_ue_l1.h"
 #include "executables/softmodem-common.h"
 #include "openair2/RRC/NR_UE/rrc_proto.h"
+#include "openair2/RRC/NR_UE/rrc_vars.h"
 #include "openair2/GNB_APP/L1_nr_paramdef.h"
 #include "openair2/GNB_APP/gnb_paramdef.h"
 #include "targets/ARCH/ETHERNET/USERSPACE/LIB/if_defs.h"
@@ -64,7 +65,17 @@ queue_t nr_dl_tti_req_queue;
 queue_t nr_tx_req_queue;
 queue_t nr_ul_dci_req_queue;
 queue_t nr_ul_tti_req_queue;
-queue_t nr_wait_ul_tti_req_queue;
+
+static slot_rnti_mcs_s slot_rnti_mcs[NUM_NFAPI_SLOT];
+
+//static int get_mcs_from_sinr(float sinr);
+//static int get_cqi_from_mcs(void);
+static void read_channel_param(const nfapi_nr_dl_tti_pdsch_pdu_rel15_t * pdu, int sf, int index);
+//static bool did_drop_transport_block(int slot, uint16_t rnti);
+static float get_bler_val(uint8_t mcs, int sinr);
+static bool should_drop_transport_block(int slot, uint16_t rnti);
+static void save_pdsch_pdu_for_crnti(nfapi_nr_dl_tti_request_t *dl_tti_request);
+static inline bool is_channel_modeling(void);
 
 void nrue_init_standalone_socket(int tx_port, int rx_port)
 {
@@ -78,13 +89,13 @@ void nrue_init_standalone_socket(int tx_port, int rx_port)
     int sd = socket(server_address.sin_family, SOCK_DGRAM, 0);
     if (sd < 0)
     {
-      LOG_E(MAC, "Socket creation error standalone PNF\n");
+      LOG_E(NR_MAC, "Socket creation error standalone PNF\n");
       return;
     }
 
     if (inet_pton(server_address.sin_family, stub_eth_params.remote_addr, &server_address.sin_addr) <= 0)
     {
-      LOG_E(MAC, "Invalid standalone PNF Address\n");
+      LOG_E(NR_MAC, "Invalid standalone PNF Address\n");
       close(sd);
       return;
     }
@@ -92,13 +103,13 @@ void nrue_init_standalone_socket(int tx_port, int rx_port)
     // Using connect to use send() instead of sendto()
     if (connect(sd, (struct sockaddr *)&server_address, addr_len) < 0)
     {
-      LOG_E(MAC, "Connection to standalone PNF failed: %s\n", strerror(errno));
+      LOG_E(NR_MAC, "Connection to standalone PNF failed: %s\n", strerror(errno));
       close(sd);
       return;
     }
     assert(ue_tx_sock_descriptor == -1);
     ue_tx_sock_descriptor = sd;
-    LOG_D(NR_RRC, "Successfully set up tx_socket in %s.\n", __FUNCTION__);
+    LOG_T(NR_RRC, "Successfully set up tx_socket in %s.\n", __FUNCTION__);
   }
 
   {
@@ -118,15 +129,15 @@ void nrue_init_standalone_socket(int tx_port, int rx_port)
 
     if (bind(sd, (struct sockaddr *)&server_address, addr_len) < 0)
     {
-      LOG_E(MAC, "Connection to standalone PNF failed: %s\n", strerror(errno));
+      LOG_E(NR_MAC, "Connection to standalone PNF failed: %s\n", strerror(errno));
       close(sd);
       return;
     }
     assert(ue_rx_sock_descriptor == -1);
     ue_rx_sock_descriptor = sd;
-    LOG_D(NR_RRC, "Successfully set up rx_socket in %s.\n", __FUNCTION__);
+    LOG_T(NR_RRC, "Successfully set up rx_socket in %s.\n", __FUNCTION__);
   }
-  LOG_I(NR_RRC, "NRUE standalone socket info: tx_port %d  rx_port %d on %s.\n",
+  LOG_D(NR_RRC, "NRUE standalone socket info: tx_port %d  rx_port %d on %s.\n",
         tx_port, rx_port, stub_eth_params.remote_addr);
 }
 
@@ -137,7 +148,7 @@ void send_nsa_standalone_msg(NR_UL_IND_t *UL_INFO, uint16_t msg_id)
     case NFAPI_NR_PHY_MSG_TYPE_RACH_INDICATION:
     {
         char buffer[NFAPI_MAX_PACKED_MESSAGE_SIZE];
-        LOG_D(NR_MAC, "RACH header id :%d", UL_INFO->rach_ind.header.message_id);
+        LOG_T(NR_MAC, "RACH header id :%d\n", UL_INFO->rach_ind.header.message_id);
         int encoded_size = nfapi_nr_p7_message_pack(&UL_INFO->rach_ind, buffer, sizeof(buffer), NULL);
         if (encoded_size <= 0)
         {
@@ -145,7 +156,7 @@ void send_nsa_standalone_msg(NR_UL_IND_t *UL_INFO, uint16_t msg_id)
                 return;
         }
 
-        LOG_I(NR_MAC, "NR_RACH_IND sent to Proxy, Size: %d Frame %d Slot %d Num PDUS %d\n", encoded_size,
+        LOG_D(NR_MAC, "NR_RACH_IND sent to Proxy, Size: %d Frame %d Slot %d Num PDUS %d\n", encoded_size,
                 UL_INFO->rach_ind.sfn, UL_INFO->rach_ind.slot, UL_INFO->rach_ind.number_of_pdus);
         if (send(ue_tx_sock_descriptor, buffer, encoded_size, 0) < 0)
         {
@@ -157,7 +168,7 @@ void send_nsa_standalone_msg(NR_UL_IND_t *UL_INFO, uint16_t msg_id)
     case NFAPI_NR_PHY_MSG_TYPE_RX_DATA_INDICATION:
     {
         char buffer[NFAPI_MAX_PACKED_MESSAGE_SIZE];
-        LOG_D(NR_MAC, "RX header id :%d", UL_INFO->rx_ind.header.message_id);
+        LOG_T(NR_MAC, "RX header id :%d\n", UL_INFO->rx_ind.header.message_id);
         int encoded_size = nfapi_nr_p7_message_pack(&UL_INFO->rx_ind, buffer, sizeof(buffer), NULL);
         if (encoded_size <= 0)
         {
@@ -165,7 +176,7 @@ void send_nsa_standalone_msg(NR_UL_IND_t *UL_INFO, uint16_t msg_id)
                 return;
         }
 
-        LOG_I(NR_MAC, "NR_RX_IND sent to Proxy, Size: %d Frame %d Slot %d Num PDUS %d\n", encoded_size,
+        LOG_D(NR_MAC, "NR_RX_IND sent to Proxy, Size: %d Frame %d Slot %d Num PDUS %d\n", encoded_size,
                 UL_INFO->rx_ind.sfn, UL_INFO->rx_ind.slot, UL_INFO->rx_ind.number_of_pdus);
         if (send(ue_tx_sock_descriptor, buffer, encoded_size, 0) < 0)
         {
@@ -177,7 +188,7 @@ void send_nsa_standalone_msg(NR_UL_IND_t *UL_INFO, uint16_t msg_id)
     case NFAPI_NR_PHY_MSG_TYPE_CRC_INDICATION:
     {
         char buffer[NFAPI_MAX_PACKED_MESSAGE_SIZE];
-        LOG_D(NR_MAC, "CRC header id :%d", UL_INFO->crc_ind.header.message_id);
+        LOG_T(NR_MAC, "CRC header id :%d\n", UL_INFO->crc_ind.header.message_id);
         int encoded_size = nfapi_nr_p7_message_pack(&UL_INFO->crc_ind, buffer, sizeof(buffer), NULL);
         if (encoded_size <= 0)
         {
@@ -185,7 +196,7 @@ void send_nsa_standalone_msg(NR_UL_IND_t *UL_INFO, uint16_t msg_id)
                 return;
         }
 
-        LOG_I(NR_MAC, "NR_CRC_IND sent to Proxy, Size: %d Frame %d Slot %d Num PDUS %d\n", encoded_size,
+        LOG_D(NR_MAC, "NR_CRC_IND sent to Proxy, Size: %d Frame %d Slot %d Num PDUS %d\n", encoded_size,
                 UL_INFO->crc_ind.sfn, UL_INFO->crc_ind.slot, UL_INFO->crc_ind.number_crcs);
         if (send(ue_tx_sock_descriptor, buffer, encoded_size, 0) < 0)
         {
@@ -197,7 +208,7 @@ void send_nsa_standalone_msg(NR_UL_IND_t *UL_INFO, uint16_t msg_id)
     case NFAPI_NR_PHY_MSG_TYPE_UCI_INDICATION:
     {
         char buffer[NFAPI_MAX_PACKED_MESSAGE_SIZE];
-        LOG_I(NR_MAC, "UCI header id :%d", UL_INFO->uci_ind.header.message_id);
+        LOG_D(NR_MAC, "UCI header id :%d\n", UL_INFO->uci_ind.header.message_id);
         int encoded_size = nfapi_nr_p7_message_pack(&UL_INFO->uci_ind, buffer, sizeof(buffer), NULL);
         if (encoded_size <= 0)
         {
@@ -205,7 +216,7 @@ void send_nsa_standalone_msg(NR_UL_IND_t *UL_INFO, uint16_t msg_id)
                 return;
         }
 
-        LOG_I(NR_MAC, "NR_UCI_IND sent to Proxy, Size: %d Frame %d Slot %d Num PDUS %d\n", encoded_size,
+        LOG_D(NR_MAC, "NR_UCI_IND sent to Proxy, Size: %d Frame %d Slot %d Num PDUS %d\n", encoded_size,
                 UL_INFO->uci_ind.sfn, UL_INFO->uci_ind.slot, UL_INFO->uci_ind.num_ucis);
         if (send(ue_tx_sock_descriptor, buffer, encoded_size, 0) < 0)
         {
@@ -221,18 +232,83 @@ void send_nsa_standalone_msg(NR_UL_IND_t *UL_INFO, uint16_t msg_id)
   }
 }
 
+bool sfn_slot_matcher(void *wanted, void *candidate)
+{
+  nfapi_p7_message_header_t *msg = candidate;
+  int sfn_sf = *(int*)wanted;
+
+  switch (msg->message_id)
+  {
+    case NFAPI_NR_PHY_MSG_TYPE_RACH_INDICATION:
+    {
+      nfapi_nr_rach_indication_t *ind = candidate;
+      return NFAPI_SFNSLOT2SFN(sfn_sf) == ind->sfn && NFAPI_SFNSLOT2SLOT(sfn_sf) == ind->slot;
+    }
+
+    case NFAPI_NR_PHY_MSG_TYPE_RX_DATA_INDICATION:
+    {
+      nfapi_nr_rx_data_indication_t *ind = candidate;
+      return NFAPI_SFNSLOT2SFN(sfn_sf) == ind->sfn && NFAPI_SFNSLOT2SLOT(sfn_sf) == ind->slot;
+    }
+
+    case NFAPI_NR_PHY_MSG_TYPE_CRC_INDICATION:
+    {
+      nfapi_nr_crc_indication_t *ind = candidate;
+      return NFAPI_SFNSLOT2SFN(sfn_sf) == ind->sfn && NFAPI_SFNSLOT2SLOT(sfn_sf) == ind->slot;
+    }
+
+    case NFAPI_NR_PHY_MSG_TYPE_UCI_INDICATION:
+    {
+      nfapi_nr_uci_indication_t *ind = candidate;
+      return NFAPI_SFNSLOT2SFN(sfn_sf) == ind->sfn && NFAPI_SFNSLOT2SLOT(sfn_sf) == ind->slot;
+    }
+
+    case NFAPI_NR_PHY_MSG_TYPE_DL_TTI_REQUEST:
+    {
+      nfapi_nr_dl_tti_request_t *ind = candidate;
+      return NFAPI_SFNSLOT2SFN(sfn_sf) == ind->SFN && NFAPI_SFNSLOT2SLOT(sfn_sf) == ind->Slot;
+    }
+
+    case NFAPI_NR_PHY_MSG_TYPE_TX_DATA_REQUEST:
+    {
+      nfapi_nr_tx_data_request_t *ind = candidate;
+      return NFAPI_SFNSLOT2SFN(sfn_sf) == ind->SFN && NFAPI_SFNSLOT2SLOT(sfn_sf) == ind->Slot;
+    }
+
+    case NFAPI_NR_PHY_MSG_TYPE_UL_DCI_REQUEST:
+    {
+      nfapi_nr_ul_dci_request_t *ind = candidate;
+      return NFAPI_SFNSLOT2SFN(sfn_sf) == ind->SFN && NFAPI_SFNSLOT2SLOT(sfn_sf) == ind->Slot;
+    }
+
+    case NFAPI_NR_PHY_MSG_TYPE_UL_TTI_REQUEST:
+    {
+      nfapi_nr_ul_tti_request_t *ind = candidate;
+      return NFAPI_SFNSLOT2SFN(sfn_sf) == ind->SFN && NFAPI_SFNSLOT2SLOT(sfn_sf) == ind->Slot;
+    }
+
+    default:
+      LOG_E(NR_MAC, "sfn_slot_match bad ID: %d\n", msg->message_id);
+
+  }
+
+  return false;
+}
+
 static void fill_dl_info_with_pdcch(fapi_nr_dci_indication_t *dci, nfapi_nr_dl_dci_pdu_t *rx_dci, int idx)
 {
     int num_bytes = (rx_dci->PayloadSizeBits + 7) / 8;
-    LOG_I(NR_PHY, "[%d, %d] PDCCH DCI (Payload) for rnti %x with PayloadSizeBits %d, num_bytes %d\n",
+    LOG_D(NR_PHY, "[%d, %d] PDCCH DCI (Payload) for rnti %x with PayloadSizeBits %d, num_bytes %d\n",
           dci->SFN, dci->slot, rx_dci->RNTI, rx_dci->PayloadSizeBits, num_bytes);
     for (int k = 0; k < num_bytes; k++)
     {
-        LOG_I(NR_MAC, "PDCCH DCI PDU payload[%d] = %d\n", k, rx_dci->Payload[k]);
+        LOG_D(NR_MAC, "PDCCH DCI PDU payload[%d] = %d\n", k, rx_dci->Payload[k]);
         dci->dci_list[idx].payloadBits[k] = rx_dci->Payload[k];
     }
     dci->dci_list[idx].payloadSize = rx_dci->PayloadSizeBits;
     dci->dci_list[idx].rnti = rx_dci->RNTI;
+    dci->dci_list[idx].n_CCE = rx_dci->CceIndex;
+    dci->dci_list[idx].N_CCE = rx_dci->AggregationLevel;
     dci->number_of_dcis = idx + 1;
 }
 
@@ -242,7 +318,7 @@ static void fill_mib_in_rx_ind(nfapi_nr_dl_tti_request_pdu_t *pdu_list, fapi_nr_
                 "pdu_index (%d) is greater than rx_indication_body size!\n", pdu_idx);
     AssertFatal(pdu_idx == rx_ind->number_pdus,  "Invalid pdu_idx %d!\n", pdu_idx);
 
-    LOG_D(NR_MAC, "Recevied an SSB and are filling rx_ind with the MIB!\n");
+    LOG_T(NR_MAC, "Recevied an SSB and are filling rx_ind with the MIB!\n");
 
     nfapi_nr_dl_tti_ssb_pdu_rel15_t *ssb_pdu = &pdu_list->ssb_pdu.ssb_pdu_rel15;
     rx_ind->rx_indication_body[pdu_idx].ssb_pdu.cell_id = ssb_pdu->PhysCellId;
@@ -311,13 +387,13 @@ static void copy_dl_tti_req_to_dl_info(nr_downlink_indication_t *dl_info, nfapi_
         nfapi_nr_dl_tti_request_pdu_t *pdu_list = &dl_tti_request->dl_tti_request_body.dl_tti_pdu_list[i];
         if (pdu_list->PDUType == NFAPI_NR_DL_TTI_PDSCH_PDU_TYPE)
         {
-            LOG_I(NR_PHY, "[%d, %d] PDSCH PDU for rnti %x\n",
+            LOG_D(NR_PHY, "[%d, %d] PDSCH PDU for rnti %x\n",
                 dl_tti_request->SFN, dl_tti_request->Slot, pdu_list->pdsch_pdu.pdsch_pdu_rel15.rnti);
         }
 
         if (pdu_list->PDUType == NFAPI_NR_DL_TTI_PDCCH_PDU_TYPE)
         {
-            LOG_I(NR_PHY, "[%d, %d] PDCCH DCI PDU (Format for incoming PDSCH PDU)\n",
+            LOG_D(NR_PHY, "[%d, %d] PDCCH DCI PDU (Format for incoming PDSCH PDU)\n",
                 dl_tti_request->SFN, dl_tti_request->Slot);
             uint16_t num_dcis = pdu_list->pdcch_pdu.pdcch_pdu_rel15.numDlDci;
             if (num_dcis > 0)
@@ -342,19 +418,19 @@ static void copy_dl_tti_req_to_dl_info(nr_downlink_indication_t *dl_info, nfapi_
                     {
                         mac->nr_ue_emul_l1.expected_sib = true;
                         mac->nr_ue_emul_l1.index_has_sib[j] = true;
-                        LOG_D(NR_MAC, "Setting index_has_sib[%d] = true\n", j);
+                        LOG_T(NR_MAC, "Setting index_has_sib[%d] = true\n", j);
                     }
                     else if (dci_pdu_list->RNTI == mac->ra.ra_rnti)
                     {
                         mac->nr_ue_emul_l1.expected_rar = true;
                         mac->nr_ue_emul_l1.index_has_rar[j] = true;
-                        LOG_D(NR_MAC, "Setting index_has_rar[%d] = true\n", j);
+                        LOG_T(NR_MAC, "Setting index_has_rar[%d] = true\n", j);
                     }
                     else
                     {
                         mac->nr_ue_emul_l1.expected_dci = true;
                         mac->nr_ue_emul_l1.index_has_dci[j] = true;
-                        LOG_D(NR_MAC, "Setting index_has_dci[%d] = true\n", j);
+                        LOG_T(NR_MAC, "Setting index_has_dci[%d] = true\n", j);
                     }
                     pdu_idx++;
                 }
@@ -388,13 +464,14 @@ static void copy_dl_tti_req_to_dl_info(nr_downlink_indication_t *dl_info, nfapi_
 
 static void fill_rx_ind(nfapi_nr_pdu_t *pdu_list, fapi_nr_rx_indication_t *rx_ind, int pdu_idx, int pdu_type)
 {
+    NR_UE_MAC_INST_t *mac = get_mac_inst(0);
     AssertFatal(pdu_list->num_TLV < sizeof(pdu_list->TLVs) / sizeof(pdu_list->TLVs[0]), "Num TLVs exceeds TLV array size");
     int length = 0;
     for (int j = 0; j < pdu_list->num_TLV; j++)
     {
         length += pdu_list->TLVs[j].length;
     }
-    LOG_I(NR_PHY, "%s: num_tlv %d and length %d, pdu index %d\n",
+    LOG_D(NR_PHY, "%s: num_tlv %d and length %d, pdu index %d\n",
         __FUNCTION__, pdu_list->num_TLV, length, pdu_idx);
     uint8_t *pdu = malloc(length);
     AssertFatal(pdu != NULL, "%s: Out of memory in malloc", __FUNCTION__);
@@ -409,7 +486,12 @@ static void fill_rx_ind(nfapi_nr_pdu_t *pdu_list, fapi_nr_rx_indication_t *rx_in
         memcpy(pdu, ptr, pdu_list->TLVs[j].length);
         pdu += pdu_list->TLVs[j].length;
     }
-    rx_ind->rx_indication_body[pdu_idx].pdsch_pdu.ack_nack = 1;
+    bool ack_nack = true;
+    if (mac->ra.ra_state >= RA_SUCCEEDED && should_drop_transport_block(rx_ind->slot, mac->crnti))
+    {
+      ack_nack = false;
+    }
+    rx_ind->rx_indication_body[pdu_idx].pdsch_pdu.ack_nack = ack_nack;
     rx_ind->rx_indication_body[pdu_idx].pdsch_pdu.pdu_length = length;
     rx_ind->rx_indication_body[pdu_idx].pdu_type = pdu_type;
 
@@ -455,7 +537,7 @@ static void copy_tx_data_req_to_dl_info(nr_downlink_indication_t *dl_info, nfapi
         }
         else
         {
-            LOG_D(NR_MAC, "mac->nr_ue_emul_l1.index_has_dci[%d] = 0, so this index contained a DCI for a different UE\n", i);
+            LOG_T(NR_MAC, "mac->nr_ue_emul_l1.index_has_dci[%d] = 0, so this index contained a DCI for a different UE\n", i);
         }
 
     }
@@ -476,7 +558,7 @@ static void copy_ul_dci_data_req_to_dl_info(nr_downlink_indication_t *dl_info, n
     {
         nfapi_nr_ul_dci_request_pdus_t *pdu_list = &ul_dci_req->ul_dci_pdu_list[i];
         AssertFatal(pdu_list->PDUType == 0, "ul_dci_req pdu type != PUCCH");
-        LOG_I(NR_PHY, "[%d %d] PUCCH PDU in ul_dci for rnti %x and numDLDCI = %d\n",
+        LOG_D(NR_PHY, "[%d %d] PUCCH PDU in ul_dci for rnti %x and numDLDCI = %d\n",
              ul_dci_req->SFN, ul_dci_req->Slot, pdu_list->pdcch_pdu.pdcch_pdu_rel15.dci_pdu->RNTI,
              pdu_list->pdcch_pdu.pdcch_pdu_rel15.numDlDci);
         uint16_t num_dci = pdu_list->pdcch_pdu.pdcch_pdu_rel15.numDlDci;
@@ -495,7 +577,7 @@ static void copy_ul_dci_data_req_to_dl_info(nr_downlink_indication_t *dl_info, n
                 nfapi_nr_dl_dci_pdu_t *dci_pdu_list = &pdu_list->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[j];
                 if (dci_pdu_list->RNTI != mac->crnti)
                 {
-                  LOG_D(NR_MAC, "dci_pdu_list->RNTI (%x) != mac->crnti (%x)\n", dci_pdu_list->RNTI, mac->crnti);
+                  LOG_T(NR_MAC, "dci_pdu_list->RNTI (%x) != mac->crnti (%x)\n", dci_pdu_list->RNTI, mac->crnti);
                   continue;
                 }
                 fill_dl_info_with_pdcch(dl_info->dci_ind, dci_pdu_list, pdu_idx);
@@ -507,148 +589,60 @@ static void copy_ul_dci_data_req_to_dl_info(nr_downlink_indication_t *dl_info, n
     dl_info->slot = ul_dci_req->Slot;
 }
 
-static nfapi_nr_uci_indication_t *multiplex_uci_ind(NR_UE_MAC_INST_t *mac, int num_active_harqs)
+static bool send_crc_ind_and_rx_ind(int sfn_slot)
 {
-    AssertFatal(num_active_harqs >= 0, "Invalid value for num_active_harqs %d\n", num_active_harqs);
-    if (num_active_harqs == 0)
-    {
-        return NULL;
-    }
-    if (num_active_harqs != nr_uci_ind_queue.num_items)
-    {
-        LOG_I(NR_MAC, "The number of active harqs %d doesn't match the number of UCIs in the queue %lu\n",
-                       num_active_harqs, nr_uci_ind_queue.num_items);
-        return NULL;
-    }
+  bool sent_crc_rx = true;
 
-    nfapi_nr_uci_indication_t *uci_ind = MALLOC(sizeof(*uci_ind));
-    uci_ind->header.message_id = NFAPI_NR_PHY_MSG_TYPE_UCI_INDICATION;
-    uci_ind->sfn = NFAPI_SFNSLOT2SFN(mac->nr_ue_emul_l1.active_harq_sfn_slot);
-    uci_ind->slot = NFAPI_SFNSLOT2SLOT(mac->nr_ue_emul_l1.active_harq_sfn_slot);
-    uci_ind->num_ucis = num_active_harqs;
-    uci_ind->uci_list = CALLOC(uci_ind->num_ucis, sizeof(*uci_ind->uci_list));
-    for (int i = 0; i < num_active_harqs; i++)
-    {
-        nfapi_nr_uci_indication_t *queued_uci_ind = get_queue(&nr_uci_ind_queue);
-        AssertFatal(queued_uci_ind, "There was not a UCI in the queue!\n");
-        nfapi_nr_uci_pucch_pdu_format_0_1_t *pdu_0_1 = &uci_ind->uci_list[i].pucch_pdu_format_0_1;
-
-        /* In openair1/SCHED_NR_UE/fapi_nr_ue_l1.c nr_ue_schedule_response_stub(), the
-        number of UCIs is hard coded to 1. This is why we always use index 0 of the
-        queued UCI indication to fill the new multiplexed UCI indication */
-        AssertFatal(queued_uci_ind->num_ucis == 1, "The number of UCIs from de-queueud UCI is not 1, its %d\n",
-                    queued_uci_ind->num_ucis);
-        uci_ind->uci_list[i].pdu_type = queued_uci_ind->uci_list[0].pdu_type;
-        uci_ind->uci_list[i].pdu_size = queued_uci_ind->uci_list[0].pdu_size;
-
-        nfapi_nr_uci_pucch_pdu_format_0_1_t *queued_pdu_0_1 = &queued_uci_ind->uci_list[0].pucch_pdu_format_0_1;
-        pdu_0_1->handle = queued_pdu_0_1->handle;
-        pdu_0_1->rnti = queued_pdu_0_1->rnti;
-        pdu_0_1->pucch_format = queued_pdu_0_1->pucch_format;
-        pdu_0_1->ul_cqi = queued_pdu_0_1->ul_cqi;
-        pdu_0_1->timing_advance = queued_pdu_0_1->timing_advance;
-        pdu_0_1->rssi = queued_pdu_0_1->rssi;
-        free(queued_uci_ind->uci_list);
-        queued_uci_ind->uci_list = NULL;
-        free(queued_uci_ind);
-        queued_uci_ind = NULL;
+  nfapi_nr_rx_data_indication_t *rx_ind = unqueue_matching(&nr_rx_ind_queue, MAX_QUEUE_SIZE, sfn_slot_matcher, &sfn_slot);
+  nfapi_nr_crc_indication_t *crc_ind = unqueue_matching(&nr_crc_ind_queue, MAX_QUEUE_SIZE, sfn_slot_matcher, &sfn_slot);
+
+  if (crc_ind && crc_ind->number_crcs > 0)
+  {
+    NR_UE_MAC_INST_t *mac = get_mac_inst(0);
+    for (int i = 0; i < crc_ind->number_crcs; i++) {
+        int harq_pid = crc_ind->crc_list[i].harq_id;
+        LOG_T(NR_MAC, "Resetting harq_pid %d active_ul_harq_sfn_slot\n", harq_pid);
+        mac->nr_ue_emul_l1.harq[harq_pid].active_ul_harq_sfn_slot = -1;
     }
-    return uci_ind;
+    NR_UL_IND_t UL_INFO = {
+      .crc_ind = *crc_ind,
+    };
+    send_nsa_standalone_msg(&UL_INFO, crc_ind->header.message_id);
+    free(crc_ind->crc_list);
+    free(crc_ind);
+  }
+  if (rx_ind && rx_ind->number_of_pdus > 0)
+  {
+    NR_UL_IND_t UL_INFO = {
+      .rx_ind = *rx_ind,
+    };
+    send_nsa_standalone_msg(&UL_INFO, rx_ind->header.message_id);
+    free(rx_ind->pdu_list);
+    free(rx_ind);
+  }
+  else
+  {
+    sent_crc_rx = false;
+  }
+  return sent_crc_rx;
 }
 
 static void copy_ul_tti_data_req_to_dl_info(nr_downlink_indication_t *dl_info, nfapi_nr_ul_tti_request_t *ul_tti_req)
 {
-    NR_UE_MAC_INST_t *mac = get_mac_inst(dl_info->module_id);
     int num_pdus = ul_tti_req->n_pdus;
+    int sfn_slot = NFAPI_SFNSLOT2HEX(ul_tti_req->SFN, ul_tti_req->Slot);
     AssertFatal(num_pdus >= 0, "Invalid ul_tti_request number of PDUS\n");
     AssertFatal(num_pdus <= sizeof(ul_tti_req->pdus_list) / sizeof(ul_tti_req->pdus_list[0]),
                 "Too many pdus %d in ul_tti_req\n", num_pdus);
 
-    bool sent_uci = false;
-    for (int i = 0; i < num_pdus; i++)
-    {
-        nfapi_nr_ul_tti_request_number_of_pdus_t *pdu_list = &ul_tti_req->pdus_list[i];
-        LOG_D(NR_PHY, "This is the pdu type %d and rnti %x and SR flag %d and harq_pdu_len %d in in ul_tti_req\n",
-              pdu_list->pdu_type, ul_tti_req->pdus_list[i].pucch_pdu.rnti, pdu_list->pucch_pdu.sr_flag, pdu_list->pucch_pdu.bit_len_harq);
-        if (pdu_list->pdu_type == NFAPI_NR_UL_CONFIG_PUCCH_PDU_TYPE && pdu_list->pucch_pdu.rnti == mac->crnti)
-        {
-            AssertFatal(nr_uci_ind_queue.num_items >= 0, "Invalid num_items in UCI_ind queue %lu\n",
-                        nr_uci_ind_queue.num_items);
-            int num_active_harqs = pdu_list->pucch_pdu.bit_len_harq;
-            LOG_I(NR_MAC, "The number of active harqs %d from ul_tti_req\n", num_active_harqs);
-            nfapi_nr_uci_indication_t *uci_ind = multiplex_uci_ind(mac, num_active_harqs);
-
-            if (uci_ind && uci_ind->num_ucis > 0)
-            {
-                LOG_D(NR_MAC, "This is the SFN/SF [%d, %d] and RNTI %x of the UCI ind. ul_tti_req.pdu[%d]->rnti = %x \n",
-                        uci_ind->sfn, uci_ind->slot, uci_ind->uci_list[0].pucch_pdu_format_0_1.rnti, i, ul_tti_req->pdus_list[i].pucch_pdu.rnti);
-                uci_ind->sfn = ul_tti_req->SFN;
-                uci_ind->slot = ul_tti_req->Slot;
-                for (int j = 0; j < uci_ind->num_ucis; j++)
-                {
-                    nfapi_nr_uci_pucch_pdu_format_0_1_t *pdu_0_1 = &uci_ind->uci_list[j].pucch_pdu_format_0_1;
-                    if (pdu_list->pucch_pdu.sr_flag)
-                    {
-                        LOG_D(NR_MAC, "We have the SR flag in pdu i %d\n", i);
-                        pdu_0_1->pduBitmap = 1; // (value->pduBitmap >> 1) & 0x01) == HARQ and (value->pduBitmap) & 0x01) == SR
-                        pdu_0_1->sr = CALLOC(1, sizeof(*pdu_0_1->sr));
-                        pdu_0_1->sr->sr_confidence_level = 0;
-                        pdu_0_1->sr->sr_indication = 1;
-                    }
-                    if (pdu_list->pucch_pdu.bit_len_harq > 0)
-                    {
-                        LOG_D(NR_MAC, "We have the Harq len bits %d\n", pdu_list->pucch_pdu.bit_len_harq);
-                        pdu_0_1->pduBitmap = 2; // (value->pduBitmap >> 1) & 0x01) == HARQ and (value->pduBitmap) & 0x01) == SR
-                        pdu_0_1->harq = CALLOC(1, sizeof(*pdu_0_1->harq));
-                        pdu_0_1->harq->num_harq = 1;
-                        pdu_0_1->harq->harq_confidence_level = 0;
-                        pdu_0_1->harq->harq_list = CALLOC(pdu_0_1->harq->num_harq, sizeof(*pdu_0_1->harq->harq_list));
-                        for (int k = 0; k < pdu_0_1->harq->num_harq; k++)
-                        {
-                            pdu_0_1->harq->harq_list[k].harq_value = 0;
-                        }
-                    }
-                }
-                LOG_I(NR_MAC, "We have dequeued the previously filled uci_ind and updated the snf/slot to %d/%d.\n",
-                      uci_ind->sfn, uci_ind->slot);
-                NR_UL_IND_t UL_INFO = {
-                    .uci_ind = *uci_ind,
-                };
-                send_nsa_standalone_msg(&UL_INFO, uci_ind->header.message_id);
-                sent_uci = true;
-
-                for (int k = 0; k < uci_ind->num_ucis; k++)
-                {
-                    nfapi_nr_uci_pucch_pdu_format_0_1_t *pdu_0_1 = &uci_ind->uci_list[k].pucch_pdu_format_0_1;
-                    if (pdu_list->pucch_pdu.sr_flag)
-                    {
-                        free(pdu_0_1->sr);
-                        pdu_0_1->sr = NULL;
-                    }
-                    if (pdu_list->pucch_pdu.bit_len_harq > 1)
-                    {
-                        free(pdu_0_1->harq->harq_list);
-                        pdu_0_1->harq->harq_list = NULL;
-                        free(pdu_0_1->harq);
-                        pdu_0_1->harq = NULL;
-                    }
-                }
-                free(uci_ind->uci_list);
-                uci_ind->uci_list = NULL;
-                free(uci_ind);
-                uci_ind = NULL;
-            }
-        }
-    }
-    if (!sent_uci)
+    if (!send_crc_ind_and_rx_ind(sfn_slot))
     {
-        LOG_E(NR_MAC, "UCI ind not sent\n");
+        LOG_T(NR_MAC, "CRC_RX ind not sent\n");
         if (!put_queue(&nr_ul_tti_req_queue, ul_tti_req))
         {
             LOG_E(NR_PHY, "put_queue failed for ul_tti_req.\n");
-            free(ul_tti_req);
-            ul_tti_req = NULL;
         }
+        return;
     }
 }
 
@@ -663,13 +657,13 @@ static void fill_dci_from_dl_config(nr_downlink_indication_t*dl_ind, fapi_nr_dl_
               "Too many dl_config pdus %d", dl_config->number_pdus);
   for (int i = 0; i < dl_config->number_pdus; i++)
   {
-    LOG_I(PHY, "In %s: filling DCI with a total of %d total DL PDUs (dl_config %p) \n",
+    LOG_D(PHY, "In %s: filling DCI with a total of %d total DL PDUs (dl_config %p) \n",
           __FUNCTION__, dl_config->number_pdus, dl_config);
     fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15_dci = &dl_config->dl_config_list[i].dci_config_pdu.dci_config_rel15;
     int num_dci_options = rel15_dci->num_dci_options;
     if (num_dci_options <= 0)
     {
-      LOG_I(NR_MAC, "num_dci_opts = %d for pdu[%d] in dl_config_list\n", rel15_dci->num_dci_options, i);
+      LOG_D(NR_MAC, "num_dci_opts = %d for pdu[%d] in dl_config_list\n", rel15_dci->num_dci_options, i);
     }
     AssertFatal(num_dci_options <= sizeof(rel15_dci->dci_length_options) / sizeof(rel15_dci->dci_length_options[0]),
                 "num_dci_options %d > dci_length_options array\n", num_dci_options);
@@ -683,17 +677,15 @@ static void fill_dci_from_dl_config(nr_downlink_indication_t*dl_ind, fapi_nr_dl_
                   "dl_config->number_pdus %d > dci_ind->dci_list array\n", num_dcis);
       for (int k = 0; k < num_dcis; k++)
       {
-        LOG_I(NR_PHY, "Received len %d, length options[%d] %d, format assigned %d, format options[%d] %d\n",
+        LOG_T(NR_PHY, "Received len %d, length options[%d] %d, format assigned %d, format options[%d] %d\n",
                   dl_ind->dci_ind->dci_list[k].payloadSize, j, rel15_dci->dci_length_options[j],
                   dl_ind->dci_ind->dci_list[k].dci_format, j, rel15_dci->dci_format_options[j]);
         if (rel15_dci->dci_length_options[j] == dl_ind->dci_ind->dci_list[k].payloadSize)
         {
             dl_ind->dci_ind->dci_list[k].dci_format = rel15_dci->dci_format_options[j];
+            LOG_D(NR_PHY, "format assigned dl_ind->dci_ind->dci_list[k].dci_format %d\n",
+                  dl_ind->dci_ind->dci_list[k].dci_format);
         }
-        int CCEind = rel15_dci->CCE[j];
-        int L = rel15_dci->L[j];
-        dl_ind->dci_ind->dci_list[k].n_CCE = CCEind;
-        dl_ind->dci_ind->dci_list[k].N_CCE = L;
       }
     }
   }
@@ -714,41 +706,52 @@ void check_and_process_dci(nfapi_nr_dl_tti_request_t *dl_tti_request,
     {
         frame = dl_tti_request->SFN;
         slot = dl_tti_request->Slot;
-        LOG_I(NR_PHY, "[%d, %d] dl_tti_request\n", frame, slot);
+        LOG_D(NR_PHY, "[%d, %d] dl_tti_request\n", frame, slot);
         copy_dl_tti_req_to_dl_info(&mac->dl_info, dl_tti_request);
+        free_and_zero(dl_tti_request);
     }
     /* This checks if the previously recevied DCI matches our current RNTI
        value. The assumption is that if the DCI matches our RNTI, then the
        incoming tx_data_request is also destined for the current UE. If the
        RAR hasn't been processed yet, we do not want to be filtering the
        tx_data_requests. */
-    if (tx_data_request && (mac->nr_ue_emul_l1.expected_sib ||
-                            mac->nr_ue_emul_l1.expected_rar ||
-                            mac->nr_ue_emul_l1.expected_dci))
+    if (tx_data_request)
     {
-        frame = tx_data_request->SFN;
-        slot = tx_data_request->Slot;
-        LOG_I(NR_PHY, "[%d, %d] PDSCH in tx_request\n", frame, slot);
-        copy_tx_data_req_to_dl_info(&mac->dl_info, tx_data_request);
+        if (mac->nr_ue_emul_l1.expected_sib ||
+            mac->nr_ue_emul_l1.expected_rar ||
+            mac->nr_ue_emul_l1.expected_dci)
+        {
+            frame = tx_data_request->SFN;
+            slot = tx_data_request->Slot;
+            LOG_I(NR_PHY, "[%d, %d] PDSCH in tx_request\n", frame, slot);
+            copy_tx_data_req_to_dl_info(&mac->dl_info, tx_data_request);
+        }
+        else
+        {
+            LOG_D(NR_MAC, "Unexpected tx_data_req\n");
+        }
+        free_and_zero(tx_data_request);
     }
     else if (ul_dci_request)
     {
         frame = ul_dci_request->SFN;
         slot = ul_dci_request->Slot;
-        LOG_I(NR_PHY, "[%d, %d] ul_dci_request\n", frame, slot);
+        LOG_D(NR_PHY, "[%d, %d] ul_dci_request\n", frame, slot);
         copy_ul_dci_data_req_to_dl_info(&mac->dl_info, ul_dci_request);
+        free_and_zero(ul_dci_request);
     }
     else if (ul_tti_request)
     {
         frame = ul_tti_request->SFN;
         slot = ul_tti_request->Slot;
-        LOG_I(NR_PHY, "[%d, %d] ul_tti_request\n", frame, slot);
+        LOG_T(NR_PHY, "[%d, %d] ul_tti_request\n", frame, slot);
         copy_ul_tti_data_req_to_dl_info(&mac->dl_info, ul_tti_request);
+        free_and_zero(ul_tti_request);
     }
     else
     {
         if (pthread_mutex_unlock(&mac->mutex_dl_info)) abort();
-        LOG_E(NR_MAC, "Error! All indications were NULL\n");
+        LOG_T(NR_MAC, "All indications were NULL in %s\n", __FUNCTION__);
         return;
     }
 
@@ -756,6 +759,7 @@ void check_and_process_dci(nfapi_nr_dl_tti_request_t *dl_tti_request,
     NR_UL_TIME_ALIGNMENT_t ul_time_alignment;
     memset(&ul_time_alignment, 0, sizeof(ul_time_alignment));
     fill_dci_from_dl_config(&mac->dl_info, &mac->dl_config_request);
+    nr_ue_scheduler(&mac->dl_info, NULL);
     nr_ue_dl_indication(&mac->dl_info, &ul_time_alignment);
 
     if (pthread_mutex_unlock(&mac->mutex_dl_info)) abort();
@@ -776,8 +780,11 @@ void check_and_process_dci(nfapi_nr_dl_tti_request_t *dl_tti_request,
                           mac->scc->tdd_UL_DL_ConfigurationCommon :
                           mac->scc_SIB->tdd_UL_DL_ConfigurationCommon,
                           ul_info.slot_tx,
-                          mac->frame_type))
-            nr_ue_ul_indication(&ul_info);
+                          mac->frame_type) && mac->ra.ra_state != RA_SUCCEEDED)
+        {
+            nr_ue_scheduler(NULL, &ul_info);
+            nr_ue_prach_scheduler(ul_info.module_id, ul_info.frame_tx, ul_info.slot_tx, ul_info.thread_id);
+        }
     }
 }
 
@@ -790,19 +797,19 @@ void save_nr_measurement_info(nfapi_nr_dl_tti_request_t *dl_tti_request)
         LOG_E(NR_PHY, "%s: dl_tti_request number of PDUS <= 0\n", __FUNCTION__);
         abort();
     }
-    LOG_D(NR_PHY, "%s: dl_tti_request number of PDUS: %d\n", __FUNCTION__, num_pdus);
+    LOG_T(NR_PHY, "%s: dl_tti_request number of PDUS: %d\n", __FUNCTION__, num_pdus);
     for (int i = 0; i < num_pdus; i++)
     {
         nfapi_nr_dl_tti_request_pdu_t *pdu_list = &dl_tti_request->dl_tti_request_body.dl_tti_pdu_list[i];
         if (pdu_list->PDUType == NFAPI_NR_DL_TTI_SSB_PDU_TYPE)
         {
-            LOG_D(NR_PHY, "Cell_id: %d, the ssb_block_idx %d, sc_offset: %d and payload %d\n",
+            LOG_T(NR_PHY, "Cell_id: %d, the ssb_block_idx %d, sc_offset: %d and payload %d\n",
                 pdu_list->ssb_pdu.ssb_pdu_rel15.PhysCellId,
                 pdu_list->ssb_pdu.ssb_pdu_rel15.SsbBlockIndex,
                 pdu_list->ssb_pdu.ssb_pdu_rel15.SsbSubcarrierOffset,
                 pdu_list->ssb_pdu.ssb_pdu_rel15.bchPayload);
             pdu_list->ssb_pdu.ssb_pdu_rel15.ssbRsrp = 60;
-            LOG_D(NR_RRC, "Setting pdulist[%d].ssbRsrp to %d\n", i, pdu_list->ssb_pdu.ssb_pdu_rel15.ssbRsrp);
+            LOG_T(NR_RRC, "Setting pdulist[%d].ssbRsrp to %d\n", i, pdu_list->ssb_pdu.ssb_pdu_rel15.ssbRsrp);
         }
     }
 
@@ -820,7 +827,7 @@ void save_nr_measurement_info(nfapi_nr_dl_tti_request_t *dl_tti_request)
 
 static void enqueue_nr_nfapi_msg(void *buffer, ssize_t len, nfapi_p7_message_header_t header)
 {
-
+    NR_UE_MAC_INST_t *mac = get_mac_inst(0);
     switch (header.message_id)
     {
         case NFAPI_NR_PHY_MSG_TYPE_DL_TTI_REQUEST:
@@ -832,8 +839,12 @@ static void enqueue_nr_nfapi_msg(void *buffer, ssize_t len, nfapi_p7_message_hea
                 LOG_E(NR_PHY, "Message dl_tti_request failed to unpack\n");
                 break;
             }
-            LOG_I(NR_PHY, "Received an NFAPI_NR_PHY_MSG_TYPE_DL_TTI_REQUEST message in sfn/slot %d %d. \n",
+            LOG_D(NR_PHY, "Received an NFAPI_NR_PHY_MSG_TYPE_DL_TTI_REQUEST message in sfn/slot %d %d. \n",
                     dl_tti_request->SFN, dl_tti_request->Slot);
+
+            if (is_channel_modeling())
+                save_pdsch_pdu_for_crnti(dl_tti_request);
+
             if (!put_queue(&nr_dl_tti_req_queue, dl_tti_request))
             {
                 LOG_E(NR_PHY, "put_queue failed for dl_tti_request.\n");
@@ -852,7 +863,7 @@ static void enqueue_nr_nfapi_msg(void *buffer, ssize_t len, nfapi_p7_message_hea
                 LOG_E(NR_PHY, "Message tx_data_request failed to unpack\n");
                 break;
             }
-            LOG_I(NR_PHY, "Received an NFAPI_NR_PHY_MSG_TYPE_TX_DATA_REQUEST message in SFN/slot %d %d. \n",
+            LOG_D(NR_PHY, "Received an NFAPI_NR_PHY_MSG_TYPE_TX_DATA_REQUEST message in SFN/slot %d %d. \n",
                     tx_data_request->SFN, tx_data_request->Slot);
             if (!put_queue(&nr_tx_req_queue, tx_data_request))
             {
@@ -872,7 +883,7 @@ static void enqueue_nr_nfapi_msg(void *buffer, ssize_t len, nfapi_p7_message_hea
                 LOG_E(NR_PHY, "Message ul_dci_request failed to unpack\n");
                 break;
             }
-            LOG_I(NR_PHY, "Received an NFAPI_NR_PHY_MSG_TYPE_UL_DCI_REQUEST message in SFN/slot %d %d. \n",
+            LOG_D(NR_PHY, "Received an NFAPI_NR_PHY_MSG_TYPE_UL_DCI_REQUEST message in SFN/slot %d %d. \n",
                     ul_dci_request->SFN, ul_dci_request->Slot);
             if (!put_queue(&nr_ul_dci_req_queue, ul_dci_request))
             {
@@ -892,30 +903,30 @@ static void enqueue_nr_nfapi_msg(void *buffer, ssize_t len, nfapi_p7_message_hea
                 LOG_E(NR_PHY, "Message ul_tti_request failed to unpack\n");
                 break;
             }
-            LOG_I(NR_PHY, "Received an NFAPI_NR_PHY_MSG_TYPE_UL_TTI_REQUEST message in SFN/slot %d %d.\n",
-                  ul_tti_request->SFN, ul_tti_request->Slot);
-            if (nr_uci_ind_queue.num_items > 0) //TODO: In the future UL_TTIs can be for ULSCH and SRS.
-            {
-                LOG_D(NR_MAC, "We added UL_TTI_REQ to queue for sfn slot %d %d\n",
-                      ul_tti_request->SFN, ul_tti_request->Slot);
-                if (!put_queue(&nr_ul_tti_req_queue, ul_tti_request))
-                {
-                    LOG_E(NR_PHY, "put_queue failed for ul_tti_request.\n");
-                    free(ul_tti_request);
-                    ul_tti_request = NULL;
+            /* We are filtering UL_TTI_REQs below. We only care about UL_TTI_REQs that
+               will trigger sending a ul_harq (CRC/RX pair). This UL_TTI_REQ will have
+               NFAPI_NR_UL_CONFIG_PUSCH_PDU_TYPE. If we have not yet completed the CBRA/
+               CFRA procedure, we need to queue all UL_TTI_REQs. */
+            for (int i = 0; i < ul_tti_request->n_pdus; i++) {
+                if (ul_tti_request->pdus_list[i].pdu_type == NFAPI_NR_UL_CONFIG_PUSCH_PDU_TYPE &&
+                    mac->ra.ra_state >= RA_SUCCEEDED) {
+                    if (!put_queue(&nr_ul_tti_req_queue, ul_tti_request))
+                    {
+                        LOG_D(NR_PHY, "put_queue failed for ul_tti_request, calling put_queue_replace.\n");
+                        nfapi_nr_ul_tti_request_t *evicted_ul_tti_req = put_queue_replace(&nr_ul_tti_req_queue, ul_tti_request);
+                        free(evicted_ul_tti_req);
+                    }
+                    break;
+                }
+                else if (mac->ra.ra_state < RA_SUCCEEDED) {
+                    if (!put_queue(&nr_ul_tti_req_queue, ul_tti_request))
+                    {
+                        LOG_D(NR_PHY, "put_queue failed for ul_tti_request, calling put_queue_replace.\n");
+                        nfapi_nr_ul_tti_request_t *evicted_ul_tti_req = put_queue_replace(&nr_ul_tti_req_queue, ul_tti_request);
+                        free(evicted_ul_tti_req);
+                    }
+                    break;
                 }
-            }
-            /* TODO: This indicates that dl_tti_req was late or never arrived. If there are
-               not any prepared uci indications, the NRUE likely never had time to
-               populate the message is the dl_tti_req came in late and we received a
-               ul_tti_req immediately after the dl_tti_request. This is an attempt to
-               mitigate proxy timing issues. */
-            else if (nr_uci_ind_queue.num_items == 0)
-            {
-                LOG_D(NR_MAC, "We added UL_TTI_REQ to queue for sfn slot %d %d\n",
-                      ul_tti_request->SFN, ul_tti_request->Slot);
-                nfapi_nr_ul_tti_request_t *evicted_ul_tti_req = put_queue_replace(&nr_wait_ul_tti_req_queue, ul_tti_request);
-                free(evicted_ul_tti_req);
             }
             break;
         }
@@ -928,6 +939,46 @@ static void enqueue_nr_nfapi_msg(void *buffer, ssize_t len, nfapi_p7_message_hea
     return;
 }
 
+static void save_pdsch_pdu_for_crnti(nfapi_nr_dl_tti_request_t *dl_tti_request)
+{
+  int count_sent = 0;
+  NR_UE_MAC_INST_t *mac = get_mac_inst(0);
+  int number_of_pdu = dl_tti_request->dl_tti_request_body.nPDUs;
+  if (number_of_pdu <= 0)
+  {
+    LOG_E(NR_MAC, "%s: dl_tti_request pdu size <= 0\n", __FUNCTION__);
+    abort();
+  }
+
+  for (int i = 0; i < number_of_pdu; i++)
+  {
+    const nfapi_nr_dl_tti_request_pdu_t *pdu_list = &dl_tti_request->dl_tti_request_body.dl_tti_pdu_list[i];
+
+    if (pdu_list->PDUType == NFAPI_NR_DL_TTI_PDSCH_PDU_TYPE)
+    {
+      const nfapi_nr_dl_tti_pdsch_pdu_rel15_t *pdsch_pdu = &pdu_list->pdsch_pdu.pdsch_pdu_rel15;
+      if (pdsch_pdu->rnti == mac->crnti && mac->ra.ra_state == RA_SUCCEEDED)
+      {
+        read_channel_param(pdsch_pdu, dl_tti_request->Slot, count_sent);
+        count_sent++;
+        LOG_T(NR_MAC, "pdsch_pdu->rnti %x  mac->crnti %x mac->ra.ra_state %d count_sent %d\n",
+                      pdsch_pdu->rnti, mac->crnti, mac->ra.ra_state, count_sent);
+      }
+    }
+  }
+}
+
+static uint16_t get_message_id(const uint8_t *buffer, ssize_t len)
+{
+  if (len < 4)
+    return 0;
+
+  // Unpack 2 bytes message_id from buffer.
+  uint16_t v;
+  memcpy(&v, buffer + 2, sizeof(v));
+  return ntohs(v);
+}
+
 void *nrue_standalone_pnf_task(void *context)
 {
   struct sockaddr_in server_address;
@@ -957,7 +1008,7 @@ void *nrue_standalone_pnf_task(void *context)
       uint16_t *sfn_slot = CALLOC(1, sizeof(*sfn_slot));
       memcpy(sfn_slot, buffer, sizeof(*sfn_slot));
 
-      LOG_I(NR_PHY, "Received from proxy sfn %d slot %d\n",
+      LOG_D(NR_PHY, "Received from proxy sfn %d slot %d\n",
             NFAPI_SFNSLOT2SFN(*sfn_slot), NFAPI_SFNSLOT2SLOT(*sfn_slot));
 
       if (!put_queue(&nr_sfn_slot_queue, sfn_slot))
@@ -971,13 +1022,22 @@ void *nrue_standalone_pnf_task(void *context)
         abort();
       }
     }
-    else if (len == sizeof(nr_phy_channel_params_t))
+    else if (get_message_id((const uint8_t *)buffer, len) == 0x0FFF) // 0x0FFF : channel info identifier.
     {
       nr_phy_channel_params_t *ch_info = CALLOC(1, sizeof(*ch_info));
       memcpy(ch_info, buffer, sizeof(*ch_info));
 
-      LOG_D(NR_PHY, "Received_SINR = %f, sfn:slot %d:%d\n",
-            ch_info->sinr, NFAPI_SFNSLOT2SFN(ch_info->sfn_slot), NFAPI_SFNSLOT2SLOT(ch_info->sfn_slot));
+      if (ch_info->nb_of_sinrs > 1)
+        LOG_W(NR_PHY, "Expecting at most one SINR.\n");
+
+      // TODO: Update sinr field of slot_rnti_mcs to be array.
+      for (int i = 0; i < ch_info->nb_of_sinrs; ++i)
+      {
+        slot_rnti_mcs[NFAPI_SFNSLOT2SLOT(ch_info->sfn_slot)].sinr = ch_info->sinr[i];
+
+        LOG_T(NR_PHY, "Received_SINR[%d] = %f, sfn:slot %d:%d\n",
+              i, ch_info->sinr[i], NFAPI_SFNSLOT2SFN(ch_info->sfn_slot), NFAPI_SFNSLOT2SLOT(ch_info->sfn_slot));
+      }
 
       if (!put_queue(&nr_chan_param_queue, ch_info))
       {
@@ -986,7 +1046,7 @@ void *nrue_standalone_pnf_task(void *context)
 
       if (sem_post(&sfn_slot_semaphore) != 0)
       {
-        LOG_E(MAC, "sem_post() error\n");
+        LOG_E(NR_MAC, "sem_post() error\n");
         abort();
       }
     }
@@ -1005,7 +1065,7 @@ void *nrue_standalone_pnf_task(void *context)
 
 //  L2 Abstraction Layer
 int handle_bcch_bch(module_id_t module_id, int cc_id,
-                    unsigned int gNB_index, uint8_t *pduP,
+                    unsigned int gNB_index, void *phy_data, uint8_t *pduP,
                     unsigned int additional_bits,
                     uint32_t ssb_index, uint32_t ssb_length,
                     uint16_t ssb_start_subcarrier, uint16_t cell_id){
@@ -1013,6 +1073,7 @@ int handle_bcch_bch(module_id_t module_id, int cc_id,
   return nr_ue_decode_mib(module_id,
 			  cc_id,
 			  gNB_index,
+			  phy_data,
 			  additional_bits,
 			  ssb_length,  //  Lssb = 64 is not support    
 			  ssb_index,
@@ -1037,7 +1098,10 @@ int handle_dci(module_id_t module_id, int cc_id, unsigned int gNB_index, frame_t
 // L2 Abstraction Layer
 // Note: sdu should always be processed because data and timing advance updates are transmitted by the UE
 int8_t handle_dlsch(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_t *ul_time_alignment, int pdu_id){
-
+  /* L1 assigns harq_pid, but in emulated L1 mode we need to assign
+     the harq_pid based on the saved global g_harq_pid. Because we are
+     emulating L1, no antenna measurements are conducted to calculate
+     a harq_pid, therefore we must set it here. */
   if (get_softmodem_params()->emulate_l1)
     dl_info->rx_ind->rx_indication_body[pdu_id].pdsch_pdu.harq_pid = g_harq_pid;
 
@@ -1058,18 +1122,17 @@ void update_harq_status(module_id_t module_id, uint8_t harq_pid, uint8_t ack_nac
   if (current_harq->active) {
     current_harq->ack = ack_nack;
     current_harq->ack_received = true;
-    LOG_D(PHY,"Updating harq_status for harq_id %d,ack/nak %d\n",harq_pid,current_harq->ack);
+    LOG_T(PHY,"Updating harq_status for harq_id %d,ack/nak %d\n",harq_pid,current_harq->ack);
   }
   else {
     //shouldn't get here
-    LOG_E(MAC, "Trying to process acknack for an inactive harq process (%d)\n", harq_pid);
+    LOG_E(NR_MAC, "Trying to process acknack for an inactive harq process (%d)\n", harq_pid);
   }
 }
 
-
 int nr_ue_ul_indication(nr_uplink_indication_t *ul_info){
 
-  NR_UE_L2_STATE_t ret;
+  NR_UE_L2_STATE_t ret=0;
   module_id_t module_id = ul_info->module_id;
   NR_UE_MAC_INST_t *mac = get_mac_inst(module_id);
 
@@ -1081,7 +1144,7 @@ int nr_ue_ul_indication(nr_uplink_indication_t *ul_info){
     ret = nr_ue_scheduler(NULL, ul_info);
   }
   else
-    LOG_D(NR_MAC, "In %s():%d not calling scheduler. sched mode = %d and mac->ra.ra_state = %d\n",
+    LOG_T(NR_MAC, "In %s():%d not calling scheduler. sched mode = %d and mac->ra.ra_state = %d\n",
         __FUNCTION__, __LINE__, ul_info->ue_sched_mode, mac->ra.ra_state);
 
   NR_TDD_UL_DL_ConfigCommon_t *tdd_UL_DL_ConfigurationCommon = mac->scc != NULL ? mac->scc->tdd_UL_DL_ConfigurationCommon : mac->scc_SIB->tdd_UL_DL_ConfigurationCommon;
@@ -1121,9 +1184,10 @@ int nr_ue_dl_indication(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_
   } else {
     // UL indication after reception of DCI or DL PDU
     if (dl_info && dl_info->dci_ind && dl_info->dci_ind->number_of_dcis) {
-      LOG_D(MAC,"[L2][IF MODULE][DL INDICATION][DCI_IND]\n");
+
+      LOG_T(MAC,"[L2][IF MODULE][DL INDICATION][DCI_IND]\n");
       for (int i = 0; i < dl_info->dci_ind->number_of_dcis; i++) {
-        LOG_D(MAC,">>>NR_IF_Module i=%d, dl_info->dci_ind->number_of_dcis=%d\n",i,dl_info->dci_ind->number_of_dcis);
+        LOG_T(MAC,">>>NR_IF_Module i=%d, dl_info->dci_ind->number_of_dcis=%d\n",i,dl_info->dci_ind->number_of_dcis);
         nr_scheduled_response_t scheduled_response;
         int8_t ret = handle_dci(dl_info->module_id,
                                 dl_info->cc_id,
@@ -1137,17 +1201,17 @@ int nr_ue_dl_indication(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_
         /* The check below filters out UL_DCIs (format 7) which are being processed as DL_DCIs. */
         if (dci_index->dci_format == 7 && mac->ra.ra_state == RA_SUCCEEDED) {
           LOG_D(NR_MAC, "We are filtering a UL_DCI to prevent it from being treated like a DL_DCI\n");
-          break;
+          continue;
         }
         dci_pdu_rel15_t *def_dci_pdu_rel15 = &mac->def_dci_pdu_rel15[dci_index->dci_format];
         g_harq_pid = def_dci_pdu_rel15->harq_pid;
-        LOG_D(NR_MAC, "Setting harq_pid = %d and dci_index = %d (based on format)\n", g_harq_pid, dci_index->dci_format);
+        LOG_T(NR_MAC, "Setting harq_pid = %d and dci_index = %d (based on format)\n", g_harq_pid, dci_index->dci_format);
 
         ret_mask |= (ret << FAPI_NR_DCI_IND);
         if (ret >= 0) {
           AssertFatal( nr_ue_if_module_inst[module_id] != NULL, "IF module is NULL!\n" );
           AssertFatal( nr_ue_if_module_inst[module_id]->scheduled_response != NULL, "scheduled_response is NULL!\n" );
-          fill_scheduled_response(&scheduled_response, dl_config, NULL, NULL, dl_info->module_id, dl_info->cc_id, dl_info->frame, dl_info->slot, dl_info->thread_id);
+          fill_scheduled_response(&scheduled_response, dl_config, NULL, NULL, dl_info->module_id, dl_info->cc_id, dl_info->frame, dl_info->slot, dl_info->thread_id, dl_info->phy_data);
           nr_ue_if_module_inst[module_id]->scheduled_response(&scheduled_response);
         }
         memset(def_dci_pdu_rel15, 0, sizeof(*def_dci_pdu_rel15));
@@ -1160,7 +1224,7 @@ int nr_ue_dl_indication(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_
 
       for (int i=0; i<dl_info->rx_ind->number_pdus; ++i) {
 
-        LOG_D(MAC, "In %s sending DL indication to MAC. 1 PDU type %d of %d total number of PDUs \n",
+        LOG_D(NR_MAC, "In %s sending DL indication to MAC. 1 PDU type %d of %d total number of PDUs \n",
           __FUNCTION__,
           dl_info->rx_ind->rx_indication_body[i].pdu_type,
           dl_info->rx_ind->number_pdus);
@@ -1168,7 +1232,7 @@ int nr_ue_dl_indication(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_
         switch(dl_info->rx_ind->rx_indication_body[i].pdu_type){
           case FAPI_NR_RX_PDU_TYPE_SSB:
             mac->ssb_rsrp_dBm = (dl_info->rx_ind->rx_indication_body+i)->ssb_pdu.rsrp_dBm;
-            ret_mask |= (handle_bcch_bch(dl_info->module_id, dl_info->cc_id, dl_info->gNB_index,
+            ret_mask |= (handle_bcch_bch(dl_info->module_id, dl_info->cc_id, dl_info->gNB_index, dl_info->phy_data,
                                          (dl_info->rx_ind->rx_indication_body+i)->ssb_pdu.pdu,
                                          (dl_info->rx_ind->rx_indication_body+i)->ssb_pdu.additional_bits,
                                          (dl_info->rx_ind->rx_indication_body+i)->ssb_pdu.ssb_index,
@@ -1244,7 +1308,7 @@ int nr_ue_dcireq(nr_dcireq_t *dcireq) {
   dl_config->sfn = UE_mac->dl_config_request.sfn;
   dl_config->slot = UE_mac->dl_config_request.slot;
 
-  LOG_D(PHY, "Entering UE DCI configuration frame %d slot %d \n", dcireq->frame, dcireq->slot);
+  LOG_T(PHY, "Entering UE DCI configuration frame %d slot %d \n", dcireq->frame, dcireq->slot);
 
   ue_dci_configuration(UE_mac, dl_config, dcireq->frame, dcireq->slot);
 
@@ -1279,3 +1343,245 @@ void RCconfig_nr_ue_L1(void) {
     }
   }
 }
+
+/*
+static int get_mcs_from_sinr(float sinr)
+{
+  if (sinr < (nr_bler_data[0].bler_table[0][0]))
+  {
+    LOG_D(NR_MAC, "The SINR found is smaller than first MCS table\n");
+    return 0;
+  }
+
+  if (sinr > (nr_bler_data[NR_NUM_MCS-1].bler_table[nr_bler_data[NR_NUM_MCS-1].length - 1][0]))
+  {
+    LOG_D(NR_MAC, "The SINR found is larger than last MCS table\n");
+    return NR_NUM_MCS-1;
+  }
+
+  for (int n = NR_NUM_MCS-1; n >= 0; n--)
+  {
+    CHECK_INDEX(nr_bler_data, n);
+    float largest_sinr = (nr_bler_data[n].bler_table[nr_bler_data[n].length - 1][0]);
+    float smallest_sinr = (nr_bler_data[n].bler_table[0][0]);
+    if (sinr < largest_sinr && sinr > smallest_sinr)
+    {
+      LOG_D(NR_MAC, "The SINR found in MCS %d table\n", n);
+      return n;
+    }
+  }
+  LOG_E(NR_MAC, "Unable to get an MCS value.\n");
+  abort();
+}
+*/
+
+/*
+static int get_cqi_from_mcs(void)
+{
+  static const int mcs_to_cqi[] = {0, 1, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8,
+                                   9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15};
+  assert(NUM_ELEMENTS(mcs_to_cqi) == NR_NUM_MCS);
+  int slot = 0;
+  while (slot < NUM_NFAPI_SLOT)
+  {
+    if (slot_rnti_mcs[slot].latest)
+    {
+      int num_pdus = slot_rnti_mcs[slot].num_pdus;
+      if (num_pdus <= 0)
+      {
+        LOG_E(NR_MAC, "%s: slot_rnti_mcs[%d].num_pdus = 0\n", __FUNCTION__, slot);
+        abort();
+      }
+
+      CHECK_INDEX(slot_rnti_mcs[slot].mcs, num_pdus);
+      int mcs = get_mcs_from_sinr(slot_rnti_mcs[slot].sinr);
+      CHECK_INDEX(mcs_to_cqi, mcs);
+      int cqi = mcs_to_cqi[mcs];
+      LOG_D(NR_MAC, "SINR: %f -> MCS: %d -> CQI: %d\n", slot_rnti_mcs[slot].sinr, mcs, cqi);
+      return cqi;
+    }
+    slot++;
+  }
+  LOG_E(NR_MAC, "Unable to get CQI value because no MCS found\n");
+  abort();
+}
+*/
+
+static void read_channel_param(const nfapi_nr_dl_tti_pdsch_pdu_rel15_t * pdu, int slot, int index)
+{
+  if (pdu == NULL)
+  {
+    LOG_E(NR_MAC,"PDU NULL\n");
+    abort();
+  }
+
+  /* This function is executed for every pdsch pdu type in a dl_tti_request. We save
+     the assocaited MCS and RNTI value for each. The 'index' passed in is a count of
+     how many times we have called this function for a particular dl_tti_request. It
+     allows us to save MCS/RNTI data in correct indicies when multiple pdsch pdu's are received.*/
+  for (int i = 0; i < NUM_NFAPI_SLOT; i++)
+  {
+    slot_rnti_mcs[i].latest = false;
+  }
+
+  CHECK_INDEX(slot_rnti_mcs[slot].rnti, index);
+  CHECK_INDEX(slot_rnti_mcs[slot].mcs, index);
+  CHECK_INDEX(slot_rnti_mcs[slot].drop_flag, index);
+  slot_rnti_mcs[slot].rnti[index] = pdu->rnti;
+  slot_rnti_mcs[slot].mcs[index] = pdu->mcsIndex[0];
+  slot_rnti_mcs[slot].rvIndex[index] = pdu->rvIndex[0];
+  slot_rnti_mcs[slot].drop_flag[index] = false;
+  slot_rnti_mcs[slot].num_pdus = index+1; //index starts at 0 so we incrament to get num of pdus
+  slot_rnti_mcs[slot].latest = true;
+  LOG_D(NR_MAC, "Adding MCS %d and RNTI %x for slot_rnti_mcs[%d]\n", slot_rnti_mcs[slot].mcs[index], slot_rnti_mcs[slot].rnti[index], slot);
+
+  return;
+}
+
+/*
+static bool did_drop_transport_block(int slot, uint16_t rnti)
+{
+  int num_pdus = slot_rnti_mcs[slot].num_pdus;
+  if (num_pdus <= 0)
+  {
+    LOG_E(MAC, "Problem, the PDU size is <= 0. We dropped this packet\n");
+    return true;
+  }
+  CHECK_INDEX(slot_rnti_mcs[slot].rnti, num_pdus);
+  CHECK_INDEX(slot_rnti_mcs[slot].drop_flag, num_pdus);
+  for (int n = 0; n < num_pdus; n++)
+  {
+    if (slot_rnti_mcs[slot].rnti[n] == rnti && slot_rnti_mcs[slot].drop_flag[n])
+    {
+      return true;
+    }
+  }
+  return false;
+}
+*/
+
+static float get_bler_val(uint8_t mcs, int sinr)
+{
+  // 4th col = dropped packets, 5th col = total packets
+  float bler_val = 0.0;
+  CHECK_INDEX(nr_bler_data, mcs);
+  LOG_D(NR_MAC, "sinr %d min %d max %d\n", sinr,
+                (int)(nr_bler_data[mcs].bler_table[0][0] * 10),
+                (int)(nr_bler_data[mcs].bler_table[nr_bler_data[mcs].length - 1][0] * 10)
+  );
+
+  if (sinr < (int)(nr_bler_data[mcs].bler_table[0][0] * 10))
+  {
+    LOG_D(NR_MAC, "MCS %d table. SINR is smaller than lowest SINR, bler_val is set based on lowest SINR in table\n", mcs);
+    bler_val = nr_bler_data[mcs].bler_table[0][4] / nr_bler_data[mcs].bler_table[0][5];
+    return bler_val;
+  }
+  if (sinr > (int)(nr_bler_data[mcs].bler_table[nr_bler_data[mcs].length - 1][0] * 10))
+  {
+    LOG_D(NR_MAC, "MCS %d table. SINR is greater than largest SINR. bler_val is set based on largest SINR in table\n", mcs);
+    bler_val = nr_bler_data[mcs].bler_table[(nr_bler_data[mcs].length - 1)][4] / nr_bler_data[mcs].bler_table[(nr_bler_data[mcs].length - 1)][5];
+    return bler_val;
+  }
+  // Loop through bler table to find sinr_index
+  for (int i = 0; i < nr_bler_data[mcs].length; i++)
+  {
+    int temp_sinr = (int)(nr_bler_data[mcs].bler_table[i][0] * 10);
+    if (temp_sinr == sinr)
+    {
+      bler_val = nr_bler_data[mcs].bler_table[i][4] / nr_bler_data[mcs].bler_table[i][5];
+      return bler_val;
+    }
+    // Linear interpolation when SINR is between indices
+    if (temp_sinr > sinr)
+    {
+      float bler_val1 = nr_bler_data[mcs].bler_table[i - 1][4] / nr_bler_data[mcs].bler_table[i - 1][5];
+      float bler_val2 = nr_bler_data[mcs].bler_table[i][4] / nr_bler_data[mcs].bler_table[i][5];
+      LOG_D(NR_MAC, "sinr %d min %f max %f\n", sinr, bler_val1, bler_val2);
+      return ((bler_val1 + bler_val2) / 2);
+    }
+  }
+  LOG_E(NR_MAC, "NO SINR INDEX FOUND!\n");
+  abort();
+
+}
+
+static inline bool is_channel_modeling(void)
+{
+  /* TODO: For now we enable channel modeling based on the node_number.
+     Replace with a command line option to enable/disable channel modeling.
+     The LTE UE will crash when channel modeling is conducted for NSA
+     mode. It does not crash for LTE mode. We have not implemented channel
+     modeling for NSA mode yet. For now, we ensure only do do channel modeling
+     in LTE/NR mode. */
+  return get_softmodem_params()->node_number == 0 && !get_softmodem_params()->nsa;
+}
+
+static bool should_drop_transport_block(int slot, uint16_t rnti)
+{
+  if (!is_channel_modeling())
+  {
+    return false;
+  }
+
+  /* We want to avoid dropping setup messages because this would be pathological. */
+  NR_UE_MAC_INST_t *mac = get_mac_inst(0);
+  if (mac->ra.ra_state < RA_SUCCEEDED)
+  {
+    LOG_D(NR_MAC, "Not dropping because MAC state: %d", mac->ra.ra_state);
+    return false;
+  }
+
+  /* Get block error rate (bler_val) from table based on every saved
+     MCS and SINR to be used as the cutoff rate for dropping packets.
+     Generate random uniform vairable to compare against bler_val. */
+  int num_pdus = slot_rnti_mcs[slot].num_pdus;
+  assert(slot < 20 && slot >= 0);
+  LOG_D(NR_MAC, "rnti: %x  num_pdus %d state %d slot %u sinr %f\n",
+        rnti, num_pdus, mac->ra.ra_state, slot, slot_rnti_mcs[slot].sinr);
+  assert(num_pdus > 0);
+  CHECK_INDEX(slot_rnti_mcs[slot].rnti, num_pdus);
+  CHECK_INDEX(slot_rnti_mcs[slot].mcs, num_pdus);
+  CHECK_INDEX(slot_rnti_mcs[slot].drop_flag, num_pdus);
+  int n = 0;
+  uint8_t mcs = 99;
+  for (n = 0; n < num_pdus; n++)
+  {
+    if (slot_rnti_mcs[slot].rnti[n] == rnti)
+    {
+      mcs = slot_rnti_mcs[slot].mcs[n];
+    }
+    if (mcs != 99)
+    {
+      /* Use MCS to get the bler value. Since there can be multiple MCS
+         values for a particular slot, we verify that all PDUs are not
+         flagged for drop before returning. If even one is flagged for drop
+         we return immediately because we drop the entire packet. */
+
+      LOG_D(NR_MAC, "rnti: %x mcs %u slot %u sinr %f\n",
+        slot_rnti_mcs[slot].rnti[n], mcs, slot, slot_rnti_mcs[slot].sinr);
+
+      float bler_val;
+      if (slot_rnti_mcs[slot].rvIndex[n] != 0)
+        bler_val = 0;
+      else
+        bler_val = get_bler_val(mcs, ((int)(slot_rnti_mcs[slot].sinr * 10)));
+      double drop_cutoff = ((double) rand() / (RAND_MAX));
+      assert(drop_cutoff <= 1);
+      LOG_D(NR_MAC, "SINR = %f, Bler_val = %f, MCS = %"PRIu8"\n", slot_rnti_mcs[slot].sinr, bler_val, slot_rnti_mcs[slot].mcs[n]);
+      if (drop_cutoff <= bler_val)
+      {
+        slot_rnti_mcs[slot].drop_flag[n] = true;
+        LOG_T(NR_MAC, "We are dropping this packet. Bler_val = %f, MCS = %"PRIu8", slot = %d\n", bler_val, slot_rnti_mcs[slot].mcs[n], slot);
+        return slot_rnti_mcs[slot].drop_flag[n];
+      }
+    }
+
+  }
+
+  if (mcs == 99)
+  {
+    LOG_E(NR_MAC, "NO MCS Found for rnti %x. slot_rnti_mcs[%d].mcs[%d] \n", rnti, slot, n);
+    abort();
+  }
+  return false;
+}
diff --git a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.h b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.h
index 2a8a5147694b8d86dd6d0c488f2cf717cb8ef9f3..45d1a071ca96323c353dcf5d0b5754c773fedae2 100755
--- a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.h
+++ b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.h
@@ -41,15 +41,44 @@
 #include "nfapi_nr_interface_scf.h"
 #include "openair2/NR_PHY_INTERFACE/NR_IF_Module.h"
 
+#define NR_NUM_MCS 29
+#define NUM_SINR 100
+#define NUM_BLER_COL 13
+#define NUM_NFAPI_SLOT 20
+#define NR_NUM_LAYER 1
+
 typedef struct NR_UL_TIME_ALIGNMENT NR_UL_TIME_ALIGNMENT_t;
 
 typedef struct nr_phy_channel_params_t
 {
     uint16_t sfn_slot;
-    float sinr;
+    uint16_t message_id;
+    uint16_t nb_of_sinrs;
+    float sinr[NR_NUM_LAYER];
     // Incomplete, need all channel parameters
 } nr_phy_channel_params_t;
 
+typedef struct
+{
+    uint8_t slot;
+    uint16_t rnti[256];
+    uint8_t mcs[256];
+    uint8_t rvIndex[256];
+    float sinr;
+    uint16_t num_pdus;
+    bool drop_flag[256];
+    bool latest;
+
+} slot_rnti_mcs_s;
+
+typedef struct
+{
+    uint16_t length;
+    float bler_table[NUM_SINR][NUM_BLER_COL];
+} nr_bler_struct;
+
+extern nr_bler_struct nr_bler_data[NR_NUM_MCS];
+
 typedef enum {
   ONLY_PUSCH,
   NOT_PUSCH,
@@ -94,6 +123,9 @@ typedef struct {
     /// dci reception indication structure
     fapi_nr_dci_indication_t *dci_ind;
 
+    /// PHY specific data structure that can be passed on to L2 via nr_downlink_indication_t and
+    /// back to L1 via the nr_scheduled_response_t 
+    void *phy_data;
 } nr_downlink_indication_t;
 
 
@@ -147,6 +179,9 @@ typedef struct {
     /// data transmission request structure
     fapi_nr_tx_request_t *tx_request;
 
+    /// PHY data structure initially passed on to L2 via the nr_downlink_indication_t and
+    /// returned to L1 via nr_scheduled_response_t
+    void *phy_data;
 } nr_scheduled_response_t;
 
 typedef struct {
@@ -240,6 +275,8 @@ void check_and_process_dci(nfapi_nr_dl_tti_request_t *dl_tti_request,
                            nfapi_nr_ul_dci_request_t *ul_dci_request,
                            nfapi_nr_ul_tti_request_t *ul_tti_request);
 
+bool sfn_slot_matcher(void *wanted, void *candidate);
+
 /**\brief done free of memory allocation by module_id and release to pointer pool.
    \param module_id module id*/
 int nr_ue_if_module_kill(uint32_t module_id);
@@ -255,6 +292,7 @@ int nr_ue_dcireq(nr_dcireq_t *dcireq);
 
 //  TODO check
 /**\brief handle BCCH-BCH message from dl_indication
+   \param phy_data        PHY structure to be filled in by the callee in the FAPI call (L1 caller -> indication to L2 -> FAPI call to L1 callee)
    \param pduP            pointer to bch pdu
    \param additional_bits corresponding to 38.212 ch.7
    \param ssb_index       SSB index within 0 - (L_ssb-1) corresponding to 38.331 ch.13 parameter i
@@ -263,6 +301,7 @@ int nr_ue_dcireq(nr_dcireq_t *dcireq);
 int handle_bcch_bch(module_id_t module_id,
                     int cc_id,
                     unsigned int gNB_index,
+                    void *phy_data,
                     uint8_t *pduP,
                     unsigned int additional_bits,
                     uint32_t ssb_index,
diff --git a/openair2/PHY_INTERFACE/phy_stub_UE.c b/openair2/PHY_INTERFACE/phy_stub_UE.c
index 1598e3d6203c91a80a838a538f55144544d7eaa4..c4650f18f3a93e8c7e1878bbc5e687b6b0da81b2 100644
--- a/openair2/PHY_INTERFACE/phy_stub_UE.c
+++ b/openair2/PHY_INTERFACE/phy_stub_UE.c
@@ -1259,6 +1259,17 @@ void ue_init_standalone_socket(int tx_port, int rx_port)
   }
 }
 
+static uint16_t get_message_id(const uint8_t *buffer, ssize_t len)
+{
+  if (len < 4)
+    return 0;
+
+  // Unpack 2 bytes message_id from buffer.
+  uint16_t v;
+  memcpy(&v, buffer + 2, sizeof(v));
+  return ntohs(v);
+}
+
 void *ue_standalone_pnf_task(void *context)
 {
   struct sockaddr_in server_address;
@@ -1301,7 +1312,7 @@ void *ue_standalone_pnf_task(void *context)
         abort();
       }
     }
-    else if (len == sizeof(phy_channel_params_t))
+    else if (get_message_id((const uint8_t *)buffer, len) == 0x0FFF) // 0x0FFF : channel info identifier.
     {
       phy_channel_params_t ch_info;
       memcpy(&ch_info, buffer, sizeof(phy_channel_params_t));
@@ -1314,8 +1325,15 @@ void *ue_standalone_pnf_task(void *context)
       uint16_t sf = ch_info.sfn_sf & 15;
       assert(sf < 10);
 
-      sf_rnti_mcs[sf].sinr = ch_info.sinr;
-      LOG_D(MAC, "Received_SINR = %f\n",ch_info.sinr);
+      if (ch_info.nb_of_sinrs > 1)
+        LOG_W(MAC, "Expecting at most one SINR.\n");
+
+      // TODO: Update sinr field of slot_rnti_mcs to be array.
+      for (int i = 0; i < ch_info.nb_of_sinrs; ++i)
+      {
+        sf_rnti_mcs[sf].sinr = ch_info.sinr[i];
+        LOG_D(MAC, "Received_SINR[%d] = %f\n", i, ch_info.sinr[i]);
+      }
     }
     else
     {
diff --git a/openair2/PHY_INTERFACE/phy_stub_UE.h b/openair2/PHY_INTERFACE/phy_stub_UE.h
index ebaae6e667b8aa7f8a7a88415871ba73df23f34f..d68d1dffdd91a25371c7193521bd2ae68f8a3298 100644
--- a/openair2/PHY_INTERFACE/phy_stub_UE.h
+++ b/openair2/PHY_INTERFACE/phy_stub_UE.h
@@ -24,6 +24,7 @@
 #define NUM_MCS 28
 #define NUM_SINR 100
 #define NUM_BLER_COL 13
+#define LTE_NUM_LAYER 1
 
 // this mutex is used to set multiple UE's UL value in L2 FAPI simulator.
 extern FILL_UL_INFO_MUTEX_t fill_ul_mutex;
@@ -126,7 +127,9 @@ void handle_nfapi_ul_pdu_UE_MAC(module_id_t Mod_id,
 typedef struct phy_channel_params_t
 {
     uint16_t sfn_sf;
-    float sinr;
+    uint16_t message_id;
+    uint16_t nb_of_sinrs;
+    float sinr[LTE_NUM_LAYER];
     // Incomplete, need all channel parameters
 } phy_channel_params_t;
 
diff --git a/openair2/RRC/LTE/rrc_UE.c b/openair2/RRC/LTE/rrc_UE.c
index b46bba249268ff8466f195a3afb7a972f3eedebe..9b37853ed2b2ac5503f29632e66e9f88cf3bbf99 100644
--- a/openair2/RRC/LTE/rrc_UE.c
+++ b/openair2/RRC/LTE/rrc_UE.c
@@ -3175,7 +3175,8 @@ int decode_SIB1( const protocol_ctxt_t *const ctxt_pP, const uint8_t eNB_index,
     const size_t num_plmn_data = sizeof(plmn_data) / sizeof(plmn_data[0]);
     for (size_t plmn_ind = 0;; ++plmn_ind) {
       if (plmn_ind == num_plmn_data) {
-        LOG_E( RRC, "Did not find name from internal table for %u %u\n", mcc, mnc);
+        LOG_W( RRC, "Did not find operator name from internal table for MCC %0*d, MNC %0*d\n",
+               mccdigits, mcc, mncdigits, mnc);
         break;
       }
       if ((plmn_data[plmn_ind].mcc == mcc) && (plmn_data[plmn_ind].mnc == mnc)) {
diff --git a/openair2/RRC/LTE/rrc_eNB_S1AP.c b/openair2/RRC/LTE/rrc_eNB_S1AP.c
index 9b9e267828552335e0754e90f097435b51c13cc4..f24c9ab1b616df1c3cf5d781c4feb515c435ffbf 100644
--- a/openair2/RRC/LTE/rrc_eNB_S1AP.c
+++ b/openair2/RRC/LTE/rrc_eNB_S1AP.c
@@ -1757,7 +1757,7 @@ int rrc_eNB_process_PAGING_IND(MessageDef *msg_p, const char *msg_name, instance
           && RC.rrc[instance]->configuration.mnc[j] == S1AP_PAGING_IND(msg_p).plmn_identity[tai_size].mnc
           && RC.rrc[instance]->configuration.tac == S1AP_PAGING_IND(msg_p).tac[tai_size]) {
         for (uint8_t CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
-          lte_frame_type_t frame_type = RC.eNB[instance][CC_id]->frame_parms.frame_type;
+          frame_type_t frame_type = RC.eNB[instance][CC_id]->frame_parms.frame_type;
           /* get nB from configuration */
           /* get default DRX cycle from configuration */
           Tc = (uint8_t)RC.rrc[instance]->configuration.radioresourceconfig[CC_id].pcch_defaultPagingCycle;
diff --git a/openair2/RRC/NR/MESSAGES/asn1_msg.c b/openair2/RRC/NR/MESSAGES/asn1_msg.c
index 9a59d1977ac2754ca03a150fe450c8d4d0312ecc..9252a23596156771840f8f939f39ee3d52c4abcb 100755
--- a/openair2/RRC/NR/MESSAGES/asn1_msg.c
+++ b/openair2/RRC/NR/MESSAGES/asn1_msg.c
@@ -1452,15 +1452,15 @@ void fill_mastercellGroupConfig(NR_CellGroupConfig_t *cellGroupConfig, NR_CellGr
   ASN_SEQUENCE_ADD(&ue_context_mastercellGroup->rlc_BearerToAddModList->list, rlc_BearerConfig_drb);
 }
 
+
 void update_cellGroupConfig(NR_CellGroupConfig_t *cellGroupConfig,
-                            rrc_gNB_carrier_data_t *carrier,
                             NR_UE_NR_Capability_t *uecap,
-                            const gNB_RrcConfigurationReq* configuration)
-{
+                            const gNB_RrcConfigurationReq* configuration) {
+
   NR_SpCellConfig_t *SpCellConfig = cellGroupConfig->spCellConfig;
   if (SpCellConfig == NULL) return;
 
-  NR_ServingCellConfigCommon_t *scc = carrier->servingcellconfigcommon;
+  NR_ServingCellConfigCommon_t *scc = configuration->scc;
 
   NR_BWP_DownlinkDedicated_t *bwp_Dedicated = SpCellConfig->spCellConfigDedicated->initialDownlinkBWP;
   set_dl_mcs_table(scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.subcarrierSpacing,
@@ -1471,7 +1471,7 @@ void update_cellGroupConfig(NR_CellGroupConfig_t *cellGroupConfig,
     for (int i=0; i<DL_BWP_list->list.count; i++){
       NR_BWP_Downlink_t *bwp = DL_BWP_list->list.array[i];
       int scs = bwp->bwp_Common->genericParameters.subcarrierSpacing;
-      set_dl_mcs_table(scs, configuration->force_256qam_off ? NULL : uecap, bwp->bwp_Dedicated, carrier->servingcellconfigcommon);
+      set_dl_mcs_table(scs, configuration->force_256qam_off ? NULL : uecap, bwp->bwp_Dedicated, scc);
     }
   }
 }
@@ -1951,9 +1951,9 @@ int16_t do_RRCReconfiguration(
 
     if(cellGroupConfig!=NULL){
       update_cellGroupConfig(cellGroupConfig,
-                             carrier,
                              ue_context_pP->ue_context.UE_Capability_nr,
                              configuration);
+
       enc_rval = uper_encode_to_buffer(&asn_DEF_NR_CellGroupConfig,
           NULL,
           (void *)cellGroupConfig,
diff --git a/openair2/RRC/NR/MESSAGES/asn1_msg.h b/openair2/RRC/NR/MESSAGES/asn1_msg.h
index 52efba6f45dba44099631f0f840f818d4c47fcb7..aeef5f93a7ef1eac76400206cd0bbf44c9fe595e 100644
--- a/openair2/RRC/NR/MESSAGES/asn1_msg.h
+++ b/openair2/RRC/NR/MESSAGES/asn1_msg.h
@@ -112,7 +112,6 @@ void fill_initial_cellGroupConfig(int uid,
                                   const gNB_RrcConfigurationReq *configuration);
 
 void update_cellGroupConfig(NR_CellGroupConfig_t *cellGroupConfig,
-                            rrc_gNB_carrier_data_t *carrier,
                             NR_UE_NR_Capability_t *uecap,
                             const gNB_RrcConfigurationReq *configuration);
 
diff --git a/openair2/RRC/NR/nr_rrc_config.c b/openair2/RRC/NR/nr_rrc_config.c
index f8f05f2fe59abd98efc07f35637685d81910dd7c..54fb5a168b1e30d9bf9b56f9aa7ef5813c074287 100644
--- a/openair2/RRC/NR/nr_rrc_config.c
+++ b/openair2/RRC/NR/nr_rrc_config.c
@@ -31,6 +31,145 @@
 #include "nr_rrc_config.h"
 #include "common/utils/nr/nr_common.h"
 
+const uint8_t slotsperframe[5] = {10, 20, 40, 80, 160};
+
+
+void set_csirs_periodicity(NR_NZP_CSI_RS_Resource_t *nzpcsi0, int uid, int nb_slots_per_period) {
+
+  nzpcsi0->periodicityAndOffset = calloc(1,sizeof(*nzpcsi0->periodicityAndOffset));
+  int ideal_period = nb_slots_per_period*MAX_MOBILES_PER_GNB;
+
+  if (ideal_period<5) {
+    nzpcsi0->periodicityAndOffset->present = NR_CSI_ResourcePeriodicityAndOffset_PR_slots4;
+    nzpcsi0->periodicityAndOffset->choice.slots4 = nb_slots_per_period*uid;
+  }
+  else if (ideal_period<6) {
+    nzpcsi0->periodicityAndOffset->present = NR_CSI_ResourcePeriodicityAndOffset_PR_slots5;
+    nzpcsi0->periodicityAndOffset->choice.slots5 = nb_slots_per_period*uid;
+  }
+  else if (ideal_period<9) {
+    nzpcsi0->periodicityAndOffset->present = NR_CSI_ResourcePeriodicityAndOffset_PR_slots8;
+    nzpcsi0->periodicityAndOffset->choice.slots8 = nb_slots_per_period*uid;
+  }
+  else if (ideal_period<11) {
+    nzpcsi0->periodicityAndOffset->present = NR_CSI_ResourcePeriodicityAndOffset_PR_slots10;
+    nzpcsi0->periodicityAndOffset->choice.slots10 = nb_slots_per_period*uid;
+  }
+  else if (ideal_period<17) {
+    nzpcsi0->periodicityAndOffset->present = NR_CSI_ResourcePeriodicityAndOffset_PR_slots16;
+    nzpcsi0->periodicityAndOffset->choice.slots16 = nb_slots_per_period*uid;
+  }
+  else if (ideal_period<21) {
+    nzpcsi0->periodicityAndOffset->present = NR_CSI_ResourcePeriodicityAndOffset_PR_slots20;
+    nzpcsi0->periodicityAndOffset->choice.slots20 = nb_slots_per_period*uid;
+  }
+  else if (ideal_period<41) {
+    nzpcsi0->periodicityAndOffset->present = NR_CSI_ResourcePeriodicityAndOffset_PR_slots40;
+    nzpcsi0->periodicityAndOffset->choice.slots40 = nb_slots_per_period*uid;
+  }
+  else if (ideal_period<81) {
+    nzpcsi0->periodicityAndOffset->present = NR_CSI_ResourcePeriodicityAndOffset_PR_slots80;
+    nzpcsi0->periodicityAndOffset->choice.slots80 = nb_slots_per_period*uid;
+  }
+  else if (ideal_period<161) {
+    nzpcsi0->periodicityAndOffset->present = NR_CSI_ResourcePeriodicityAndOffset_PR_slots160;
+    nzpcsi0->periodicityAndOffset->choice.slots160 = nb_slots_per_period*uid;
+  }
+  else {
+    nzpcsi0->periodicityAndOffset->present = NR_CSI_ResourcePeriodicityAndOffset_PR_slots320;
+    nzpcsi0->periodicityAndOffset->choice.slots320 = (nb_slots_per_period*uid)%320 + (nb_slots_per_period*uid)/320;
+  }
+}
+
+
+void config_csirs(NR_ServingCellConfigCommon_t *servingcellconfigcommon,
+                  NR_CSI_MeasConfig_t *csi_MeasConfig,
+                  int uid,
+                  int num_dl_antenna_ports,
+                  int curr_bwp,
+                  int do_csirs) {
+
+  if (do_csirs) {
+
+    csi_MeasConfig->nzp_CSI_RS_ResourceSetToAddModList  = calloc(1,sizeof(*csi_MeasConfig->nzp_CSI_RS_ResourceSetToAddModList));
+    NR_NZP_CSI_RS_ResourceSet_t *nzpcsirs0 = calloc(1,sizeof(*nzpcsirs0));
+    nzpcsirs0->nzp_CSI_ResourceSetId = 0;
+    NR_NZP_CSI_RS_ResourceId_t *nzpid0 = calloc(1,sizeof(*nzpid0));
+    *nzpid0 = 0;
+    ASN_SEQUENCE_ADD(&nzpcsirs0->nzp_CSI_RS_Resources,nzpid0);
+    nzpcsirs0->repetition = NULL;
+    nzpcsirs0->aperiodicTriggeringOffset = NULL;
+    nzpcsirs0->trs_Info = NULL;
+    ASN_SEQUENCE_ADD(&csi_MeasConfig->nzp_CSI_RS_ResourceSetToAddModList->list,nzpcsirs0);
+
+    const NR_TDD_UL_DL_Pattern_t *tdd = servingcellconfigcommon->tdd_UL_DL_ConfigurationCommon ?
+                                        &servingcellconfigcommon->tdd_UL_DL_ConfigurationCommon->pattern1 : NULL;
+
+    const int n_slots_frame = slotsperframe[*servingcellconfigcommon->ssbSubcarrierSpacing];
+
+    int nb_slots_per_period = n_slots_frame;
+    if (tdd)
+      nb_slots_per_period = n_slots_frame/get_nb_periods_per_frame(tdd->dl_UL_TransmissionPeriodicity);
+
+    csi_MeasConfig->nzp_CSI_RS_ResourceToAddModList = calloc(1,sizeof(*csi_MeasConfig->nzp_CSI_RS_ResourceToAddModList));
+    NR_NZP_CSI_RS_Resource_t *nzpcsi0 = calloc(1,sizeof(*nzpcsi0));
+    nzpcsi0->nzp_CSI_RS_ResourceId = 0;
+    NR_CSI_RS_ResourceMapping_t resourceMapping;
+    switch (num_dl_antenna_ports) {
+      case 1:
+        resourceMapping.frequencyDomainAllocation.present = NR_CSI_RS_ResourceMapping__frequencyDomainAllocation_PR_row2;
+        resourceMapping.frequencyDomainAllocation.choice.row2.buf = calloc(2, sizeof(uint8_t));
+        resourceMapping.frequencyDomainAllocation.choice.row2.size = 2;
+        resourceMapping.frequencyDomainAllocation.choice.row2.bits_unused = 4;
+        resourceMapping.frequencyDomainAllocation.choice.row2.buf[0] = 0;
+        resourceMapping.frequencyDomainAllocation.choice.row2.buf[1] = 16;
+        resourceMapping.nrofPorts = NR_CSI_RS_ResourceMapping__nrofPorts_p1;
+        resourceMapping.cdm_Type = NR_CSI_RS_ResourceMapping__cdm_Type_noCDM;
+        break;
+      case 2:
+        resourceMapping.frequencyDomainAllocation.present = NR_CSI_RS_ResourceMapping__frequencyDomainAllocation_PR_other;
+        resourceMapping.frequencyDomainAllocation.choice.other.buf = calloc(2, sizeof(uint8_t));
+        resourceMapping.frequencyDomainAllocation.choice.other.size = 1;
+        resourceMapping.frequencyDomainAllocation.choice.other.bits_unused = 2;
+        resourceMapping.frequencyDomainAllocation.choice.other.buf[0] = 4;
+        resourceMapping.nrofPorts = NR_CSI_RS_ResourceMapping__nrofPorts_p2;
+        resourceMapping.cdm_Type = NR_CSI_RS_ResourceMapping__cdm_Type_fd_CDM2;
+        break;
+      case 4:
+        resourceMapping.frequencyDomainAllocation.present = NR_CSI_RS_ResourceMapping__frequencyDomainAllocation_PR_row4;
+        resourceMapping.frequencyDomainAllocation.choice.row4.buf = calloc(2, sizeof(uint8_t));
+        resourceMapping.frequencyDomainAllocation.choice.row4.size = 1;
+        resourceMapping.frequencyDomainAllocation.choice.row4.bits_unused = 5;
+        resourceMapping.frequencyDomainAllocation.choice.row4.buf[0] = 32;
+        resourceMapping.nrofPorts = NR_CSI_RS_ResourceMapping__nrofPorts_p4;
+        resourceMapping.cdm_Type = NR_CSI_RS_ResourceMapping__cdm_Type_fd_CDM2;
+        break;
+      default:
+        AssertFatal(1==0,"Number of ports not yet supported\n");
+    }
+    resourceMapping.firstOFDMSymbolInTimeDomain = 13;  // last symbol of slot
+    resourceMapping.firstOFDMSymbolInTimeDomain2 = NULL;
+    resourceMapping.density.present = NR_CSI_RS_ResourceMapping__density_PR_one;
+    resourceMapping.density.choice.one = (NULL_t)0;
+    resourceMapping.freqBand.startingRB = 0;
+    resourceMapping.freqBand.nrofRBs = ((curr_bwp>>2)+(curr_bwp%4>0))<<2;
+    nzpcsi0->resourceMapping = resourceMapping;
+    nzpcsi0->powerControlOffset = 0;
+    nzpcsi0->powerControlOffsetSS=calloc(1,sizeof(*nzpcsi0->powerControlOffsetSS));
+    *nzpcsi0->powerControlOffsetSS = NR_NZP_CSI_RS_Resource__powerControlOffsetSS_db0;
+    nzpcsi0->scramblingID = *servingcellconfigcommon->physCellId;
+    set_csirs_periodicity(nzpcsi0, uid, nb_slots_per_period);
+    nzpcsi0->qcl_InfoPeriodicCSI_RS = NULL;
+    ASN_SEQUENCE_ADD(&csi_MeasConfig->nzp_CSI_RS_ResourceToAddModList->list,nzpcsi0);
+  }
+  else {
+    csi_MeasConfig->nzp_CSI_RS_ResourceToAddModList = NULL;
+    csi_MeasConfig->nzp_CSI_RS_ResourceSetToAddModList  = NULL;
+  }
+  csi_MeasConfig->nzp_CSI_RS_ResourceSetToReleaseList = NULL;
+  csi_MeasConfig->nzp_CSI_RS_ResourceToReleaseList = NULL;
+}
+
 void prepare_sim_uecap(NR_UE_NR_Capability_t *cap,
                        NR_ServingCellConfigCommon_t *scc,
                        int numerology,
@@ -77,7 +216,7 @@ void prepare_sim_uecap(NR_UE_NR_Capability_t *cap,
 
 void nr_rrc_config_dl_tda(NR_ServingCellConfigCommon_t *scc){
 
-  lte_frame_type_t frame_type = get_frame_type(*scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0], *scc->ssbSubcarrierSpacing);
+  frame_type_t frame_type = get_frame_type(*scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0], *scc->ssbSubcarrierSpacing);
   int curr_bwp = scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth;
   // coreset duration setting to be improved in the framework of RRC harmonization, potentially using a common function
   int len_coreset = 1;
@@ -114,7 +253,7 @@ void nr_rrc_config_ul_tda(NR_ServingCellConfigCommon_t *scc, int min_fb_delay){
 
   uint8_t DELTA[4]= {2,3,4,6}; // Delta parameter for Msg3
   int mu = scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.subcarrierSpacing;
-  lte_frame_type_t frame_type = get_frame_type(*scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0], *scc->ssbSubcarrierSpacing);
+  frame_type_t frame_type = get_frame_type(*scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0], *scc->ssbSubcarrierSpacing);
 
   struct NR_PUSCH_TimeDomainResourceAllocation *pusch_timedomainresourceallocation = CALLOC(1,sizeof(struct NR_PUSCH_TimeDomainResourceAllocation));
   pusch_timedomainresourceallocation->k2  = CALLOC(1,sizeof(long));
diff --git a/openair2/RRC/NR/nr_rrc_config.h b/openair2/RRC/NR/nr_rrc_config.h
index 1a0d091e3594ef01f77dbc3185d01f5ec764c5d8..7a0fe892fdc850f02138959e4b9261fa8f987636 100644
--- a/openair2/RRC/NR/nr_rrc_config.h
+++ b/openair2/RRC/NR/nr_rrc_config.h
@@ -113,6 +113,12 @@ typedef struct physicalcellgroup_s{
 
 void nr_rrc_config_dl_tda(NR_ServingCellConfigCommon_t *scc);
 void nr_rrc_config_ul_tda(NR_ServingCellConfigCommon_t *scc, int min_fb_delay);
+void config_csirs(NR_ServingCellConfigCommon_t *servingcellconfigcommon,
+                  NR_CSI_MeasConfig_t *csi_MeasConfig,
+                  int uid,
+                  int num_dl_antenna_ports,
+                  int curr_bwp,
+                  int do_csirs);
 void set_dl_mcs_table(int scs, NR_UE_NR_Capability_t *cap,
                       NR_BWP_DownlinkDedicated_t *bwp_Dedicated,
                       NR_ServingCellConfigCommon_t *scc);
diff --git a/openair2/RRC/NR/nr_rrc_proto.h b/openair2/RRC/NR/nr_rrc_proto.h
index f1462fee341012b4b07aa2fe51f81dd908481446..006040bbb9417f842d6e028acd39bee8f9c958a6 100644
--- a/openair2/RRC/NR/nr_rrc_proto.h
+++ b/openair2/RRC/NR/nr_rrc_proto.h
@@ -82,12 +82,6 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco
                                      const gNB_RrcConfigurationReq *configuration,
                                      int uid);
 
-void config_csirs(NR_ServingCellConfigCommon_t *servingcellconfigcommon,
-                  NR_CSI_MeasConfig_t *csi_MeasConfig,
-                  int dl_antenna_ports,
-                  int curr_bwp,
-                  int do_csirs);
-
 void fill_default_reconfig(NR_ServingCellConfigCommon_t *servingcellconfigcommon,
                            NR_ServingCellConfig_t *servingcellconfigdedicated,
                            NR_RRCReconfiguration_IEs_t *reconfig,
diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c
index 3a8fc34e20b819092220232abba9cbd3d2e79e11..1715677c6df6fed74a2d1301af30157962984aaa 100755
--- a/openair2/RRC/NR/rrc_gNB.c
+++ b/openair2/RRC/NR/rrc_gNB.c
@@ -821,7 +821,6 @@ rrc_gNB_generate_dedicatedRRCReconfiguration(
   uint8_t                        buffer[RRC_BUF_SIZE];
   uint16_t                       size;
   int                            qos_flow_index = 0;
-  NR_QFI_t                       qfi = 0;
   int                            pdu_sessions_done = 0;
   int i;
   NR_CellGroupConfig_t *cellGroupConfig;
@@ -872,15 +871,21 @@ rrc_gNB_generate_dedicatedRRCReconfiguration(
     sdap_config = CALLOC(1, sizeof(NR_SDAP_Config_t));
     memset(sdap_config, 0, sizeof(NR_SDAP_Config_t));
     sdap_config->pdu_Session = ue_context_pP->ue_context.pduSession[i].param.pdusession_id;
-    sdap_config->sdap_HeaderDL = NR_SDAP_Config__sdap_HeaderDL_present;
-    sdap_config->sdap_HeaderUL = NR_SDAP_Config__sdap_HeaderUL_absent;
+    if (rrc->configuration.enable_sdap) {
+      sdap_config->sdap_HeaderDL = NR_SDAP_Config__sdap_HeaderDL_present;
+      sdap_config->sdap_HeaderUL = NR_SDAP_Config__sdap_HeaderUL_present;
+    } else {
+      sdap_config->sdap_HeaderDL = NR_SDAP_Config__sdap_HeaderDL_absent;
+      sdap_config->sdap_HeaderUL = NR_SDAP_Config__sdap_HeaderUL_absent;
+    }
     sdap_config->defaultDRB = TRUE;
     sdap_config->mappedQoS_FlowsToAdd = calloc(1, sizeof(struct NR_SDAP_Config__mappedQoS_FlowsToAdd));
     memset(sdap_config->mappedQoS_FlowsToAdd, 0, sizeof(struct NR_SDAP_Config__mappedQoS_FlowsToAdd));
 
     for (qos_flow_index = 0; qos_flow_index < ue_context_pP->ue_context.pduSession[i].param.nb_qos; qos_flow_index++) {
-      qfi = ue_context_pP->ue_context.pduSession[i].param.qos[qos_flow_index].qfi;
-      ASN_SEQUENCE_ADD(&sdap_config->mappedQoS_FlowsToAdd->list, &qfi);
+      NR_QFI_t *qfi = calloc(1, sizeof(NR_QFI_t));
+      *qfi = ue_context_pP->ue_context.pduSession[i].param.qos[qos_flow_index].qfi;
+      ASN_SEQUENCE_ADD(&sdap_config->mappedQoS_FlowsToAdd->list, qfi);
     }
     sdap_config->mappedQoS_FlowsToRelease = NULL;
     DRB_config->cnAssociation->choice.sdap_Config = sdap_config;
diff --git a/openair2/RRC/NR/rrc_gNB_NGAP.c b/openair2/RRC/NR/rrc_gNB_NGAP.c
index 4492380d7f86460d3b7827670b646fdb1e3b70cf..c73c3d9649df3bdd81b2eda5e497db748662adb7 100644
--- a/openair2/RRC/NR/rrc_gNB_NGAP.c
+++ b/openair2/RRC/NR/rrc_gNB_NGAP.c
@@ -969,9 +969,9 @@ rrc_gNB_process_NGAP_PDUSESSION_SETUP_REQ(
   uint16_t                        ue_initial_id;
   uint32_t                        gNB_ue_ngap_id;
   rrc_gNB_ue_context_t            *ue_context_p = NULL;
-  protocol_ctxt_t                 ctxt;
-  gtpv1u_gnb_create_tunnel_req_t  create_tunnel_req;
-  gtpv1u_gnb_create_tunnel_resp_t create_tunnel_resp;
+  protocol_ctxt_t                 ctxt={0};
+  gtpv1u_gnb_create_tunnel_req_t  create_tunnel_req={0};
+  gtpv1u_gnb_create_tunnel_resp_t create_tunnel_resp={0};
   uint8_t                         pdu_sessions_done;
   uint8_t                         inde_list[NR_NB_RB_MAX - 3]= {0};
   int                             ret = 0;
diff --git a/openair2/RRC/NR/rrc_gNB_reconfig.c b/openair2/RRC/NR/rrc_gNB_reconfig.c
index a112afbb960ca16b8a914a647fb0a44e4566046b..4e9245cf46126fd7eb2576176cec0fb4e87c2c81 100644
--- a/openair2/RRC/NR/rrc_gNB_reconfig.c
+++ b/openair2/RRC/NR/rrc_gNB_reconfig.c
@@ -223,7 +223,7 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco
  secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->phaseTrackingRS=NULL;
 
  secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_AdditionalPosition = calloc(1,sizeof(*secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_AdditionalPosition));
- *secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_AdditionalPosition = NR_DMRS_DownlinkConfig__dmrs_AdditionalPosition_pos0;
+ *secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_AdditionalPosition = NR_DMRS_DownlinkConfig__dmrs_AdditionalPosition_pos1;
 
 
  secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->tci_StatesToAddModList=calloc(1,sizeof(*secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->tci_StatesToAddModList));
@@ -572,7 +572,7 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco
    bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->phaseTrackingRS=NULL;
  }
  bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_AdditionalPosition = calloc(1,sizeof(*bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_AdditionalPosition));
- *bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_AdditionalPosition = NR_DMRS_DownlinkConfig__dmrs_AdditionalPosition_pos0;
+ *bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_AdditionalPosition = NR_DMRS_DownlinkConfig__dmrs_AdditionalPosition_pos1;
 
  bwp->bwp_Dedicated->pdsch_Config->choice.setup->tci_StatesToAddModList=calloc(1,sizeof(*bwp->bwp_Dedicated->pdsch_Config->choice.setup->tci_StatesToAddModList));
 
@@ -1066,24 +1066,7 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco
  csi_MeasConfig->csi_IM_ResourceToReleaseList = NULL;
  csi_MeasConfig->csi_IM_ResourceSetToReleaseList = NULL;
 
- if (do_csirs) {
-   csi_MeasConfig->nzp_CSI_RS_ResourceSetToAddModList  = calloc(1,sizeof(*csi_MeasConfig->nzp_CSI_RS_ResourceSetToAddModList));
-   NR_NZP_CSI_RS_ResourceSet_t *nzpcsirs0 = calloc(1,sizeof(*nzpcsirs0));
-   nzpcsirs0->nzp_CSI_ResourceSetId = 0;
-   NR_NZP_CSI_RS_ResourceId_t *nzpid0 = calloc(1,sizeof(*nzpid0));
-   *nzpid0 = 0;
-   ASN_SEQUENCE_ADD(&nzpcsirs0->nzp_CSI_RS_Resources,nzpid0);
-   nzpcsirs0->repetition = NULL;
-   nzpcsirs0->aperiodicTriggeringOffset = NULL;
-   nzpcsirs0->trs_Info = NULL;
-   ASN_SEQUENCE_ADD(&csi_MeasConfig->nzp_CSI_RS_ResourceSetToAddModList->list,nzpcsirs0);
- }
- else
-   csi_MeasConfig->nzp_CSI_RS_ResourceSetToAddModList  = NULL;
-
- csi_MeasConfig->nzp_CSI_RS_ResourceSetToReleaseList = NULL;
-
- config_csirs(servingcellconfigcommon, csi_MeasConfig,dl_antenna_ports,curr_bwp,do_csirs);
+ config_csirs(servingcellconfigcommon, csi_MeasConfig, uid, dl_antenna_ports, curr_bwp, do_csirs);
 
  csi_MeasConfig->csi_SSB_ResourceSetToAddModList = calloc(1,sizeof(*csi_MeasConfig->csi_SSB_ResourceSetToAddModList));
  csi_MeasConfig->csi_SSB_ResourceSetToReleaseList = NULL;
@@ -1102,9 +1085,9 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco
  ASN_SEQUENCE_ADD(&csi_MeasConfig->csi_SSB_ResourceSetToAddModList->list,ssbresset0);
 
  csi_MeasConfig->csi_ResourceConfigToAddModList = calloc(1,sizeof(*csi_MeasConfig->csi_ResourceConfigToAddModList));
+ csi_MeasConfig->csi_ResourceConfigToReleaseList = NULL;
 
  if (do_csirs) {
-   csi_MeasConfig->csi_ResourceConfigToReleaseList = NULL;
    NR_CSI_ResourceConfig_t *csires0 = calloc(1,sizeof(*csires0));
    csires0->csi_ResourceConfigId=0;
    csires0->csi_RS_ResourceSetList.present = NR_CSI_ResourceConfig__csi_RS_ResourceSetList_PR_nzp_CSI_RS_SSB;
@@ -1315,62 +1298,6 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco
 }
 
 
-void config_csirs(NR_ServingCellConfigCommon_t *servingcellconfigcommon,
-                  NR_CSI_MeasConfig_t *csi_MeasConfig,
-                  int dl_antenna_ports,
-                  int curr_bwp,
-                  int do_csirs) {
-
- if (do_csirs) {
-   csi_MeasConfig->nzp_CSI_RS_ResourceToAddModList = calloc(1,sizeof(*csi_MeasConfig->nzp_CSI_RS_ResourceToAddModList));
-   NR_NZP_CSI_RS_Resource_t *nzpcsi0 = calloc(1,sizeof(*nzpcsi0));
-   nzpcsi0->nzp_CSI_RS_ResourceId = 0;
-   NR_CSI_RS_ResourceMapping_t resourceMapping;
-   switch (dl_antenna_ports) {
-     case 1:
-       resourceMapping.frequencyDomainAllocation.present = NR_CSI_RS_ResourceMapping__frequencyDomainAllocation_PR_row2;
-       resourceMapping.frequencyDomainAllocation.choice.row2.buf = calloc(2, sizeof(uint8_t));
-       resourceMapping.frequencyDomainAllocation.choice.row2.size = 2;
-       resourceMapping.frequencyDomainAllocation.choice.row2.bits_unused = 4;
-       resourceMapping.frequencyDomainAllocation.choice.row2.buf[0] = 0;
-       resourceMapping.frequencyDomainAllocation.choice.row2.buf[1] = 16;
-       resourceMapping.nrofPorts = NR_CSI_RS_ResourceMapping__nrofPorts_p1;
-       resourceMapping.cdm_Type = NR_CSI_RS_ResourceMapping__cdm_Type_noCDM;
-       break;
-     case 2:
-       resourceMapping.frequencyDomainAllocation.present = NR_CSI_RS_ResourceMapping__frequencyDomainAllocation_PR_other;
-       resourceMapping.frequencyDomainAllocation.choice.other.buf = calloc(2, sizeof(uint8_t));
-       resourceMapping.frequencyDomainAllocation.choice.other.size = 1;
-       resourceMapping.frequencyDomainAllocation.choice.other.bits_unused = 2;
-       resourceMapping.frequencyDomainAllocation.choice.other.buf[0] = 4;
-       resourceMapping.nrofPorts = NR_CSI_RS_ResourceMapping__nrofPorts_p2;
-       resourceMapping.cdm_Type = NR_CSI_RS_ResourceMapping__cdm_Type_fd_CDM2;
-       break;
-     default:
-       AssertFatal(1==0,"Number of ports not yet supported\n");
-   }
-   resourceMapping.firstOFDMSymbolInTimeDomain = 6;
-   resourceMapping.firstOFDMSymbolInTimeDomain2 = NULL;
-   resourceMapping.density.present = NR_CSI_RS_ResourceMapping__density_PR_one;
-   resourceMapping.density.choice.one = (NULL_t)0;
-   resourceMapping.freqBand.startingRB = 0;
-   resourceMapping.freqBand.nrofRBs = ((curr_bwp>>2)+(curr_bwp%4>0))<<2;
-   nzpcsi0->resourceMapping = resourceMapping;
-   nzpcsi0->powerControlOffset = 0;
-   nzpcsi0->powerControlOffsetSS=calloc(1,sizeof(*nzpcsi0->powerControlOffsetSS));
-   *nzpcsi0->powerControlOffsetSS = NR_NZP_CSI_RS_Resource__powerControlOffsetSS_db0;
-   nzpcsi0->scramblingID = *servingcellconfigcommon->physCellId;
-   nzpcsi0->periodicityAndOffset = calloc(1,sizeof(*nzpcsi0->periodicityAndOffset));
-   nzpcsi0->periodicityAndOffset->present = NR_CSI_ResourcePeriodicityAndOffset_PR_slots320;
-   nzpcsi0->periodicityAndOffset->choice.slots320 = 0;
-   nzpcsi0->qcl_InfoPeriodicCSI_RS = NULL;
-   ASN_SEQUENCE_ADD(&csi_MeasConfig->nzp_CSI_RS_ResourceToAddModList->list,nzpcsi0);
- }
- else
-   csi_MeasConfig->nzp_CSI_RS_ResourceToAddModList = NULL;
-}
-
-
 void fill_default_reconfig(NR_ServingCellConfigCommon_t *servingcellconfigcommon,
                            NR_ServingCellConfig_t *servingcellconfigdedicated,
                            NR_RRCReconfiguration_IEs_t *reconfig,
diff --git a/openair2/RRC/NR_UE/rrc_UE.c b/openair2/RRC/NR_UE/rrc_UE.c
index fa1690e450cb060f884363b2be539eacadd15790..6a678d0e183700d84b444eecde4eacadaa18849f 100644
--- a/openair2/RRC/NR_UE/rrc_UE.c
+++ b/openair2/RRC/NR_UE/rrc_UE.c
@@ -2795,7 +2795,6 @@ void start_oai_nrue_threads()
     init_queue(&nr_tx_req_queue);
     init_queue(&nr_ul_dci_req_queue);
     init_queue(&nr_ul_tti_req_queue);
-    init_queue(&nr_wait_ul_tti_req_queue);
 
     if (sem_init(&sfn_slot_semaphore, 0, 0) != 0)
     {
diff --git a/openair2/RRC/NR_UE/rrc_proto.h b/openair2/RRC/NR_UE/rrc_proto.h
index 62d9167251300a064289082f07ddb7a6e6ed5fe5..510fbff230ebec811f9dd9a5c6b0c7ea5fe1454e 100644
--- a/openair2/RRC/NR_UE/rrc_proto.h
+++ b/openair2/RRC/NR_UE/rrc_proto.h
@@ -51,7 +51,6 @@ extern queue_t nr_dl_tti_req_queue;
 extern queue_t nr_tx_req_queue;
 extern queue_t nr_ul_dci_req_queue;
 extern queue_t nr_ul_tti_req_queue;
-extern queue_t nr_wait_ul_tti_req_queue;
 //
 //  main_rrc.c
 //
diff --git a/openair2/SDAP/nr_sdap/nr_sdap.c b/openair2/SDAP/nr_sdap/nr_sdap.c
new file mode 100644
index 0000000000000000000000000000000000000000..74ef93aff743fa9929e9c0d3aa2227dc5c45ec5b
--- /dev/null
+++ b/openair2/SDAP/nr_sdap/nr_sdap.c
@@ -0,0 +1,86 @@
+/*
+ * 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 "nr_sdap.h"
+
+boolean_t sdap_data_req(protocol_ctxt_t *ctxt_p,
+                        const srb_flag_t srb_flag,
+                        const rb_id_t rb_id,
+                        const mui_t mui,
+                        const confirm_t confirm,
+                        const sdu_size_t sdu_buffer_size,
+                        unsigned char *const sdu_buffer,
+                        const pdcp_transmission_mode_t pt_mode,
+                        const uint32_t *sourceL2Id,
+                        const uint32_t *destinationL2Id,
+                        const uint8_t qfi,
+                        const boolean_t rqi,
+                        const int pdusession_id) {
+  nr_sdap_entity_t *sdap_entity;
+  sdap_entity = nr_sdap_get_entity(ctxt_p->rnti, pdusession_id);
+
+  if(sdap_entity == NULL) {
+    LOG_E(SDAP, "%s:%d:%s: Entity not found with ue rnti: %x and pdusession id: %d\n", __FILE__, __LINE__, __FUNCTION__, ctxt_p->rnti, pdusession_id);
+    return 0;
+  }
+
+  boolean_t ret = sdap_entity->tx_entity(sdap_entity,
+                                         ctxt_p,
+                                         srb_flag,
+                                         rb_id,
+                                         mui,
+                                         confirm,
+                                         sdu_buffer_size,
+                                         sdu_buffer,
+                                         pt_mode,
+                                         sourceL2Id,
+                                         destinationL2Id,
+                                         qfi,
+                                         rqi);
+  return ret;
+}
+
+void sdap_data_ind(rb_id_t pdcp_entity,
+                   int is_gnb,
+                   int has_sdap,
+                   int has_sdapULheader,
+                   int pdusession_id,
+                   int rnti,
+                   char *buf,
+                   int size) {
+  nr_sdap_entity_t *sdap_entity;
+  sdap_entity = nr_sdap_get_entity(rnti, pdusession_id);
+
+  if(sdap_entity == NULL) {
+    LOG_E(SDAP, "%s:%d:%s: Entity not found\n", __FILE__, __LINE__, __FUNCTION__);
+    return;
+  }
+
+  sdap_entity->rx_entity(sdap_entity,
+                         pdcp_entity,
+                         is_gnb,
+                         has_sdap,
+                         has_sdapULheader,
+                         pdusession_id,
+                         rnti,
+                         buf,
+                         size);
+}
diff --git a/openair2/SDAP/nr_sdap/nr_sdap.h b/openair2/SDAP/nr_sdap/nr_sdap.h
new file mode 100644
index 0000000000000000000000000000000000000000..cd702cfd7f39d2b6698842b3fa1b643458ba0710
--- /dev/null
+++ b/openair2/SDAP/nr_sdap/nr_sdap.h
@@ -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
+ */
+
+#ifndef _NR_SDAP_GNB_H_
+#define _NR_SDAP_GNB_H_
+
+#include "openair2/COMMON/platform_types.h"
+#include "common/utils/LOG/log.h"
+#include "nr_sdap_entity.h"
+
+/*
+ * TS 37.324 4.4 Functions
+ * Transfer of user plane data
+ * Downlink - gNB
+ * Uplink   - nrUE
+ */
+boolean_t sdap_data_req(protocol_ctxt_t *ctxt_p,
+                        const srb_flag_t srb_flag,
+                        const rb_id_t rb_id,
+                        const mui_t mui,
+                        const confirm_t confirm,
+                        const sdu_size_t sdu_buffer_size,
+                        unsigned char *const sdu_buffer,
+                        const pdcp_transmission_mode_t pt_mode,
+                        const uint32_t *sourceL2Id,
+                        const uint32_t *destinationL2Id,
+                        const uint8_t qfi,
+                        const boolean_t rqi,
+                        const int pdusession_id
+                       );
+
+/*
+ * TS 37.324 4.4 Functions
+ * Transfer of user plane data
+ * Uplink   - gNB
+ * Downlink - nrUE
+ */
+void sdap_data_ind(rb_id_t pdcp_entity,
+                   int is_gnb,
+                   int has_sdap,
+                   int has_sdapULheader,
+                   int pdusession_id,
+                   int rnti,
+                   char *buf,
+                   int size
+                  );
+
+#endif
diff --git a/openair2/SDAP/nr_sdap/nr_sdap_entity.c b/openair2/SDAP/nr_sdap/nr_sdap_entity.c
new file mode 100644
index 0000000000000000000000000000000000000000..c5d1c1d6fe1dd1d630c464dd9e7fb2f79a491301
--- /dev/null
+++ b/openair2/SDAP/nr_sdap/nr_sdap_entity.c
@@ -0,0 +1,481 @@
+/*
+ * 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 "nr_sdap_entity.h"
+#include "common/utils/LOG/log.h"
+#include <openair2/LAYER2/PDCP_v10.1.0/pdcp.h>
+#include <openair3/ocp-gtpu/gtp_itf.h>
+#include "openair2/LAYER2/nr_pdcp/nr_pdcp_ue_manager.h"
+
+#include <stdlib.h>
+#include <string.h>
+#include <pthread.h>
+
+typedef struct {
+  nr_sdap_entity_t *sdap_entity_llist;
+} nr_sdap_entity_info;
+
+static nr_sdap_entity_info sdap_info;
+
+nr_pdcp_ue_manager_t *nr_pdcp_sdap_get_ue_manager(void);
+
+void nr_pdcp_submit_sdap_ctrl_pdu(int rnti, rb_id_t sdap_ctrl_pdu_drb, nr_sdap_ul_hdr_t ctrl_pdu){
+  nr_pdcp_ue_t *ue;
+  nr_pdcp_ue_manager_t *nr_pdcp_ue_manager;
+  nr_pdcp_ue_manager = nr_pdcp_sdap_get_ue_manager();
+  ue = nr_pdcp_manager_get_ue(nr_pdcp_ue_manager, rnti);
+  ue->drb[sdap_ctrl_pdu_drb-1]->recv_sdu(ue->drb[sdap_ctrl_pdu_drb-1], (char*)&ctrl_pdu, SDAP_HDR_LENGTH, RLC_MUI_UNDEFINED);
+  return;
+}
+
+static boolean_t nr_sdap_tx_entity(nr_sdap_entity_t *entity,
+                                   protocol_ctxt_t *ctxt_p,
+                                   const srb_flag_t srb_flag,
+                                   const rb_id_t rb_id,
+                                   const mui_t mui,
+                                   const confirm_t confirm,
+                                   const sdu_size_t sdu_buffer_size,
+                                   unsigned char *const sdu_buffer,
+                                   const pdcp_transmission_mode_t pt_mode,
+                                   const uint32_t *sourceL2Id,
+                                   const uint32_t *destinationL2Id,
+                                   const uint8_t qfi,
+                                   const boolean_t rqi
+                                  ) {
+  /* The offset of the SDAP header, it might be 0 if the has_sdap is not true in the pdcp entity. */
+  int offset=0;
+  boolean_t ret=false;
+  /*Hardcode DRB ID given from upper layer (ue/enb_tun_read_thread rb_id), it will change if we have SDAP*/
+  rb_id_t sdap_drb_id = rb_id;
+  int pdcp_ent_has_sdap = 0;
+
+  if(sdu_buffer == NULL) {
+    LOG_E(SDAP, "%s:%d:%s: NULL sdu_buffer \n", __FILE__, __LINE__, __FUNCTION__);
+    exit(1);
+  }
+
+  uint8_t sdap_buf[SDAP_MAX_PDU];
+  rb_id_t pdcp_entity = entity->qfi2drb_map(entity, qfi, rb_id);
+
+  if(pdcp_entity){
+    sdap_drb_id = pdcp_entity;
+    pdcp_ent_has_sdap = entity->qfi2drb_table[qfi].hasSdap;
+  }
+
+  if(!pdcp_ent_has_sdap){
+    ret = pdcp_data_req(ctxt_p,
+                        srb_flag,
+                        sdap_drb_id,
+                        mui,
+                        confirm,
+                        sdu_buffer_size,
+                        sdu_buffer,
+                        pt_mode,
+                        sourceL2Id,
+                        destinationL2Id);
+
+    if(!ret)
+      LOG_E(SDAP, "%s:%d:%s: PDCP refused PDU\n", __FILE__, __LINE__, __FUNCTION__);
+
+    return ret;
+  }
+
+  if(sdu_buffer_size == 0 || sdu_buffer_size > 8999) {
+    LOG_E(SDAP, "%s:%d:%s: NULL or 0 or exceeded sdu_buffer_size (over max PDCP SDU)\n", __FILE__, __LINE__, __FUNCTION__);
+    return 0;
+  }
+
+  if(ctxt_p->enb_flag) { // gNB
+    offset = SDAP_HDR_LENGTH;
+    /*
+     * TS 37.324 4.4 Functions
+     * marking QoS flow ID in DL packets.
+     *
+     * Construct the DL SDAP data PDU.
+     */
+    nr_sdap_dl_hdr_t sdap_hdr;
+    sdap_hdr.QFI = qfi;
+    sdap_hdr.RQI = rqi;
+    sdap_hdr.RDI = 0; // SDAP Hardcoded Value
+    /* Add the SDAP DL Header to the buffer */
+    memcpy(&sdap_buf[0], &sdap_hdr, SDAP_HDR_LENGTH);
+    memcpy(&sdap_buf[SDAP_HDR_LENGTH], sdu_buffer, sdu_buffer_size);
+    LOG_D(SDAP, "TX Entity QFI: %u \n", sdap_hdr.QFI);
+    LOG_D(SDAP, "TX Entity RQI: %u \n", sdap_hdr.RQI);
+    LOG_D(SDAP, "TX Entity RDI: %u \n", sdap_hdr.RDI);
+  } else { // nrUE
+    offset = SDAP_HDR_LENGTH;
+    /*
+     * TS 37.324 4.4 Functions
+     * marking QoS flow ID in UL packets.
+     *
+     * 5.2.1 Uplink
+     * construct the UL SDAP data PDU as specified in the subclause 6.2.2.3.
+     */
+    nr_sdap_ul_hdr_t sdap_hdr;
+    sdap_hdr.QFI = qfi;
+    sdap_hdr.R = 0;
+    sdap_hdr.DC = rqi;
+    /* Add the SDAP UL Header to the buffer */
+    memcpy(&sdap_buf[0], &sdap_hdr, SDAP_HDR_LENGTH);
+    memcpy(&sdap_buf[SDAP_HDR_LENGTH], sdu_buffer, sdu_buffer_size);
+    LOG_D(SDAP, "TX Entity QFI: %u \n", sdap_hdr.QFI);
+    LOG_D(SDAP, "TX Entity R: %u \n", sdap_hdr.R);
+    LOG_D(SDAP, "TX Entity DC: %u \n", sdap_hdr.DC);
+  }
+
+  /*
+   * TS 37.324 5.2 Data transfer
+   * 5.2.1 Uplink UE side
+   * submit the constructed UL SDAP data PDU to the lower layers
+   *
+   * Downlink gNB side
+   */
+  ret = pdcp_data_req(ctxt_p,
+                      srb_flag,
+                      sdap_drb_id,
+                      mui,
+                      confirm,
+                      sdu_buffer_size+offset,
+                      sdap_buf,
+                      pt_mode,
+                      sourceL2Id,
+                      destinationL2Id);
+
+  if(!ret)
+    LOG_E(SDAP, "%s:%d:%s: PDCP refused PDU\n", __FILE__, __LINE__, __FUNCTION__);
+
+  return ret;
+}
+
+static void nr_sdap_rx_entity(nr_sdap_entity_t *entity,
+                              rb_id_t pdcp_entity,
+                              int is_gnb,
+                              int has_sdap,
+                              int has_sdapHeader,
+                              int pdusession_id,
+                              int rnti,
+                              char *buf,
+                              int size) {
+  /* The offset of the SDAP header, it might be 0 if the has_sdap is not true in the pdcp entity. */
+  int offset=0;
+
+  if(is_gnb) { // gNB
+    if(has_sdap && has_sdapHeader ) { // Handling the SDAP Header
+      offset = SDAP_HDR_LENGTH;
+      nr_sdap_ul_hdr_t *sdap_hdr = (nr_sdap_ul_hdr_t *)buf;
+      LOG_D(SDAP, "RX Entity Received QFI : %u\n", sdap_hdr->QFI);
+      LOG_D(SDAP, "RX Entity Received Reserved bit : %u\n", sdap_hdr->R);
+      LOG_D(SDAP, "RX Entity Received DC bit : %u\n", sdap_hdr->DC);
+
+      switch (sdap_hdr->DC) {
+        case SDAP_HDR_UL_DATA_PDU:
+          LOG_D(SDAP, "RX Entity Received SDAP Data PDU\n");
+          break;
+
+        case SDAP_HDR_UL_CTRL_PDU:
+          LOG_D(SDAP, "RX Entity Received SDAP Control PDU\n");
+          break;
+      }
+    }
+
+    // Pushing SDAP SDU to GTP-U Layer
+    MessageDef *message_p;
+    uint8_t *gtpu_buffer_p;
+    gtpu_buffer_p = itti_malloc(TASK_PDCP_ENB, TASK_GTPV1_U, size + GTPU_HEADER_OVERHEAD_MAX - offset);
+    AssertFatal(gtpu_buffer_p != NULL, "OUT OF MEMORY");
+    memcpy(&gtpu_buffer_p[GTPU_HEADER_OVERHEAD_MAX], buf+offset, size-offset);
+    message_p = itti_alloc_new_message(TASK_PDCP_ENB, 0 , GTPV1U_GNB_TUNNEL_DATA_REQ);
+    AssertFatal(message_p != NULL, "OUT OF MEMORY");
+    GTPV1U_GNB_TUNNEL_DATA_REQ(message_p).buffer = gtpu_buffer_p;
+    GTPV1U_GNB_TUNNEL_DATA_REQ(message_p).length              = size-offset;
+    GTPV1U_GNB_TUNNEL_DATA_REQ(message_p).offset              = GTPU_HEADER_OVERHEAD_MAX;
+    GTPV1U_GNB_TUNNEL_DATA_REQ(message_p).rnti                = rnti;
+    GTPV1U_GNB_TUNNEL_DATA_REQ(message_p).pdusession_id       = pdusession_id;
+    LOG_D(SDAP, "%s()  sending message to gtp size %d\n", __func__,  size-offset);
+    itti_send_msg_to_task(TASK_GTPV1_U, INSTANCE_DEFAULT, message_p);
+  } else { //nrUE
+    /*
+     * TS 37.324 5.2 Data transfer
+     * 5.2.2 Downlink
+     * if the DRB from which this SDAP data PDU is received is configured by RRC with the presence of SDAP header.
+     */
+    if(has_sdap && has_sdapHeader) { // Handling the SDAP Header
+      offset = SDAP_HDR_LENGTH;
+      /*
+       * TS 37.324 5.2 Data transfer
+       * 5.2.2 Downlink
+       * retrieve the SDAP SDU from the DL SDAP data PDU as specified in the subclause 6.2.2.2.
+       */
+      nr_sdap_dl_hdr_t *sdap_hdr = (nr_sdap_dl_hdr_t *)buf;
+      LOG_D(SDAP, "RX Entity Received QFI : %u\n", sdap_hdr->QFI);
+      LOG_D(SDAP, "RX Entity Received RQI : %u\n", sdap_hdr->RQI);
+      LOG_D(SDAP, "RX Entity Received RDI : %u\n", sdap_hdr->RDI);
+
+      /*
+       * TS 37.324 5.2 Data transfer
+       * 5.2.2 Downlink
+       * Perform reflective QoS flow to DRB mapping as specified in the subclause 5.3.2.
+       */
+      if(sdap_hdr->RDI == SDAP_REFLECTIVE_MAPPING) {
+        /*
+         * TS 37.324 5.3 QoS flow to DRB Mapping 
+         * 5.3.2 Reflective mapping
+         * If there is no stored QoS flow to DRB mapping rule for the QoS flow and a default DRB is configured.
+         */
+        if(!entity->qfi2drb_table[sdap_hdr->QFI].drb_id && entity->default_drb){
+          nr_sdap_ul_hdr_t sdap_ctrl_pdu = entity->sdap_construct_ctrl_pdu(sdap_hdr->QFI);
+          rb_id_t sdap_ctrl_pdu_drb = entity->sdap_map_ctrl_pdu(entity, pdcp_entity, SDAP_CTRL_PDU_MAP_DEF_DRB, sdap_hdr->QFI);
+          entity->sdap_submit_ctrl_pdu(rnti, sdap_ctrl_pdu_drb, sdap_ctrl_pdu);
+        }
+
+        /*
+         * TS 37.324 5.3 QoS flow to DRB mapping 
+         * 5.3.2 Reflective mapping
+         * if the stored QoS flow to DRB mapping rule for the QoS flow 
+         * is different from the QoS flow to DRB mapping of the DL SDAP data PDU
+         * and
+         * the DRB according to the stored QoS flow to DRB mapping rule is configured by RRC
+         * with the presence of UL SDAP header
+         */
+        if( (pdcp_entity != entity->qfi2drb_table[sdap_hdr->QFI].drb_id) && 
+             has_sdapHeader ){
+          nr_sdap_ul_hdr_t sdap_ctrl_pdu = entity->sdap_construct_ctrl_pdu(sdap_hdr->QFI);
+          rb_id_t sdap_ctrl_pdu_drb = entity->sdap_map_ctrl_pdu(entity, pdcp_entity, SDAP_CTRL_PDU_MAP_RULE_DRB, sdap_hdr->QFI);
+          entity->sdap_submit_ctrl_pdu(rnti, sdap_ctrl_pdu_drb, sdap_ctrl_pdu);
+        }
+
+        /*
+         * TS 37.324 5.3 QoS flow to DRB Mapping 
+         * 5.3.2 Reflective mapping
+         * store the QoS flow to DRB mapping of the DL SDAP data PDU as the QoS flow to DRB mapping rule for the UL. 
+         */ 
+        entity->qfi2drb_table[sdap_hdr->QFI].drb_id = pdcp_entity;
+      }
+
+      /*
+       * TS 37.324 5.2 Data transfer
+       * 5.2.2 Downlink
+       * perform RQI handling as specified in the subclause 5.4
+       */
+      if(sdap_hdr->RQI == SDAP_RQI_HANDLING) {
+        LOG_W(SDAP, "UE - TODD 5.4\n");
+      }
+    } /*  else - retrieve the SDAP SDU from the DL SDAP data PDU as specified in the subclause 6.2.2.1 */
+
+    /*
+     * TS 37.324 5.2 Data transfer
+     * 5.2.2 Downlink
+     * deliver the retrieved SDAP SDU to the upper layer.
+     */
+    extern int nas_sock_fd[];
+    int len = write(nas_sock_fd[0], &buf[offset], size-offset);
+    LOG_D(SDAP, "RX Entity len : %d\n", len);
+    LOG_D(SDAP, "RX Entity size : %d\n", size);
+    LOG_D(SDAP, "RX Entity offset : %d\n", offset);
+
+    if (len != size-offset)
+      LOG_E(SDAP, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__);
+  }
+}
+
+void nr_sdap_qfi2drb_map_update(nr_sdap_entity_t *entity, uint8_t qfi, rb_id_t drb, boolean_t hasSdap){
+  if(qfi < SDAP_MAX_QFI &&
+     qfi > SDAP_MAP_RULE_EMPTY &&
+     drb > 0 &&
+     drb <= AVLBL_DRB)
+  {
+    entity->qfi2drb_table[qfi].drb_id = drb;
+    entity->qfi2drb_table[qfi].hasSdap = hasSdap;
+    LOG_D(SDAP, "Updated QFI to DRB Map: QFI %u -> DRB %ld \n", qfi, entity->qfi2drb_table[qfi].drb_id);
+    LOG_D(SDAP, "DRB %ld %s\n", entity->qfi2drb_table[qfi].drb_id, hasSdap ? "has SDAP" : "does not have SDAP");
+  }
+}
+
+void nr_sdap_qfi2drb_map_del(nr_sdap_entity_t *entity, uint8_t qfi){
+  entity->qfi2drb_table[qfi].drb_id = SDAP_NO_MAPPING_RULE;
+  LOG_D(SDAP, "Deleted QFI to DRB Map for QFI %u \n", qfi);
+}
+
+rb_id_t nr_sdap_qfi2drb_map(nr_sdap_entity_t *entity, uint8_t qfi, rb_id_t upper_layer_rb_id){
+  rb_id_t pdcp_entity;
+
+  pdcp_entity = entity->qfi2drb_table[qfi].drb_id;
+
+  if(pdcp_entity){
+    return pdcp_entity;
+  } else if(entity->default_drb) {
+    LOG_D(SDAP, "Mapped QFI %u to Default DRB\n", qfi);
+    return entity->default_drb;
+  } else {
+    return SDAP_MAP_RULE_EMPTY;
+  }
+
+  return pdcp_entity;
+}
+
+nr_sdap_ul_hdr_t nr_sdap_construct_ctrl_pdu(uint8_t qfi){
+  nr_sdap_ul_hdr_t sdap_end_marker_hdr;
+  sdap_end_marker_hdr.QFI = qfi;
+  sdap_end_marker_hdr.R = 0;
+  sdap_end_marker_hdr.DC = SDAP_HDR_UL_CTRL_PDU;
+  LOG_D(SDAP, "Constructed Control PDU with QFI:%u R:%u DC:%u \n", sdap_end_marker_hdr.QFI,
+                                                                   sdap_end_marker_hdr.R,
+                                                                   sdap_end_marker_hdr.DC);
+  return sdap_end_marker_hdr;
+}
+
+rb_id_t nr_sdap_map_ctrl_pdu(nr_sdap_entity_t *entity, rb_id_t pdcp_entity, int map_type, uint8_t dl_qfi){
+  rb_id_t drb_of_endmarker = 0;
+  if(map_type == SDAP_CTRL_PDU_MAP_DEF_DRB){
+    drb_of_endmarker = entity->default_drb;
+    LOG_D(SDAP, "Mapped Control PDU to default drb\n");
+  }
+  if(map_type == SDAP_CTRL_PDU_MAP_RULE_DRB){
+    drb_of_endmarker = entity->qfi2drb_map(entity, dl_qfi, pdcp_entity);
+    LOG_D(SDAP, "Mapped Control PDU according to the mapping rule, qfi %u \n", dl_qfi);
+  }
+  return drb_of_endmarker;
+}
+
+void nr_sdap_submit_ctrl_pdu(int rnti, rb_id_t sdap_ctrl_pdu_drb, nr_sdap_ul_hdr_t ctrl_pdu){
+  if(sdap_ctrl_pdu_drb){
+    nr_pdcp_submit_sdap_ctrl_pdu(rnti, sdap_ctrl_pdu_drb, ctrl_pdu);
+    LOG_D(SDAP, "Sent Control PDU to PDCP Layer.\n");
+  }
+}
+
+void nr_sdap_ue_qfi2drb_config(nr_sdap_entity_t *existing_sdap_entity,
+                               rb_id_t pdcp_entity,
+                               uint16_t rnti,
+                               NR_QFI_t *mapped_qfi_2_add,
+                               uint8_t mappedQFIs2AddCount,
+                               uint8_t drb_identity)
+{
+  uint8_t qfi = 0;
+
+  for(int i = 0; i < mappedQFIs2AddCount; i++){
+    qfi = mapped_qfi_2_add[i];
+    if(existing_sdap_entity->default_drb && existing_sdap_entity->qfi2drb_table[qfi].drb_id == SDAP_NO_MAPPING_RULE){
+      nr_sdap_ul_hdr_t sdap_ctrl_pdu = existing_sdap_entity->sdap_construct_ctrl_pdu(qfi);
+      rb_id_t sdap_ctrl_pdu_drb = existing_sdap_entity->sdap_map_ctrl_pdu(existing_sdap_entity, pdcp_entity, SDAP_CTRL_PDU_MAP_DEF_DRB, qfi);
+      existing_sdap_entity->sdap_submit_ctrl_pdu(rnti, sdap_ctrl_pdu_drb, sdap_ctrl_pdu);
+    }
+    if(existing_sdap_entity->qfi2drb_table[qfi].drb_id != drb_identity && existing_sdap_entity->qfi2drb_table[qfi].hasSdap){
+      nr_sdap_ul_hdr_t sdap_ctrl_pdu = existing_sdap_entity->sdap_construct_ctrl_pdu(qfi);
+      rb_id_t sdap_ctrl_pdu_drb = existing_sdap_entity->sdap_map_ctrl_pdu(existing_sdap_entity, pdcp_entity, SDAP_CTRL_PDU_MAP_RULE_DRB, qfi);
+      existing_sdap_entity->sdap_submit_ctrl_pdu(rnti, sdap_ctrl_pdu_drb, sdap_ctrl_pdu);
+    }
+  }
+}
+
+nr_sdap_entity_t *new_nr_sdap_entity(int has_sdap,
+                                     uint16_t rnti,
+                                     int pdusession_id,
+                                     boolean_t is_defaultDRB,
+                                     uint8_t drb_identity,
+                                     NR_QFI_t *mapped_qfi_2_add,
+                                     uint8_t mappedQFIs2AddCount)
+{
+  if(nr_sdap_get_entity(rnti, pdusession_id)) {
+    LOG_E(SDAP, "SDAP Entity for UE already exists.\n");
+    nr_sdap_entity_t *existing_sdap_entity = nr_sdap_get_entity(rnti, pdusession_id);
+    rb_id_t pdcp_entity = existing_sdap_entity->default_drb;
+    nr_sdap_ue_qfi2drb_config(existing_sdap_entity, pdcp_entity, rnti, mapped_qfi_2_add, mappedQFIs2AddCount, drb_identity);
+    return existing_sdap_entity;
+  }
+
+  nr_sdap_entity_t *sdap_entity;
+  sdap_entity = calloc(1, sizeof(nr_sdap_entity_t));
+
+  if(sdap_entity == NULL) {
+    LOG_E(SDAP, "SDAP Entity creation failed, out of memory\n");
+    exit(1);
+  }
+
+  sdap_entity->rnti = rnti;
+  sdap_entity->pdusession_id = pdusession_id;
+
+  sdap_entity->tx_entity = nr_sdap_tx_entity;
+  sdap_entity->rx_entity = nr_sdap_rx_entity;
+
+  sdap_entity->sdap_construct_ctrl_pdu = nr_sdap_construct_ctrl_pdu;
+  sdap_entity->sdap_map_ctrl_pdu = nr_sdap_map_ctrl_pdu;
+  sdap_entity->sdap_submit_ctrl_pdu = nr_sdap_submit_ctrl_pdu;
+
+  sdap_entity->qfi2drb_map_update = nr_sdap_qfi2drb_map_update;
+  sdap_entity->qfi2drb_map_delete = nr_sdap_qfi2drb_map_del;
+  sdap_entity->qfi2drb_map = nr_sdap_qfi2drb_map;
+
+  if(is_defaultDRB) {
+    sdap_entity->default_drb = drb_identity;
+    LOG_I(SDAP, "Default DRB for the created SDAP entity: %ld \n", sdap_entity->default_drb);
+
+    if(mappedQFIs2AddCount) {
+      for (int i = 0; i < mappedQFIs2AddCount; i++)
+      {
+        LOG_D(SDAP, "Mapped QFI to Add : %ld \n", mapped_qfi_2_add[i]);
+        sdap_entity->qfi2drb_map_update(sdap_entity, mapped_qfi_2_add[i], sdap_entity->default_drb, has_sdap);
+      }
+    }
+  }
+
+  sdap_entity->next_entity = sdap_info.sdap_entity_llist;
+  sdap_info.sdap_entity_llist = sdap_entity;
+  return sdap_entity;
+}
+
+nr_sdap_entity_t *nr_sdap_get_entity(uint16_t rnti, int pdusession_id) {
+  nr_sdap_entity_t *sdap_entity;
+  sdap_entity = sdap_info.sdap_entity_llist;
+
+  if(sdap_entity == NULL)
+    return NULL;
+
+  while(sdap_entity->rnti != rnti && sdap_entity->next_entity != NULL) {
+    sdap_entity = sdap_entity->next_entity;
+  }
+
+  if (sdap_entity->rnti == rnti && sdap_entity->pdusession_id == pdusession_id)
+    return sdap_entity;
+
+  return NULL;
+}
+
+void delete_nr_sdap_entity(uint16_t rnti) {
+  nr_sdap_entity_t *entityPtr, *entityPrev = NULL;
+  entityPtr = sdap_info.sdap_entity_llist;
+
+  if(entityPtr->rnti == rnti) {
+    sdap_info.sdap_entity_llist = sdap_info.sdap_entity_llist->next_entity;
+    free(entityPtr);
+  } else {
+    while(entityPtr->rnti != rnti && entityPtr->next_entity != NULL) {
+      entityPrev = entityPtr;
+      entityPtr = entityPtr->next_entity;
+    }
+
+    if(entityPtr->rnti != rnti) {
+      entityPrev->next_entity = entityPtr->next_entity;
+      free(entityPtr);
+    }
+  }
+}
diff --git a/openair2/SDAP/nr_sdap/nr_sdap_entity.h b/openair2/SDAP/nr_sdap/nr_sdap_entity.h
new file mode 100644
index 0000000000000000000000000000000000000000..b46e5bf4e3462bef98b65b5e2e799b14dc7b6319
--- /dev/null
+++ b/openair2/SDAP/nr_sdap/nr_sdap_entity.h
@@ -0,0 +1,182 @@
+/*
+ * 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 _NR_SDAP_ENTITY_H_
+#define _NR_SDAP_ENTITY_H_
+
+#include <stdint.h>
+#include "openair2/COMMON/platform_types.h"
+#include "openair2/LAYER2/nr_pdcp/nr_pdcp_entity.h"
+#include "NR_RadioBearerConfig.h"
+
+#define SDAP_BITMASK_DC             (0x80)
+#define SDAP_BITMASK_R              (0x40)
+#define SDAP_BITMASK_QFI            (0x3F)
+#define SDAP_BITMASK_RQI            (0x40)
+#define SDAP_HDR_UL_DATA_PDU        (1)
+#define SDAP_HDR_UL_CTRL_PDU        (0)
+#define SDAP_HDR_LENGTH             (1)
+#define SDAP_MAX_QFI                (64)
+#define SDAP_MAP_RULE_EMPTY         (0)
+#define AVLBL_DRB                   (5)
+#define SDAP_NO_MAPPING_RULE        (0)
+#define SDAP_REFLECTIVE_MAPPING     (1)
+#define SDAP_RQI_HANDLING           (1)
+#define SDAP_CTRL_PDU_MAP_DEF_DRB   (0)
+#define SDAP_CTRL_PDU_MAP_RULE_DRB  (1)
+#define SDAP_MAX_PDU                (9000)
+
+/*
+ * The values of QoS Flow ID (QFI) and Reflective QoS Indication,
+ * are located in the PDU Session Container, which is conveyed by
+ * the GTP-U Extension Header. Inside the DL PDU SESSION INFORMATION frame.
+ * TS 38.415 Fig. 5.5.2.1-1
+ */
+typedef struct nr_sdap_dl_hdr_s {
+  uint8_t QFI:6;
+  uint8_t RQI:1;
+  uint8_t RDI:1;
+} __attribute__((packed)) nr_sdap_dl_hdr_t;
+
+typedef struct nr_sdap_ul_hdr_s {
+  uint8_t QFI:6;
+  uint8_t R:1;
+  uint8_t DC:1;
+} __attribute__((packed)) nr_sdap_ul_hdr_t;
+
+typedef struct qfi2drb_s {
+  rb_id_t drb_id;
+  boolean_t hasSdap;
+} qfi2drb_t;
+
+void nr_pdcp_submit_sdap_ctrl_pdu(int rnti, rb_id_t sdap_ctrl_pdu_drb, nr_sdap_ul_hdr_t ctrl_pdu);
+
+typedef struct nr_sdap_entity_s {
+  uint16_t rnti;
+  rb_id_t default_drb;
+  int pdusession_id;
+  qfi2drb_t qfi2drb_table[SDAP_MAX_QFI];
+
+  void (*qfi2drb_map_update)(struct nr_sdap_entity_s *entity, uint8_t qfi, rb_id_t drb, boolean_t hasSdap);
+  void (*qfi2drb_map_delete)(struct nr_sdap_entity_s *entity, uint8_t qfi);
+  rb_id_t (*qfi2drb_map)(struct nr_sdap_entity_s *entity, uint8_t qfi, rb_id_t upper_layer_rb_id);
+
+  nr_sdap_ul_hdr_t (*sdap_construct_ctrl_pdu)(uint8_t qfi);
+  rb_id_t (*sdap_map_ctrl_pdu)(struct nr_sdap_entity_s *entity, rb_id_t pdcp_entity, int map_type, uint8_t dl_qfi);
+  void (*sdap_submit_ctrl_pdu)(int rnti, rb_id_t sdap_ctrl_pdu_drb, nr_sdap_ul_hdr_t ctrl_pdu);
+
+
+  boolean_t (*tx_entity)(struct nr_sdap_entity_s *entity,
+                         protocol_ctxt_t *ctxt_p,
+                         const srb_flag_t srb_flag,
+                         const rb_id_t rb_id,
+                         const mui_t mui,
+                         const confirm_t confirm,
+                         const sdu_size_t sdu_buffer_size,
+                         unsigned char *const sdu_buffer,
+                         const pdcp_transmission_mode_t pt_mode,
+                         const uint32_t *sourceL2Id,
+                         const uint32_t *destinationL2Id,
+                         const uint8_t qfi,
+                         const boolean_t rqi
+                         );
+
+  void (*rx_entity)(struct nr_sdap_entity_s *entity,
+                    rb_id_t pdcp_entity,
+                    int is_gnb,
+                    int has_sdap,
+                    int has_sdapULheader,
+                    int pdusession_id,
+                    int rnti,
+                    char *buf,
+                    int size);
+
+  /* List of entities */
+  struct nr_sdap_entity_s *next_entity;
+} nr_sdap_entity_t;
+
+/* QFI to DRB Mapping Related Function */
+void nr_sdap_qfi2drb_map_update(nr_sdap_entity_t *entity, uint8_t qfi, rb_id_t drb, boolean_t hasSdap);
+
+/* QFI to DRB Mapping Related Function */
+void nr_sdap_qfi2drb_map_del(nr_sdap_entity_t *entity, uint8_t qfi);
+
+/*
+ * TS 37.324
+ * 4.4 Functions
+ * Mapping between a QoS flow and a DRB for both DL and UL.
+ *
+ * 5.2.1 Uplink
+ * If there is no stored QoS flow to DRB mapping rule for the QoS flow as specified in the subclause 5.3, map the SDAP SDU to the default DRB
+ * else, map the SDAP SDU to the DRB according to the stored QoS flow to DRB mapping rule.
+ */
+rb_id_t nr_sdap_qfi2drb_map(nr_sdap_entity_t *entity, uint8_t qfi, rb_id_t upper_layer_rb_id);
+
+/*
+ * TS 37.324 5.3 QoS flow to DRB Mapping 
+ * construct an end-marker control PDU, as specified in the subclause 6.2.3, for the QoS flow;
+ */
+nr_sdap_ul_hdr_t nr_sdap_construct_ctrl_pdu(uint8_t qfi);
+
+/*
+ * TS 37.324 5.3 QoS flow to DRB Mapping 
+ * map the end-marker control PDU to the
+ * 1.) default DRB or 
+ * 2.) DRB according to the stored QoS flow to DRB mapping rule
+ */
+rb_id_t nr_sdap_map_ctrl_pdu(nr_sdap_entity_t *entity, rb_id_t pdcp_entity, int map_type, uint8_t dl_qfi);
+
+/*
+ * TS 37.324 5.3 QoS flow to DRB Mapping 
+ * Submit the end-marker control PDU to the lower layer.
+ */
+void nr_sdap_submit_ctrl_pdu(int rnti, rb_id_t sdap_ctrl_pdu_drb, nr_sdap_ul_hdr_t ctrl_pdu);
+
+/*
+ * TS 37.324 5.3 QoS flow to DRB Mapping 
+ * 5.3.1 Configuration Procedures
+ */
+void nr_sdap_ue_qfi2drb_config(nr_sdap_entity_t *existing_sdap_entity, 
+                               rb_id_t pdcp_entity, 
+                               uint16_t rnti,
+                               NR_QFI_t *mapped_qfi_2_add, 
+                               uint8_t mappedQFIs2AddCount,
+                               uint8_t drb_identity);
+
+/*
+ * TS 37.324 4.4 5.1.1 SDAP entity establishment
+ * Establish an SDAP entity.
+ */
+nr_sdap_entity_t *new_nr_sdap_entity(int has_sdap,
+                                     uint16_t rnti,
+                                     int pdusession_id,
+                                     boolean_t is_defaultDRB,
+                                     uint8_t default_DRB,
+                                     NR_QFI_t *mapped_qfi_2_add,
+                                     uint8_t mappedQFIs2AddCount);
+
+/* Entity Handling Related Functions */
+nr_sdap_entity_t *nr_sdap_get_entity(uint16_t rnti, int pdusession_id);
+
+/* Entity Handling Related Functions */
+void delete_nr_sdap_entity(uint16_t rnti);
+
+#endif
diff --git a/openair2/SDAP/nr_sdap/nr_sdap_gnb.c b/openair2/SDAP/nr_sdap/nr_sdap_gnb.c
deleted file mode 100644
index 5f0a2640e960ddd6b660c21a4035cd64152b79a3..0000000000000000000000000000000000000000
--- a/openair2/SDAP/nr_sdap/nr_sdap_gnb.c
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * 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 "nr_sdap_gnb.h"
-#include <openair2/LAYER2/PDCP_v10.1.0/pdcp.h>
-
-boolean_t sdap_gnb_data_req(protocol_ctxt_t *ctxt_p,
-                            const srb_flag_t srb_flag,
-                            const rb_id_t rb_id,
-                            const mui_t mui,
-                            const confirm_t confirm,
-                            const sdu_size_t sdu_buffer_size,
-                            unsigned char *const sdu_buffer,
-                            const pdcp_transmission_mode_t pt_mode,
-                            const uint32_t *sourceL2Id,
-                            const uint32_t *destinationL2Id
-                           ) {
-  if(sdu_buffer == NULL) {
-    LOG_E(PDCP, "%s:%d:%s: SDAP Layer gNB - NULL sdu_buffer \n", __FILE__, __LINE__, __FUNCTION__);
-    exit(1);
-  }
-
-  if(sdu_buffer_size == 0) {
-    LOG_E(PDCP, "%s:%d:%s: SDAP Layer gNB - NULL or 0 sdu_buffer_size \n", __FILE__, __LINE__, __FUNCTION__);
-    exit(1);
-  }
-
-  uint8_t *sdap_buf = (uint8_t *)malloc(sdu_buffer_size+SDAP_HDR_LENGTH);
-  nr_sdap_dl_hdr_t sdap_hdr;
-  sdap_hdr.RDI = 0; // SDAP_Hardcoded -
-  sdap_hdr.RQI = 0; // SDAP_Hardcoded - Should get this info from DL_PDU_SESSION_INFORMATION
-  sdap_hdr.QFI = 1; // SDAP_Hardcoded - Should get this info from DL_PDU_SESSION_INFORMATION
-  memcpy(&sdap_buf[0], &sdap_hdr, 1);
-  memcpy(&sdap_buf[1], sdu_buffer, sdu_buffer_size);
-  rb_id_t sdap_drb_id = rb_id; // SDAP_Hardcoded - Should get this info from QFI to DRB mapping table
-  boolean_t ret = pdcp_data_req(ctxt_p,
-                                srb_flag,
-                                sdap_drb_id,
-                                mui,
-                                confirm,
-                                sdu_buffer_size+1,
-                                sdap_buf,
-                                pt_mode,
-                                sourceL2Id,
-                                destinationL2Id);
-
-  if(!ret) {
-    LOG_E(PDCP, "%s:%d:%s: SDAP Layer gNB - PDCP DL refused PDU\n", __FILE__, __LINE__, __FUNCTION__);
-    free(sdap_buf);
-    return 0;
-  }
-
-  free(sdap_buf);
-  return 1;
-}
-
-void sdap_gnb_ul_header_handler(char sdap_gnb_ul_hdr) {
-  nr_sdap_ul_hdr_t *sdap_hdr_ul = (nr_sdap_ul_hdr_t *)&sdap_gnb_ul_hdr;
-
-  switch (sdap_hdr_ul->DC) {
-    case SDAP_HDR_UL_DATA_PDU:
-      LOG_I(PDCP, "%s:%d:%s: SDAP Layer gNB - UL Received SDAP Data PDU\n", __FILE__, __LINE__, __FUNCTION__);
-      break;
-
-    case SDAP_HDR_UL_CTRL_PDU:
-      LOG_I(PDCP, "%s:%d:%s: SDAP Layer gNB - Received SDAP Control PDU\n", __FILE__, __LINE__, __FUNCTION__);
-      break;
-  }
-}
\ No newline at end of file
diff --git a/openair2/SDAP/nr_sdap/nr_sdap_gnb.h b/openair2/SDAP/nr_sdap/nr_sdap_gnb.h
deleted file mode 100644
index 243aa8901088d81039cfa8576883e49d6572e4c2..0000000000000000000000000000000000000000
--- a/openair2/SDAP/nr_sdap/nr_sdap_gnb.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * 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 _NR_SDAP_GNB_
-#define _NR_SDAP_GNB_
-
-#include "openair2/COMMON/platform_types.h"
-#include "common/utils/LOG/log.h"
-
-#define SDAP_BITMASK_DC         (0x80)
-#define SDAP_BITMASK_R          (0x40)
-#define SDAP_BITMASK_QFI        (0x3F)
-#define SDAP_HDR_UL_DATA_PDU    (1)
-#define SDAP_HDR_UL_CTRL_PDU    (0)
-#define SDAP_HDR_LENGTH         (1)
-
-typedef struct nr_sdap_dl_hdr_s {
-  uint8_t QFI:6;
-  uint8_t RQI:1;
-  uint8_t RDI:1;
-} __attribute__((packed)) nr_sdap_dl_hdr_t;
-
-typedef struct nr_sdap_ul_hdr_s {
-  uint8_t QFI:6;
-  uint8_t R:1;
-  uint8_t DC:1;
-} __attribute__((packed)) nr_sdap_ul_hdr_t;
-
-boolean_t sdap_gnb_data_req(protocol_ctxt_t *ctxt_p,
-                            const srb_flag_t srb_flag,
-                            const rb_id_t rb_id,
-                            const mui_t mui,
-                            const confirm_t confirm,
-                            const sdu_size_t sdu_buffer_size,
-                            unsigned char *const sdu_buffer,
-                            const pdcp_transmission_mode_t pt_mode,
-                            const uint32_t *sourceL2Id,
-                            const uint32_t *destinationL2Id
-                           );
-
-void sdap_gnb_ul_header_handler(char sdap_gnb_ul_hdr);
-
-#endif
\ No newline at end of file
diff --git a/openair2/SDAP/nr_sdap/sdap_gNB.c b/openair2/SDAP/nr_sdap/sdap_gNB.c
deleted file mode 100644
index ad84e4c273a63a01331453c738080b675467f23d..0000000000000000000000000000000000000000
--- a/openair2/SDAP/nr_sdap/sdap_gNB.c
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * 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 sdap_gNB.c
- * \brief sdap tasks for gNB
- * \author Konstantinos Alexandris <Konstantinos.Alexandris@eurecom.fr>, Cedric Roux <Cedric.Roux@eurecom.fr>, Navid Nikaein <Navid.Nikaein@eurecom.fr>
- * \date 2018
- * \version 1.0
- */
-#define SDAP_GNB
-#define SDAP_GNB_C
-
diff --git a/openair2/UTIL/OCG/OCG.h b/openair2/UTIL/OCG/OCG.h
index 58cc7184e7d05ef0f449f15aafa44a2b1ca9c7c4..452581bb1783cc03e3cf6ce768e1b4b440041566 100644
--- a/openair2/UTIL/OCG/OCG.h
+++ b/openair2/UTIL/OCG/OCG.h
@@ -700,7 +700,7 @@ typedef struct {
   unsigned int n_frames_flag; // if set, then let the emulation goes to infinity
   node_function_t node_function[MAX_NUM_CCs];
   node_timing_t node_timing[MAX_NUM_CCs];
-  unsigned char frame_type[MAX_NUM_CCs]; //! LTE frame type (TDD=1, FDD=0). \note this should be converted to \ref lte_frame_type_t (header file reorganization needed)
+  unsigned char frame_type[MAX_NUM_CCs]; //! LTE frame type (TDD=1, FDD=0). \note this should be converted to \ref frame_type_t (header file reorganization needed)
   char *frame_type_name[MAX_NUM_CCs];
   unsigned char tdd_config[MAX_NUM_CCs];
   unsigned char tdd_config_S[MAX_NUM_CCs];
diff --git a/openair2/X2AP/x2ap_eNB_defs.h b/openair2/X2AP/x2ap_eNB_defs.h
index 063302d03abf7fce76f4307a272ba2def99afc10..bd6092e0cba75f72171d8f118789a3f9638296a2 100644
--- a/openair2/X2AP/x2ap_eNB_defs.h
+++ b/openair2/X2AP/x2ap_eNB_defs.h
@@ -172,7 +172,7 @@ typedef struct x2ap_eNB_instance_s {
   int32_t                 uplink_frequency_offset[MAX_NUM_CCs];
   uint32_t                Nid_cell[MAX_NUM_CCs];
   int16_t                 N_RB_DL[MAX_NUM_CCs];
-  lte_frame_type_t        frame_type[MAX_NUM_CCs];
+  frame_type_t            frame_type[MAX_NUM_CCs];
   uint32_t                fdd_earfcn_DL[MAX_NUM_CCs];
   uint32_t                fdd_earfcn_UL[MAX_NUM_CCs];
   uint32_t                subframeAssignment[MAX_NUM_CCs];
diff --git a/openair3/M3AP/m3ap_MCE_defs.h b/openair3/M3AP/m3ap_MCE_defs.h
index 18ad70a408b50739aedae4fa13ffee03711b2238..4dcb2b4db021559ce3304996210ffabf96aa7a15 100644
--- a/openair3/M3AP/m3ap_MCE_defs.h
+++ b/openair3/M3AP/m3ap_MCE_defs.h
@@ -170,7 +170,7 @@ typedef struct m3ap_MCE_instance_s {
   int32_t                 uplink_frequency_offset[MAX_NUM_CCs];
   uint32_t                Nid_cell[MAX_NUM_CCs];
   int16_t                 N_RB_DL[MAX_NUM_CCs];
-  lte_frame_type_t        frame_type[MAX_NUM_CCs];
+  frame_type_t            frame_type[MAX_NUM_CCs];
   uint32_t                fdd_earfcn_DL[MAX_NUM_CCs];
   uint32_t                fdd_earfcn_UL[MAX_NUM_CCs];
   int                     num_cc;
diff --git a/openair3/M3AP/m3ap_MME_defs.h b/openair3/M3AP/m3ap_MME_defs.h
index 3b5725655de153cd605793838ce27aa9df2b31af..6608587cc3be76e79ba04b525a64c3a44e4cf331 100644
--- a/openair3/M3AP/m3ap_MME_defs.h
+++ b/openair3/M3AP/m3ap_MME_defs.h
@@ -170,7 +170,7 @@ typedef struct m3ap_MME_instance_s {
   int32_t                 uplink_frequency_offset[MAX_NUM_CCs];
   uint32_t                Nid_cell[MAX_NUM_CCs];
   int16_t                 N_RB_DL[MAX_NUM_CCs];
-  lte_frame_type_t        frame_type[MAX_NUM_CCs];
+  frame_type_t            frame_type[MAX_NUM_CCs];
   uint32_t                fdd_earfcn_DL[MAX_NUM_CCs];
   uint32_t                fdd_earfcn_UL[MAX_NUM_CCs];
   int                     num_cc;
diff --git a/openair3/NAS/NR_UE/nr_nas_msg_sim.c b/openair3/NAS/NR_UE/nr_nas_msg_sim.c
index 283f3b7311d123d13bd18a3c02222574f8a07b85..e151fec9b43f63fa9b8d8fcb3e04faba2112a206 100644
--- a/openair3/NAS/NR_UE/nr_nas_msg_sim.c
+++ b/openair3/NAS/NR_UE/nr_nas_msg_sim.c
@@ -428,7 +428,7 @@ void generateRegistrationRequest(as_nas_info_t *initialNasMsg, int Mod_id) {
   size += 10;
 
   // encode the message
-  initialNasMsg->data = (Byte_t *)malloc(size * sizeof(Byte_t));
+  initialNasMsg->data = malloc16_clear(size * sizeof(Byte_t));
   registration_request_buf = initialNasMsg->data;
 
   initialNasMsg->length = mm_msg_encode(mm_msg, (uint8_t*)(initialNasMsg->data), size);
diff --git a/openair3/ocp-gtpu/gtp_itf.cpp b/openair3/ocp-gtpu/gtp_itf.cpp
index cc41de3550bb701e3b04cf09733aab6fb96dc347..7b8ba308bfb41a979b97c5244dc9052befe74a05 100644
--- a/openair3/ocp-gtpu/gtp_itf.cpp
+++ b/openair3/ocp-gtpu/gtp_itf.cpp
@@ -17,9 +17,11 @@ extern "C" {
 #include <openair2/COMMON/gtpv1_u_messages_types.h>
 #include <openair3/ocp-gtpu/gtp_itf.h>
 #include <openair2/LAYER2/PDCP_v10.1.0/pdcp.h>
-#include "openair2/SDAP/nr_sdap/nr_sdap_gnb.h"
+#include "openair2/SDAP/nr_sdap/nr_sdap.h"
 //#include <openair1/PHY/phy_extern.h>
 
+static boolean_t is_gnb = false;
+
 #pragma pack(1)
 
 typedef struct Gtpv1uMsgHeader {
@@ -34,8 +36,35 @@ typedef struct Gtpv1uMsgHeader {
   teid_t teid;
 } __attribute__((packed)) Gtpv1uMsgHeaderT;
 
+typedef struct Gtpv1uMsgHeaderOptFields {
+  uint8_t seqNum1Oct;
+  uint8_t seqNum2Oct;
+  uint8_t NPDUNum;
+  uint8_t NextExtHeaderType;    
+} __attribute__((packed)) Gtpv1uMsgHeaderOptFieldsT;
+
+typedef struct PDUSessionContainer {
+  uint8_t spare:4;
+  uint8_t PDU_type:4;
+  uint8_t QFI:6;
+  uint8_t RQI:1;
+  uint8_t PPP:1;
+} __attribute__((packed)) PDUSessionContainerT;
+
+typedef struct Gtpv1uExtHeader {
+  uint8_t ExtHeaderLen;
+  PDUSessionContainerT pdusession_cntr;
+  //uint8_t NextExtHeaderType;
+}__attribute__((packed)) Gtpv1uExtHeaderT;
+
 #pragma pack()
 
+// TS 29.281, fig 5.2.1-3
+#define PDU_SESSION_CONTAINER       (0x85)
+// TS 29.281, 5.2.1
+#define EXT_HDR_LNTH_OCTET_UNITS    (4)
+#define NO_MORE_EXT_HDRS            (0)
+
 // TS 29.060, table 7.1 defines the possible message types
 // here are all the possible messages (3GPP R16)
 #define GTP_ECHO_REQ                                         (1)
@@ -65,6 +94,8 @@ typedef struct {
   rnti_t rnti;
   ebi_t incoming_rb_id;
   gtpCallback callBack;
+  gtpCallbackSDAP callBackSDAP;
+  int pdusession_id;
 } rntiData_t;
 
 class gtpEndPoint {
@@ -448,6 +479,10 @@ teid_t newGtpuCreateTunnel(instance_t instance, rnti_t rnti, int incoming_bearer
   inst->te2ue_mapping[incoming_teid].incoming_rb_id= incoming_bearer_id;
 
   inst->te2ue_mapping[incoming_teid].callBack=callBack;
+  
+  inst->te2ue_mapping[incoming_teid].callBackSDAP = sdap_data_req;
+
+  inst->te2ue_mapping[incoming_teid].pdusession_id = (uint8_t)outgoing_bearer_id;
 
   gtpv1u_bearer_t *tmp=&inst->ue2te_mapping[rnti].bearers[outgoing_bearer_id];
 
@@ -567,14 +602,14 @@ int gtpv1u_create_ngu_tunnel(  const instance_t instance,
         create_tunnel_req->num_tunnels,
         create_tunnel_req->outgoing_teid[0]);
   tcp_udp_port_t dstport=globGtp.instances[compatInst(instance)].get_dstport();
-
+  is_gnb = true;
   for (int i = 0; i < create_tunnel_req->num_tunnels; i++) {
     teid_t teid=newGtpuCreateTunnel(instance, create_tunnel_req->rnti,
                                     create_tunnel_req->incoming_rb_id[i],
                                     create_tunnel_req->pdusession_id[i],
                                     create_tunnel_req->outgoing_teid[i],
                                     create_tunnel_req->dst_addr[i], dstport,
-                                    sdap_gnb_data_req);
+                                    pdcp_data_req);
     create_tunnel_resp->status=0;
     create_tunnel_resp->rnti=create_tunnel_req->rnti;
     create_tunnel_resp->num_tunnels=create_tunnel_req->num_tunnels;
@@ -815,10 +850,28 @@ static int Gtpv1uHandleGpdu(int h,
     return GTPNOK;
   }
 
-  int offset=8;
-
-  if( msgHdr->E ||  msgHdr->S ||msgHdr->PN)
-    offset+=8;
+  int offset=sizeof(Gtpv1uMsgHeaderT);
+
+  uint8_t qfi = 0;
+  boolean_t rqi = FALSE;
+
+  if( msgHdr->E || msgHdr->S || msgHdr->PN){
+   Gtpv1uMsgHeaderOptFieldsT *msgHdrOpt = (Gtpv1uMsgHeaderOptFieldsT *)(msgBuf+offset);
+   offset+=sizeof(Gtpv1uMsgHeaderOptFieldsT);
+    if( msgHdr->E && msgHdrOpt->NextExtHeaderType == PDU_SESSION_CONTAINER){
+      Gtpv1uExtHeaderT *msgHdrExt = (Gtpv1uExtHeaderT *)(msgBuf+offset);
+      offset+=msgHdrExt->ExtHeaderLen*EXT_HDR_LNTH_OCTET_UNITS;
+      qfi = msgHdrExt->pdusession_cntr.QFI;
+      rqi = msgHdrExt->pdusession_cntr.RQI;
+
+      /* 
+       * Check if the next extension header type of GTP extension header is set to 0
+       * We can not put it in the struct Gtpv1uExtHeaderT because the length is dynamic.
+       */
+      if(*(msgBuf+offset-1) != NO_MORE_EXT_HDRS)
+        LOG_W(GTPU, "Warning -  Next extension header is not zero, handle it \n");
+    }
+  }
 
   // This context is not good for gtp
   // frame, ... has no meaning
@@ -843,17 +896,34 @@ static int Gtpv1uHandleGpdu(int h,
   const uint32_t destinationL2Id=0;
   pthread_mutex_unlock(&globGtp.gtp_lock);
 
-  if ( !tunnel->second.callBack(&ctxt,
-                                srb_flag,
-                                rb_id,
-                                mui,
-                                confirm,
-                                sdu_buffer_size,
-                                sdu_buffer,
-                                mode,
-                                &sourceL2Id,
-                                &destinationL2Id) )
-    LOG_E(GTPU,"[%d] down layer refused incoming packet\n", h);
+  if(is_gnb && qfi){
+    if ( !tunnel->second.callBackSDAP(&ctxt,
+                                      srb_flag,
+                                      rb_id,
+                                      mui,
+                                      confirm,
+                                      sdu_buffer_size,
+                                      sdu_buffer,
+                                      mode,
+                                      &sourceL2Id,
+                                      &destinationL2Id,
+                                      qfi,
+                                      rqi,
+                                      tunnel->second.pdusession_id) )
+      LOG_E(GTPU,"[%d] down layer refused incoming packet\n", h);
+  } else {
+    if ( !tunnel->second.callBack(&ctxt,
+                                  srb_flag,
+                                  rb_id,
+                                  mui,
+                                  confirm,
+                                  sdu_buffer_size,
+                                  sdu_buffer,
+                                  mode,
+                                  &sourceL2Id,
+                                  &destinationL2Id) )
+      LOG_E(GTPU,"[%d] down layer refused incoming packet\n", h);
+  }
 
   LOG_D(GTPU,"[%d] Received a %d bytes packet for: teid:%x\n", h,
         msgBufLen-offset,
diff --git a/openair3/ocp-gtpu/gtp_itf.h b/openair3/ocp-gtpu/gtp_itf.h
index ba6cf0f8bb98e3da99af0e7c4162c5fe2ffb731d..17882ebf1e7e0f04846782a2e0733c123a5def7f 100644
--- a/openair3/ocp-gtpu/gtp_itf.h
+++ b/openair3/ocp-gtpu/gtp_itf.h
@@ -20,6 +20,21 @@ typedef boolean_t (*gtpCallback)(
   const uint32_t *sourceL2Id,
   const uint32_t *destinationL2Id);
 
+typedef boolean_t (*gtpCallbackSDAP)(
+  protocol_ctxt_t  *ctxt_pP,
+  const srb_flag_t     srb_flagP,
+  const rb_id_t        rb_idP,
+  const mui_t          muiP,
+  const confirm_t      confirmP,
+  const sdu_size_t     sdu_buffer_sizeP,
+  unsigned char *const sdu_buffer_pP,
+  const pdcp_transmission_mode_t modeP,
+  const uint32_t *sourceL2Id,
+  const uint32_t *destinationL2Id,
+  const uint8_t   qfi,
+  const boolean_t rqi,
+  const int       pdusession_id);
+
 typedef struct openAddr_s {
   char originHost[HOST_NAME_MAX];
   char originService[HOST_NAME_MAX];
diff --git a/targets/ARCH/rfsimulator/apply_channelmod.c b/targets/ARCH/rfsimulator/apply_channelmod.c
index d7d3a68965717280276ec9d839ab6e576e98d390..4ff5321e4d973572ce25026fc908ad35e4c8fc5b 100644
--- a/targets/ARCH/rfsimulator/apply_channelmod.c
+++ b/targets/ARCH/rfsimulator/apply_channelmod.c
@@ -52,7 +52,8 @@
   either we regenerate the channel (call again random_channel(desc,0)), or we keep it over subframes
   legacy: we regenerate each sub frame in UL, and each frame only in DL
 */
-void rxAddInput( struct complex16 *input_sig, struct complex16 *after_channel_sig,
+void rxAddInput( const c16_t *input_sig,
+		 c16_t *after_channel_sig,
                  int rxAnt,
                  channel_desc_t *channelDesc,
                  int nbSamples,
@@ -73,7 +74,7 @@ void rxAddInput( struct complex16 *input_sig, struct complex16 *after_channel_si
   const int nbTx=channelDesc->nb_tx;
 
   for (int i=0; i<((int)nbSamples-dd); i++) {
-    struct complex16 *out_ptr=after_channel_sig+dd+i;
+    c16_t *out_ptr=after_channel_sig+dd+i;
     struct complexd rx_tmp= {0};
 
     for (int txAnt=0; txAnt < nbTx; txAnt++) {
@@ -87,7 +88,7 @@ void rxAddInput( struct complex16 *input_sig, struct complex16 *after_channel_si
         // but it is not very usefull
         // it would be better to split out each antenna in a separate flow
         // that will allow to mix ru antennas freely
-        struct complex16 tx16=input_sig[((TS+i-l)*nbTx+txAnt)%CirSize];
+        c16_t tx16=input_sig[((TS+i-l)*nbTx+txAnt)%CirSize];
         rx_tmp.r += tx16.r * channelModel[l].r - tx16.i * channelModel[l].i;
         rx_tmp.i += tx16.i * channelModel[l].r + tx16.r * channelModel[l].i;
       } //l
diff --git a/targets/ARCH/rfsimulator/rfsimulator.h b/targets/ARCH/rfsimulator/rfsimulator.h
index 292873032e010d7d1443f5e5424fe4c087962f39..e69d41fa6cea830df0f5d55ba2022c26ea70b988 100644
--- a/targets/ARCH/rfsimulator/rfsimulator.h
+++ b/targets/ARCH/rfsimulator/rfsimulator.h
@@ -25,8 +25,8 @@
 #define  __RFSIMULATOR_H
 double gaussZiggurat(double mean, double variance);
 void tableNor(unsigned long seed);
-void rxAddInput( struct complex16 *input_sig,
-                 struct complex16 *after_channel_sig,
+void rxAddInput( const c16_t *input_sig,
+                 c16_t *after_channel_sig,
                  int rxAnt,
                  channel_desc_t *channelDesc,
                  int nbSamples,
diff --git a/targets/ARCH/rfsimulator/simulator.c b/targets/ARCH/rfsimulator/simulator.c
index 24a0348d35d6857f13bdfda34dc0f175de3aab96..bc9882b4bd2342ffecb3e47dcd89888ea208f1e7 100644
--- a/targets/ARCH/rfsimulator/simulator.c
+++ b/targets/ARCH/rfsimulator/simulator.c
@@ -100,7 +100,7 @@ static telnetshell_vardef_t rfsimu_vardef[] = {
 };
 pthread_mutex_t Sockmutex;
 
-typedef struct complex16 sample_t; // 2*16 bits complex number
+typedef c16_t sample_t; // 2*16 bits complex number
 
 typedef struct buffer_s {
   int conn_sock;
@@ -117,7 +117,7 @@ typedef struct buffer_s {
 
 typedef struct {
   int listen_sock, epollfd;
-  openair0_timestamp nextTimestamp;
+  openair0_timestamp nextRxTstamp;
   openair0_timestamp lastWroteTS;
   uint64_t typeStamp;
   char *ip;
@@ -196,7 +196,7 @@ static void removeCirBuf(rfsimulator_state_t *bridge, int sock) {
   free(bridge->buf[sock].circularBuf);
   // Fixme: no free_channel_desc_scm(bridge->buf[sock].channel_model) implemented
   // a lot of mem leaks
-  free(bridge->buf[sock].channel_model);
+  //free(bridge->buf[sock].channel_model);
   memset(&bridge->buf[sock], 0, sizeof(buffer_t));
   bridge->buf[sock].conn_sock=-1;
 }
@@ -429,8 +429,6 @@ static int rfsimulator_write_internal(rfsimulator_state_t *t, openair0_timestamp
   if (!alreadyLocked)
     pthread_mutex_lock(&Sockmutex);
 
-  LOG_D(HW,"sending %d samples at time: %ld\n", nsamps, timestamp);
-
   for (int i=0; i<FD_SETSIZE; i++) {
     buffer_t *b=&t->buf[i];
 
@@ -495,7 +493,7 @@ static bool flushInput(rfsimulator_state_t *t, int timeout, int nsamps_for_initi
       setblocking(conn_sock, notBlocking);
       allocCirBuf(t, conn_sock);
       LOG_I(HW,"A client connected, sending the current time\n");
-      struct complex16 v= {0};
+      c16_t v= {0};
       void *samplesVoid[t->tx_num_channels];
 
       for ( int i=0; i < t->tx_num_channels; i++)
@@ -549,14 +547,14 @@ static bool flushInput(rfsimulator_state_t *t, int timeout, int nsamps_for_initi
                      (t->typeStamp == ENB_MAGICDL && b->th.magic==UE_MAGICDL), "Socket Error in protocol");
         b->headerMode=false;
 
-        if ( t->nextTimestamp == 0 ) { // First block in UE, resync with the eNB current TS
-          t->nextTimestamp=b->th.timestamp> nsamps_for_initial ?
+        if ( t->nextRxTstamp == 0 ) { // First block in UE, resync with the eNB current TS
+          t->nextRxTstamp=b->th.timestamp> nsamps_for_initial ?
                            b->th.timestamp -  nsamps_for_initial :
                            0;
           b->lastReceivedTS=b->th.timestamp> nsamps_for_initial ?
                             b->th.timestamp :
                             nsamps_for_initial;
-          LOG_W(HW,"UE got first timestamp: starting at %lu\n",  t->nextTimestamp);
+          LOG_W(HW,"UE got first timestamp: starting at %lu\n",  t->nextRxTstamp);
           b->trashingPacket=true;
         } else if ( b->lastReceivedTS < b->th.timestamp) {
           int nbAnt= b->th.nbAnt;
@@ -623,7 +621,7 @@ static int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimest
   }
 
   rfsimulator_state_t *t = device->priv;
-  LOG_D(HW, "Enter rfsimulator_read, expect %d samples, will release at TS: %ld\n", nsamps, t->nextTimestamp+nsamps);
+  LOG_D(HW, "Enter rfsimulator_read, expect %d samples, will release at TS: %ld\n", nsamps, t->nextRxTstamp+nsamps);
   // deliver data from received data
   // check if a UE is connected
   int first_sock;
@@ -634,54 +632,22 @@ static int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimest
 
   if ( first_sock ==  FD_SETSIZE ) {
     // no connected device (we are eNB, no UE is connected)
-    if ( t->nextTimestamp == 0)
+    if ( t->nextRxTstamp == 0)
       LOG_W(HW,"No connected device, generating void samples...\n");
 
     if (!flushInput(t, 10,  nsamps)) {
       for (int x=0; x < nbAnt; x++)
         memset(samplesVoid[x],0,sampleToByte(nsamps,1));
 
-      t->nextTimestamp+=nsamps;
+      t->nextRxTstamp+=nsamps;
 
-      if ( ((t->nextTimestamp/nsamps)%100) == 0)
-        LOG_D(HW,"No UE, Generated void samples for Rx: %ld\n", t->nextTimestamp);
+      if ( ((t->nextRxTstamp/nsamps)%100) == 0)
+        LOG_D(HW,"No UE, Generated void samples for Rx: %ld\n", t->nextRxTstamp);
 
-      *ptimestamp = t->nextTimestamp-nsamps;
+      *ptimestamp = t->nextRxTstamp-nsamps;
       return nsamps;
     }
   } else {
-    pthread_mutex_lock(&Sockmutex);
-
-    if ( t->nextTimestamp > 0 && t->lastWroteTS < t->nextTimestamp) {
-      pthread_mutex_unlock(&Sockmutex);
-      usleep(10000);
-      pthread_mutex_lock(&Sockmutex);
-
-      if ( t->lastWroteTS < t->nextTimestamp ) {
-        // Assuming Tx is not done fully in another thread
-        // We can never write is the past from the received time
-        // So, the node perform receive but will never write these symbols
-        // let's tell this to the opposite node
-        // We send timestamp for nb samples required
-        // assuming this should have been done earlier if a Tx would exist
-        pthread_mutex_unlock(&Sockmutex);
-        struct complex16 v= {0};
-        void *dummyS[t->tx_num_channels];
-
-        for ( int i=0; i < t->tx_num_channels; i++)
-          dummyS[i]=(void *)&v;
-
-        LOG_I(HW, "No samples Tx occured, so we send 1 sample to notify it: Tx:%lu, Rx:%lu\n",
-              t->lastWroteTS, t->nextTimestamp);
-        rfsimulator_write_internal(t, t->nextTimestamp,
-                                   dummyS, 1,
-                                   t->tx_num_channels, 1, true);
-      } else {
-        pthread_mutex_unlock(&Sockmutex);
-        LOG_W(HW, "trx_write came from another thread\n");
-      }
-    } else
-      pthread_mutex_unlock(&Sockmutex);
 
     bool have_to_wait;
 
@@ -692,7 +658,7 @@ static int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimest
         buffer_t *b=&t->buf[sock];
 
         if ( b->circularBuf )
-          if ( t->nextTimestamp+nsamps > b->lastReceivedTS ) {
+          if ( t->nextRxTstamp+nsamps > b->lastReceivedTS ) {
             have_to_wait=true;
             break;
           }
@@ -701,7 +667,7 @@ static int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimest
       if (have_to_wait)
         /*printf("Waiting on socket, current last ts: %ld, expected at least : %ld\n",
           ptr->lastReceivedTS,
-          t->nextTimestamp+nsamps);
+          t->nextRxTstamp+nsamps);
         */
         flushInput(t, 3, nsamps);
     } while (have_to_wait);
@@ -728,11 +694,11 @@ static int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimest
 
       for (int a=0; a<nbAnt; a++) {//loop over number of Rx antennas
         if ( ptr->channel_model != NULL ) // apply a channel model
-          rxAddInput( ptr->circularBuf, (struct complex16 *) samplesVoid[a],
+          rxAddInput( ptr->circularBuf, (c16_t *) samplesVoid[a],
                       a,
                       ptr->channel_model,
                       nsamps,
-                      t->nextTimestamp,
+                      t->nextRxTstamp,
                       CirSize
                     );
         else { // no channel modeling
@@ -747,8 +713,8 @@ static int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimest
           //LOG_I(HW, "nbAnt_tx %d\n",nbAnt_tx);
           for (int i=0; i < nsamps; i++) {//loop over nsamps
             for (int a_tx=0; a_tx<nbAnt_tx; a_tx++) { //sum up signals from nbAnt_tx antennas
-              out[i].r += (short)(ptr->circularBuf[((t->nextTimestamp+i)*nbAnt_tx+a_tx)%CirSize].r*H_awgn_mimo[a][a_tx]);
-              out[i].i += (short)(ptr->circularBuf[((t->nextTimestamp+i)*nbAnt_tx+a_tx)%CirSize].i*H_awgn_mimo[a][a_tx]);
+              out[i].r += (short)(ptr->circularBuf[((t->nextRxTstamp+i)*nbAnt_tx+a_tx)%CirSize].r*H_awgn_mimo[a][a_tx]);
+              out[i].i += (short)(ptr->circularBuf[((t->nextRxTstamp+i)*nbAnt_tx+a_tx)%CirSize].i*H_awgn_mimo[a][a_tx]);
             } // end for a_tx
           } // end for i (number of samps)
         } // end of no channel modeling
@@ -756,11 +722,11 @@ static int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimest
     }
   }
 
-  *ptimestamp = t->nextTimestamp; // return the time of the first sample
-  t->nextTimestamp+=nsamps;
+  *ptimestamp = t->nextRxTstamp; // return the time of the first sample
+  t->nextRxTstamp+=nsamps;
   LOG_D(HW,"Rx to upper layer: %d from %ld to %ld, energy in first antenna %d\n",
         nsamps,
-        *ptimestamp, t->nextTimestamp,
+        *ptimestamp, t->nextRxTstamp,
         signal_energy(samplesVoid[0], nsamps));
   return nsamps;
 }
diff --git a/targets/RT/USER/lte-ru.c b/targets/RT/USER/lte-ru.c
index 66ce6ef2474acaa36da14769254d8664e1e37d2d..cee15ef48b1f269d2b4c779acf01f37b049aac5b 100644
--- a/targets/RT/USER/lte-ru.c
+++ b/targets/RT/USER/lte-ru.c
@@ -733,7 +733,7 @@ void tx_rf(RU_t *ru,
   int sf_extension = 0;
 
   if ((SF_type == SF_DL) ||
-      (SF_type == SF_S)) {
+      (SF_type == SF_S) ) {
     int siglen=fp->samples_per_tti,flags=1;
 
     if (SF_type == SF_S) {
@@ -831,6 +831,23 @@ void tx_rf(RU_t *ru,
       late_control=STATE_BURST_TERMINATE;
       LOG_E(PHY,"TX : Timeout (sent %d/%d) state =%d\n",txs, siglen,late_control);
     }
+  } else if (IS_SOFTMODEM_RFSIM ) {
+    // in case of rfsim, we always enable tx because we need to feed rx of the opposite side
+    // we write 1 single I/Q sample to trigger Rx (rfsim will fill gaps with 0 I/Q)
+    void *dummy_tx[ru->frame_parms->nb_antennas_tx];
+    int16_t dummy_tx_data[ru->frame_parms->nb_antennas_tx][2]; // 2 because the function we call use pairs of int16_t implicitly as complex numbers
+    memset(dummy_tx_data,0,sizeof(dummy_tx_data));
+    for (int i=0; i<ru->frame_parms->nb_antennas_tx; i++)
+      dummy_tx[i]= dummy_tx_data[i];
+    
+    AssertFatal( 1 ==
+                 ru->rfdevice.trx_write_func(&ru->rfdevice,
+                                             timestamp+ru->ts_offset-ru->openair0_cfg.tx_sample_advance-sf_extension,
+                                             dummy_tx,
+                                             1,
+                                             ru->frame_parms->nb_antennas_tx,
+                                             4),"");
+    
   }
 }
 
diff --git a/targets/RT/USER/lte-softmodem.h b/targets/RT/USER/lte-softmodem.h
index 0267ad8ce0ab32d0a15c9304a1025b5437dd74bb..1c887dd3c8ee4652fa9ac7d7335ce2557bf67e7f 100644
--- a/targets/RT/USER/lte-softmodem.h
+++ b/targets/RT/USER/lte-softmodem.h
@@ -49,7 +49,6 @@
     {"debug-ue-prach",           CONFIG_HLP_DBGUEPR,    PARAMFLAG_BOOL,   uptr:NULL,                  defuintval:1,       TYPE_INT,   0},    \
     {"no-L2-connect",            CONFIG_HLP_NOL2CN,     PARAMFLAG_BOOL,   uptr:NULL,                  defuintval:1,       TYPE_INT,   0},    \
     {"calib-prach-tx",           CONFIG_HLP_CALPRACH,   PARAMFLAG_BOOL,   uptr:NULL,                  defuintval:1,       TYPE_INT,   0},    \
-    {"loop-memory",              CONFIG_HLP_UELOOP,     0,                strptr:&loopfile,           defstrval:"iqs.in", TYPE_STRING,0},    \
     {"ue-dump-frame",            CONFIG_HLP_DUMPFRAME,  PARAMFLAG_BOOL,   iptr:&dumpframe,            defintval:0,        TYPE_INT,   0},    \
   }
 #define CMDLINE_CALIBUERX_IDX                   0
diff --git a/targets/RT/USER/lte-ue.c b/targets/RT/USER/lte-ue.c
index 9010a40bf951feb6008f4a4acdb0d394f376aaa7..0658b8b9d0ba17f47b932ae9cff05ff5e9e56e77 100644
--- a/targets/RT/USER/lte-ue.c
+++ b/targets/RT/USER/lte-ue.c
@@ -87,15 +87,12 @@ extern void multicast_link_start(void (*rx_handlerP) (unsigned int, char *),
 extern int multicast_link_write_sock(int groupP, char *dataP, uint32_t sizeP);
 
 
-int	tx_req_num_elems;
+int tx_req_num_elems;
 extern uint16_t sf_ahead;
 //extern int tx_req_UE_MAC1();
 
 void ue_stub_rx_handler(unsigned int, char *);
 
-int32_t **rxdata;
-int32_t **txdata;
-
 int timer_subframe = 0;
 int timer_frame = 0;
 SF_ticking *phy_stub_ticking = NULL;
@@ -111,7 +108,7 @@ typedef struct eutra_band_s {
   uint32_t ul_max;
   uint32_t dl_min;
   uint32_t dl_max;
-  lte_frame_type_t frame_type;
+  frame_type_t frame_type;
 } eutra_band_t;
 
 typedef struct band_info_s {
@@ -176,6 +173,7 @@ PHY_VARS_UE *init_ue_vars(LTE_DL_FRAME_PARMS *frame_parms,
 {
   PHY_VARS_UE *ue = (PHY_VARS_UE *)calloc(1,sizeof(PHY_VARS_UE));
   AssertFatal(ue,"");
+
   if (frame_parms!=(LTE_DL_FRAME_PARMS *)NULL) { // if we want to give initial frame parms, allocate the PHY_VARS_UE structure and put them in
     memcpy(&(ue->frame_parms), frame_parms, sizeof(LTE_DL_FRAME_PARMS));
   }
@@ -204,8 +202,7 @@ void init_thread(int sched_runtime,
                  int sched_deadline,
                  int sched_fifo,
                  cpu_set_t *cpuset,
-                 char *name)
-{
+                 char *name) {
 #ifdef DEADLINE_SCHEDULER
 
   if (sched_runtime!=0) {
@@ -266,8 +263,7 @@ void init_UE(int nb_inst,
              runmode_t mode,
              int rxgain,
              int txpowermax,
-             LTE_DL_FRAME_PARMS *fp0)
-{
+             LTE_DL_FRAME_PARMS *fp0) {
   PHY_VARS_UE *UE;
   int         inst;
   int         ret;
@@ -283,9 +279,7 @@ void init_UE(int nb_inst,
     if (PHY_vars_UE_g[inst]==NULL) PHY_vars_UE_g[inst] = (PHY_VARS_UE **)calloc(1+MAX_NUM_CCs,sizeof(PHY_VARS_UE *));
 
     LOG_I(PHY,"Allocating UE context %d\n",inst);
-
     PHY_vars_UE_g[inst][0] = init_ue_vars(fp0,inst,0);
-
     // turn off timing control loop in UE
     PHY_vars_UE_g[inst][0]->no_timing_correction = timing_correction;
     UE = PHY_vars_UE_g[inst][0];
@@ -362,7 +356,6 @@ void init_UE(int nb_inst,
 
     LOG_I(PHY,"Intializing UE Threads for instance %d (%p,%p)...\n",inst,PHY_vars_UE_g[inst],PHY_vars_UE_g[inst][0]);
     init_UE_threads(inst);
-
     ret = openair0_device_load(&(UE->rfdevice), &openair0_cfg[0]);
 
     if (ret !=0) {
@@ -385,8 +378,7 @@ void init_UE(int nb_inst,
 void init_UE_stub_single_thread(int nb_inst,
                                 int eMBMS_active,
                                 int uecap_xer_in,
-                                char *emul_iface)
-{
+                                char *emul_iface) {
   int         inst;
   LOG_I(PHY,"UE : Calling Layer 2 for initialization, nb_inst: %d \n", nb_inst);
   l2_init_ue(eMBMS_active,(uecap_xer_in==1)?uecap_xer:NULL,
@@ -411,24 +403,23 @@ void init_UE_stub_single_thread(int nb_inst,
   }
 }
 
-void init_UE_standalone_thread(int ue_idx)
-{
+void init_UE_standalone_thread(int ue_idx) {
   int standalone_tx_port = 3211 + ue_idx * 2;
   int standalone_rx_port = 3212 + ue_idx * 2;
   ue_init_standalone_socket(standalone_tx_port, standalone_rx_port);
-
   pthread_t thread;
+
   if (pthread_create(&thread, NULL, ue_standalone_pnf_task, NULL) != 0) {
     LOG_E(MAC, "pthread_create failed for calling ue_standalone_pnf_task");
   }
+
   pthread_setname_np(thread, "oai:ue-stand");
 }
 
 void init_UE_stub(int nb_inst,
                   int eMBMS_active,
                   int uecap_xer_in,
-                  char *emul_iface)
-{
+                  char *emul_iface) {
   int         inst;
   LOG_I(PHY,"UE : Calling Layer 2 for initialization\n");
   l2_init_ue(eMBMS_active,(uecap_xer_in==1)?uecap_xer:NULL,
@@ -462,8 +453,7 @@ void init_UE_stub(int nb_inst,
  * \returns a pointer to an int. The storage is not on the heap and must not be freed.
  */
 
-static void *UE_thread_synch(void *arg)
-{
+static void *UE_thread_synch(void *arg) {
   static int UE_thread_synch_retval;
   int i ;
   PHY_VARS_UE *UE = (PHY_VARS_UE *) arg;
@@ -478,6 +468,7 @@ static void *UE_thread_synch(void *arg)
   printf("UE_thread_sync in with PHY_vars_UE %p\n",arg);
   cpu_set_t cpuset;
   CPU_ZERO(&cpuset);
+
   if ( threads.sync != -1 )
     CPU_SET(threads.sync, &cpuset);
 
@@ -757,8 +748,7 @@ static void *UE_thread_synch(void *arg)
  * \param arg is a pointer to a \ref PHY_VARS_UE structure.
  * \returns a pointer to an int. The storage is not on the heap and must not be freed.
  */
-const char *get_connectionloss_errstr(int errcode)
-{
+const char *get_connectionloss_errstr(int errcode) {
   switch (errcode) {
     case CONNECTION_LOST:
       return "RRC Connection lost, returning to PRACH";
@@ -773,8 +763,7 @@ const char *get_connectionloss_errstr(int errcode)
   return "UNKNOWN RETURN CODE";
 }
 
-static void *UE_thread_rxn_txnp4(void *arg)
-{
+static void *UE_thread_rxn_txnp4(void *arg) {
   static __thread int UE_thread_rxtx_retval;
   struct rx_tx_thread_data *rtd = arg;
   UE_rxtx_proc_t *proc = rtd->proc;
@@ -867,13 +856,11 @@ static void *UE_thread_rxn_txnp4(void *arg)
 
     if ((subframe_select( &UE->frame_parms, proc->subframe_tx) == SF_UL) ||
         (UE->frame_parms.frame_type == FDD) )
-      if (UE->mode != loop_through_memory)
-        phy_procedures_UE_TX(UE,proc,0,0,UE->mode);
+      phy_procedures_UE_TX(UE,proc,0,0,UE->mode);
 
     if ((subframe_select( &UE->frame_parms, proc->subframe_tx) == SF_S) &&
         (UE->frame_parms.frame_type == TDD))
-      if (UE->mode != loop_through_memory)
-        phy_procedures_UE_S_TX(UE,0,0);
+      phy_procedures_UE_S_TX(UE,0,0);
 
     proc->instance_cnt_rxtx--;
 
@@ -895,8 +882,7 @@ static void *UE_thread_rxn_txnp4(void *arg)
 unsigned int emulator_absSF;
 
 void ue_stub_rx_handler(unsigned int num_bytes,
-                        char *rx_buffer)
-{
+                        char *rx_buffer) {
   PHY_VARS_UE *UE;
   UE = PHY_vars_UE_g[0][0];
   UE_tport_t *pdu = (UE_tport_t *)rx_buffer;
@@ -951,14 +937,14 @@ void ue_stub_rx_handler(unsigned int num_bytes,
   }
 }
 
-uint64_t clock_usec(void)
-{
-    struct timespec t;
-    if (clock_gettime(CLOCK_MONOTONIC, &t) == -1)
-    {
-        abort();
-    }
-    return (uint64_t)t.tv_sec * 1000000 + (t.tv_nsec / 1000);
+uint64_t clock_usec(void) {
+  struct timespec t;
+
+  if (clock_gettime(CLOCK_MONOTONIC, &t) == -1) {
+    abort();
+  }
+
+  return (uint64_t)t.tv_sec * 1000000 + (t.tv_nsec / 1000);
 }
 /*!
  * \brief This is the UE thread for RX subframe n and TX subframe n+4.
@@ -968,23 +954,21 @@ uint64_t clock_usec(void)
  * \returns a pointer to an int. The storage is not on the heap and must not be freed.
  */
 
-static void *UE_phy_stub_standalone_pnf_task(void *arg)
-{
+static void *UE_phy_stub_standalone_pnf_task(void *arg) {
 #if 1
   {
     struct sched_param sparam =
     {
       .sched_priority = 79,
     };
-    if (pthread_setschedparam(pthread_self(), SCHED_RR, &sparam) != 0)
-    {
+
+    if (pthread_setschedparam(pthread_self(), SCHED_RR, &sparam) != 0) {
       LOG_E(PHY,"pthread_setschedparam: %s\n", strerror(errno));
     }
   }
 #else
   thread_top_init("UE_phy_stub_thread_rxn_txnp4", 1, 870000L, 1000000L, 1000000L);
 #endif
-
   // for multipule UE's L2-emulator
   //module_id_t Mod_id = 0;
   //int init_ra_UE = -1; // This counter is used to initiate the RA of each UE in different SFrames
@@ -1004,9 +988,7 @@ static void *UE_phy_stub_standalone_pnf_task(void *arg)
   PHY_VARS_UE *UE = NULL;
   int ret;
   proc = &PHY_vars_UE_g[0][0]->proc.proc_rxtx[0];
-
   UE = rtd->UE;
-
   UL_INFO = (UL_IND_t *)calloc(1, sizeof(UL_IND_t));
   UL_INFO->rx_ind.rx_indication_body.rx_pdu_list = calloc(NFAPI_RX_IND_MAX_PDU, sizeof(nfapi_rx_indication_pdu_t));
   UL_INFO->rx_ind.rx_indication_body.number_of_pdus = 0;
@@ -1019,19 +1001,15 @@ static void *UE_phy_stub_standalone_pnf_task(void *arg)
   UL_INFO->cqi_ind.cqi_indication_body.cqi_pdu_list = calloc(NFAPI_CQI_IND_MAX_PDU, sizeof(nfapi_cqi_indication_pdu_t));
   UL_INFO->cqi_ind.cqi_indication_body.cqi_raw_pdu_list = calloc(NFAPI_CQI_IND_MAX_PDU, sizeof(nfapi_cqi_indication_raw_pdu_t));
   UL_INFO->cqi_ind.cqi_indication_body.number_of_cqis = 0;
-
   proc->subframe_rx = proc->sub_frame_start;
   proc->subframe_tx = -1;
   proc->frame_rx = -1;
   proc->frame_tx = -1;
   // Initializations for nfapi-L2-emulator mode
   sync_var = 0;
-
   //PANOS: CAREFUL HERE!
   wait_sync("UE_phy_stub_standalone_pnf_task");
-
   int last_sfn_sf = -1;
-
   LOG_I(MAC, "Clearing Queues\n");
   reset_queue(&dl_config_req_tx_req_queue);
   reset_queue(&ul_config_req_queue);
@@ -1039,72 +1017,77 @@ static void *UE_phy_stub_standalone_pnf_task(void *arg)
 
   while (!oai_exit) {
     bool sent_any = false;
+
     if (sem_wait(&sfn_semaphore) != 0) {
       LOG_E(MAC, "sem_wait() error\n");
       abort();
     }
 
     int sfn_sf = current_sfn_sf;
-    if (sfn_sf == last_sfn_sf)
-    {
+
+    if (sfn_sf == last_sfn_sf) {
       LOG_W(MAC, "repeated sfn_sf = %d.%d\n",
             sfn_sf >> 4, sfn_sf & 15);
       continue;
     }
-    last_sfn_sf = sfn_sf;
 
+    last_sfn_sf = sfn_sf;
     nfapi_dl_config_req_tx_req_t *dl_config_req_tx_req = get_queue(&dl_config_req_tx_req_queue);
     nfapi_ul_config_request_t *ul_config_req = get_queue(&ul_config_req_queue);
     nfapi_hi_dci0_request_t *hi_dci0_req = get_queue(&hi_dci0_req_queue);
-
     LOG_I(MAC, "received from proxy frame %d subframe %d\n",
           NFAPI_SFNSF2SFN(sfn_sf), NFAPI_SFNSF2SF(sfn_sf));
 
     if (ul_config_req != NULL) {
       uint8_t ul_num_pdus = ul_config_req->ul_config_request_body.number_of_pdus;
+
       if (ul_num_pdus > 0) {
         char *ul_str = nfapi_ul_config_req_to_string(ul_config_req);
         LOG_I(MAC, "ul_config_req: %s\n", ul_str);
         free(ul_str);
       }
     }
+
     if (hi_dci0_req != NULL) {
       LOG_D(MAC, "hi_dci0_req pdus: %u Frame: %d Subframe: %d\n",
-      hi_dci0_req->hi_dci0_request_body.number_of_dci,
-      NFAPI_SFNSF2SFN(hi_dci0_req->sfn_sf), NFAPI_SFNSF2SF(hi_dci0_req->sfn_sf));
+            hi_dci0_req->hi_dci0_request_body.number_of_dci,
+            NFAPI_SFNSF2SFN(hi_dci0_req->sfn_sf), NFAPI_SFNSF2SF(hi_dci0_req->sfn_sf));
     }
 
     if (dl_config_req_tx_req != NULL) {
-
       nfapi_tx_req_pdu_list_t *tx_req_pdu_list = dl_config_req_tx_req->tx_req_pdu_list;
       nfapi_dl_config_request_t *dl_config_req = dl_config_req_tx_req->dl_config_req;
-
       uint16_t dl_num_pdus = dl_config_req->dl_config_request_body.number_pdu;
       LOG_I(MAC, "(OAI UE) Received dl_config_req from proxy at Frame: %d, Subframe: %d,"
             " with number of PDUs: %u\n",
             NFAPI_SFNSF2SFN(dl_config_req->sfn_sf), NFAPI_SFNSF2SF(dl_config_req->sfn_sf),
             dl_num_pdus);
+
       if (dl_num_pdus > 0) {
         char *dl_str = nfapi_dl_config_req_to_string(dl_config_req);
         LOG_I(MAC, "dl_config_req: %s\n", dl_str);
         free(dl_str);
       }
-      LOG_D(MAC, "tx_req pdus: %d\n", tx_req_pdu_list->num_pdus);
 
+      LOG_D(MAC, "tx_req pdus: %d\n", tx_req_pdu_list->num_pdus);
       // Handling dl_config_req and tx_req:
       nfapi_dl_config_request_body_t *dl_config_req_body = &dl_config_req->dl_config_request_body;
+
       for (int i = 0; i < dl_config_req_body->number_pdu; ++i) {
         nfapi_dl_config_request_pdu_t *pdu = &dl_config_req_body->dl_config_pdu_list[i];
+
         if (pdu->pdu_type == NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE) {
           i += 1;
           AssertFatal(i < dl_config_req->dl_config_request_body.number_pdu,
                       "Need PDU following DCI at index %d, but not found\n",
                       i);
           nfapi_dl_config_request_pdu_t *dlsch = &dl_config_req_body->dl_config_pdu_list[i];
+
           if (dlsch->pdu_type != NFAPI_DL_CONFIG_DLSCH_PDU_TYPE) {
             LOG_E(MAC, "expected DLSCH PDU at index %d\n", i);
             continue;
           }
+
           dl_config_req_UE_MAC_dci(NFAPI_SFNSF2SFN(dl_config_req->sfn_sf),
                                    NFAPI_SFNSF2SF(dl_config_req->sfn_sf),
                                    pdu,
@@ -1125,8 +1108,10 @@ static void *UE_phy_stub_standalone_pnf_task(void *arg)
         }
       }
     }
+
     if (hi_dci0_req) {
       nfapi_hi_dci0_request_body_t *hi_dci0_body = &hi_dci0_req->hi_dci0_request_body;
+
       for (int i = 0; i < hi_dci0_body->number_of_dci + hi_dci0_body->number_of_hi; i++) {
         nfapi_hi_dci0_request_pdu_t *pdu = &hi_dci0_body->hi_dci0_pdu_list[i];
         hi_dci0_req_UE_MAC(NFAPI_SFNSF2SFN(hi_dci0_req->sfn_sf),
@@ -1139,13 +1124,13 @@ static void *UE_phy_stub_standalone_pnf_task(void *arg)
     for (ue_index = 0; ue_index < ue_num; ue_index++) {
       ue_Mod_id = ue_thread_id + NB_THREAD_INST * ue_index; // Always 0 in standalone pnf mode
       UE = PHY_vars_UE_g[ue_Mod_id][0];
-
 #if UE_TIMING_TRACE
       start_meas(&UE->generic_stat);
 #endif
       int rx_frame = NFAPI_SFNSF2SF(sfn_sf) < 4 ? (NFAPI_SFNSF2SFN(sfn_sf) + 1023) % 1024 : NFAPI_SFNSF2SFN(sfn_sf); // subtracting 4 from subframe_tx
       int rx_subframe = NFAPI_SFNSF2SF(sfn_sf) < 4 ? NFAPI_SFNSF2SF(sfn_sf) + 6 : NFAPI_SFNSF2SF(sfn_sf) - 4;
       LOG_D(MAC, "rx_frame %d rx_subframe %d\n", rx_frame, rx_subframe);
+
       if (UE->mac_enabled == 1) {
         ret = ue_scheduler(ue_Mod_id,
                            rx_frame,
@@ -1168,67 +1153,60 @@ static void *UE_phy_stub_standalone_pnf_task(void *arg)
 
       // Prepare the future Tx data
       if ((subframe_select(&UE->frame_parms, NFAPI_SFNSF2SF(sfn_sf)) == SF_UL) ||
-          (UE->frame_parms.frame_type == FDD))
-      {
-        if (UE->mode != loop_through_memory)
-        {
-          // We make the start of RA between consecutive UEs differ by 20 frames
-          //if ((UE_mac_inst[Mod_id].UE_mode[0] == PRACH  && Mod_id == 0) || (UE_mac_inst[Mod_id].UE_mode[0] == PRACH && Mod_id>0 && rx_frame >= UE_mac_inst[Mod_id-1].ra_frame + 20) ) {
-          if (UE_mac_inst[ue_Mod_id].UE_mode[0] == RA_RESPONSE &&
-              is_prach_subframe(&UE->frame_parms, NFAPI_SFNSF2SFN(sfn_sf), NFAPI_SFNSF2SF(sfn_sf)))
-          {
-            UE_mac_inst[ue_Mod_id].UE_mode[0] = PRACH;
-          }
-          LOG_D(MAC, "UE_mode: %d\n", UE_mac_inst[ue_Mod_id].UE_mode[0]);
-          if (UE_mac_inst[ue_Mod_id].UE_mode[0] == PRACH)
-          { //&& ue_Mod_id == next_Mod_id) {
-            next_ra_frame++;
-            if (next_ra_frame > 500)
-            {
-              // check if we have PRACH opportunity
-              if (is_prach_subframe(&UE->frame_parms, NFAPI_SFNSF2SFN(sfn_sf), NFAPI_SFNSF2SF(sfn_sf)) && UE_mac_inst[ue_Mod_id].SI_Decoded == 1)
-              {
-                // The one working strangely...
-                //if (is_prach_subframe(&UE->frame_parms,NFAPI_SFNSF2SFN(sfn_sf), NFAPI_SFNSF2SF(sfn_sf) && Mod_id == (module_id_t) init_ra_UE) ) {
-                PRACH_RESOURCES_t *prach_resources = ue_get_rach(ue_Mod_id, 0, NFAPI_SFNSF2SFN(sfn_sf), 0, NFAPI_SFNSF2SF(sfn_sf));
-                if (prach_resources != NULL)
-                {
-                  LOG_I(MAC, "preamble_received_tar_power: %d\n",
-                        prach_resources->ra_PREAMBLE_RECEIVED_TARGET_POWER);
-                  UE_mac_inst[ue_Mod_id].ra_frame = NFAPI_SFNSF2SFN(sfn_sf);
-                  LOG_D(MAC, "UE_phy_stub_thread_rxn_txnp4 before RACH, Mod_id: %d frame %d subframe %d\n", ue_Mod_id, NFAPI_SFNSF2SFN(sfn_sf), NFAPI_SFNSF2SF(sfn_sf));
-                  fill_rach_indication_UE_MAC(ue_Mod_id, NFAPI_SFNSF2SFN(sfn_sf), NFAPI_SFNSF2SF(sfn_sf), UL_INFO, prach_resources->ra_PreambleIndex, prach_resources->ra_RNTI);
-                  sent_any = true;
-                  Msg1_transmitted(ue_Mod_id, 0, NFAPI_SFNSF2SFN(sfn_sf), 0);
-                  UE_mac_inst[ue_Mod_id].UE_mode[0] = RA_RESPONSE;
-                  next_Mod_id = ue_Mod_id + 1;
-                  //next_ra_frame = (rx_frame + 20)%1000;
-                  next_ra_frame = 0;
-                }
-                //ue_prach_procedures(ue,proc,eNB_id,abstraction_flag,mode);
+          (UE->frame_parms.frame_type == FDD)) {
+        // We make the start of RA between consecutive UEs differ by 20 frames
+        //if ((UE_mac_inst[Mod_id].UE_mode[0] == PRACH  && Mod_id == 0) || (UE_mac_inst[Mod_id].UE_mode[0] == PRACH && Mod_id>0 && rx_frame >= UE_mac_inst[Mod_id-1].ra_frame + 20) ) {
+        if (UE_mac_inst[ue_Mod_id].UE_mode[0] == RA_RESPONSE &&
+            is_prach_subframe(&UE->frame_parms, NFAPI_SFNSF2SFN(sfn_sf), NFAPI_SFNSF2SF(sfn_sf))) {
+          UE_mac_inst[ue_Mod_id].UE_mode[0] = PRACH;
+        }
+
+        LOG_D(MAC, "UE_mode: %d\n", UE_mac_inst[ue_Mod_id].UE_mode[0]);
+
+        if (UE_mac_inst[ue_Mod_id].UE_mode[0] == PRACH) {
+          //&& ue_Mod_id == next_Mod_id) {
+          next_ra_frame++;
+
+          if (next_ra_frame > 500) {
+            // check if we have PRACH opportunity
+            if (is_prach_subframe(&UE->frame_parms, NFAPI_SFNSF2SFN(sfn_sf), NFAPI_SFNSF2SF(sfn_sf)) && UE_mac_inst[ue_Mod_id].SI_Decoded == 1) {
+              // The one working strangely...
+              //if (is_prach_subframe(&UE->frame_parms,NFAPI_SFNSF2SFN(sfn_sf), NFAPI_SFNSF2SF(sfn_sf) && Mod_id == (module_id_t) init_ra_UE) ) {
+              PRACH_RESOURCES_t *prach_resources = ue_get_rach(ue_Mod_id, 0, NFAPI_SFNSF2SFN(sfn_sf), 0, NFAPI_SFNSF2SF(sfn_sf));
+
+              if (prach_resources != NULL) {
+                LOG_I(MAC, "preamble_received_tar_power: %d\n",
+                      prach_resources->ra_PREAMBLE_RECEIVED_TARGET_POWER);
+                UE_mac_inst[ue_Mod_id].ra_frame = NFAPI_SFNSF2SFN(sfn_sf);
+                LOG_D(MAC, "UE_phy_stub_thread_rxn_txnp4 before RACH, Mod_id: %d frame %d subframe %d\n", ue_Mod_id, NFAPI_SFNSF2SFN(sfn_sf), NFAPI_SFNSF2SF(sfn_sf));
+                fill_rach_indication_UE_MAC(ue_Mod_id, NFAPI_SFNSF2SFN(sfn_sf), NFAPI_SFNSF2SF(sfn_sf), UL_INFO, prach_resources->ra_PreambleIndex, prach_resources->ra_RNTI);
+                sent_any = true;
+                Msg1_transmitted(ue_Mod_id, 0, NFAPI_SFNSF2SFN(sfn_sf), 0);
+                UE_mac_inst[ue_Mod_id].UE_mode[0] = RA_RESPONSE;
+                next_Mod_id = ue_Mod_id + 1;
+                //next_ra_frame = (rx_frame + 20)%1000;
+                next_ra_frame = 0;
               }
+
+              //ue_prach_procedures(ue,proc,eNB_id,abstraction_flag,mode);
             }
-          } // mode is PRACH
-
-          // Substitute call to phy_procedures Tx with call to phy_stub functions in order to trigger
-          // UE Tx procedures directly at the MAC layer, based on the received ul_config requests from the vnf (eNB).
-          // Generate UL_indications which correspond to UL traffic.
-          if (ul_config_req != NULL)
-          { //&& UE_mac_inst[Mod_id].ul_config_req->ul_config_request_body.ul_config_pdu_list != NULL){
-            ul_config_req_UE_MAC(ul_config_req, NFAPI_SFNSF2SFN(sfn_sf), NFAPI_SFNSF2SF(sfn_sf), ue_Mod_id);
           }
-        }
+        } // mode is PRACH
 
-        phy_procedures_UE_SL_RX(UE, proc);
-      }
-      else
-      {
+        // Substitute call to phy_procedures Tx with call to phy_stub functions in order to trigger
+        // UE Tx procedures directly at the MAC layer, based on the received ul_config requests from the vnf (eNB).
+        // Generate UL_indications which correspond to UL traffic.
+        if (ul_config_req != NULL) {
+          //&& UE_mac_inst[Mod_id].ul_config_req->ul_config_request_body.ul_config_pdu_list != NULL){
+          ul_config_req_UE_MAC(ul_config_req, NFAPI_SFNSF2SFN(sfn_sf), NFAPI_SFNSF2SF(sfn_sf), ue_Mod_id);
+        }
+      } else {
         LOG_I(MAC, "Skipping subframe select statement proxy SFN.SF: %d.%d\n",
-        NFAPI_SFNSF2SFN(sfn_sf), NFAPI_SFNSF2SF(sfn_sf));
-        if (ul_config_req != NULL)
-        {
+              NFAPI_SFNSF2SFN(sfn_sf), NFAPI_SFNSF2SF(sfn_sf));
+
+        if (ul_config_req != NULL) {
           LOG_I(MAC, "Skipping subframe select statement ul_config_req SFN.SF: %d.%d\n",
-          NFAPI_SFNSF2SFN(ul_config_req->sfn_sf), NFAPI_SFNSF2SF(ul_config_req->sfn_sf));
+                NFAPI_SFNSF2SFN(ul_config_req->sfn_sf), NFAPI_SFNSF2SF(ul_config_req->sfn_sf));
         }
       }
     } //for (Mod_id=0; Mod_id<NB_UE_INST; Mod_id++)
@@ -1243,12 +1221,10 @@ static void *UE_phy_stub_standalone_pnf_task(void *arg)
     }
 
     if (UL_INFO->rx_ind.rx_indication_body.number_of_pdus > 0) {
-
       //LOG_D(PHY,"UL_info->rx_ind.number_of_pdus:%d RX_IND:SFN/SF:%d\n", UL_info->rx_ind.rx_indication_body.number_of_pdus, NFAPI_SFNSF2DEC(UL_info->rx_ind.sfn_sf));
       //LOG_I(MAC, "ul_config_req_UE_MAC 2.3, SFN/SF of PNF counter:%d.%d, number_of_pdus: %d \n", timer_frame, timer_subframe, UL_INFO->rx_ind.rx_indication_body.number_of_pdus);
       send_standalone_msg(UL_INFO, UL_INFO->rx_ind.header.message_id);
       sent_any = true;
-
       //LOG_I(MAC, "ul_config_req_UE_MAC 2.31 \n");
       UL_INFO->rx_ind.rx_indication_body.number_of_pdus = 0;
     }
@@ -1261,16 +1237,16 @@ static void *UE_phy_stub_standalone_pnf_task(void *arg)
 
     if (UL_INFO->harq_ind.harq_indication_body.number_of_harqs > 0) {
       //LOG_D(MAC, "ul_config_req_UE_MAC 2.4, SFN/SF of PNF counter:%d.%d, number_of_harqs: %d \n", timer_frame, timer_subframe, UL_INFO->harq_ind.harq_indication_body.number_of_harqs);
-        send_standalone_msg(UL_INFO, UL_INFO->harq_ind.header.message_id);
-        sent_any = true;
+      send_standalone_msg(UL_INFO, UL_INFO->harq_ind.header.message_id);
+      sent_any = true;
       //LOG_I(MAC, "ul_config_req_UE_MAC 2.41 \n");
       UL_INFO->harq_ind.harq_indication_body.number_of_harqs = 0;
     }
 
     if (UL_INFO->sr_ind.sr_indication_body.number_of_srs > 0) {
       //LOG_I(MAC, "ul_config_req_UE_MAC 2.5, SFN/SF of PNF counter:%d.%d, number_of_srs: %d \n", timer_frame, timer_subframe, UL_INFO->sr_ind.sr_indication_body.number_of_srs);
-        send_standalone_msg(UL_INFO, UL_INFO->sr_ind.header.message_id);
-        sent_any = true;
+      send_standalone_msg(UL_INFO, UL_INFO->sr_ind.header.message_id);
+      sent_any = true;
       //LOG_I(MAC, "ul_config_req_UE_MAC 2.51 \n");
       UL_INFO->sr_ind.sr_indication_body.number_of_srs = 0;
     }
@@ -1286,12 +1262,11 @@ static void *UE_phy_stub_standalone_pnf_task(void *arg)
         free(dl_config_req_tx_req->dl_config_req->dl_config_request_body.dl_config_pdu_list);
         dl_config_req_tx_req->dl_config_req->dl_config_request_body.dl_config_pdu_list = NULL;
       }
+
       nfapi_free_tx_req_pdu_list(dl_config_req_tx_req->tx_req_pdu_list);
       dl_config_req_tx_req->tx_req_pdu_list = NULL;
-
       free(dl_config_req_tx_req->dl_config_req);
       dl_config_req_tx_req->dl_config_req = NULL;
-
       free(dl_config_req_tx_req);
       dl_config_req_tx_req = NULL;
     }
@@ -1315,9 +1290,9 @@ static void *UE_phy_stub_standalone_pnf_task(void *arg)
       free(hi_dci0_req);
       hi_dci0_req = NULL;
     }
-    if (!sent_any)
-    {
-     send_standalone_dummy();
+
+    if (!sent_any) {
+      send_standalone_dummy();
     }
   }
 
@@ -1336,7 +1311,6 @@ static void *UE_phy_stub_standalone_pnf_task(void *arg)
   UL_INFO->rx_ind.rx_indication_body.rx_pdu_list = NULL;
   free(UL_INFO);
   UL_INFO = NULL;
-
   // thread finished
   free(arg);
   return NULL;
@@ -1350,8 +1324,7 @@ static void *UE_phy_stub_standalone_pnf_task(void *arg)
  * \returns a pointer to an int. The storage is not on the heap and must not be freed.
  */
 
-static void *UE_phy_stub_single_thread_rxn_txnp4(void *arg)
-{
+static void *UE_phy_stub_single_thread_rxn_txnp4(void *arg) {
 #if 0 // TODO: doesn't currently compile, obviated by multi-ue proxy
   thread_top_init("UE_phy_stub_thread_rxn_txnp4",1,870000L,1000000L,1000000L);
   // for multipule UE's L2-emulator
@@ -1377,7 +1350,6 @@ static void *UE_phy_stub_single_thread_rxn_txnp4(void *arg)
   proc = &PHY_vars_UE_g[0][0]->proc.proc_rxtx[0];
   phy_stub_ticking->num_single_thread[ue_thread_id] = -1;
   UE = rtd->UE;
-
   UL_INFO = (UL_IND_t *)malloc(sizeof(UL_IND_t));
   UL_INFO->rx_ind.rx_indication_body.rx_pdu_list = calloc(NB_UE_INST, sizeof(nfapi_rx_indication_pdu_t));
   UL_INFO->rx_ind.rx_indication_body.number_of_pdus = 0;
@@ -1489,19 +1461,23 @@ static void *UE_phy_stub_single_thread_rxn_txnp4(void *arg)
     }
 
     if (dl_config_req && tx_req_pdu_list) {
-      nfapi_dl_config_request_body_t* dl_config_req_body = &dl_config_req->dl_config_request_body;
+      nfapi_dl_config_request_body_t *dl_config_req_body = &dl_config_req->dl_config_request_body;
+
       for (int i = 0; i < dl_config_req_body->number_pdu; ++i) {
-        nfapi_dl_config_request_pdu_t* pdu = &dl_config_req_body->dl_config_pdu_list[i];
+        nfapi_dl_config_request_pdu_t *pdu = &dl_config_req_body->dl_config_pdu_list[i];
+
         if (pdu->pdu_type ==  NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE) {
           i += 1;
           AssertFatal(i < dl_config_req->dl_config_request_body.number_pdu,
                       "Need PDU following DCI at index %d, but not found\n",
                       i);
           nfapi_dl_config_request_pdu_t *dlsch = &dl_config_req_body->dl_config_pdu_list[i];
+
           if (dlsch->pdu_type != NFAPI_DL_CONFIG_DLSCH_PDU_TYPE) {
             LOG_E(MAC, "expected DLSCH PDU at index %d\n", i);
             continue;
           }
+
           dl_config_req_UE_MAC_dci(NFAPI_SFNSF2SFN(dl_config_req->sfn_sf),
                                    NFAPI_SFNSF2SF(dl_config_req->sfn_sf),
                                    pdu,
@@ -1523,8 +1499,9 @@ static void *UE_phy_stub_single_thread_rxn_txnp4(void *arg)
 
     if (hi_dci0_req) {
       nfapi_hi_dci0_request_body_t *hi_dci0_body = &hi_dci0_req->hi_dci0_request_body;
+
       for (int i = 0; i < hi_dci0_body->number_of_dci + hi_dci0_body->number_of_hi; i++) {
-        nfapi_hi_dci0_request_pdu_t* pdu = &hi_dci0_body->hi_dci0_pdu_list[i];
+        nfapi_hi_dci0_request_pdu_t *pdu = &hi_dci0_body->hi_dci0_pdu_list[i];
         hi_dci0_req_UE_MAC(NFAPI_SFNSF2SFN(hi_dci0_req->sfn_sf),
                            NFAPI_SFNSF2SF(hi_dci0_req->sfn_sf),
                            pdu,
@@ -1592,44 +1569,41 @@ static void *UE_phy_stub_single_thread_rxn_txnp4(void *arg)
 
       if ((subframe_select( &UE->frame_parms, proc->subframe_tx) == SF_UL) ||
           (UE->frame_parms.frame_type == FDD) )
-        if (UE->mode != loop_through_memory) {
-          // We make the start of RA between consecutive UEs differ by 20 frames
-          //if ((UE_mac_inst[Mod_id].UE_mode[0] == PRACH  && Mod_id == 0) || (UE_mac_inst[Mod_id].UE_mode[0] == PRACH && Mod_id>0 && proc->frame_rx >= UE_mac_inst[Mod_id-1].ra_frame + 20) ) {
-          if (UE_mac_inst[ue_Mod_id].UE_mode[0] == PRACH  && ue_Mod_id == next_Mod_id) {
-            next_ra_frame++;
-
-            if(next_ra_frame > 500) {
-              // check if we have PRACH opportunity
-              if (is_prach_subframe(&UE->frame_parms,proc->frame_tx, proc->subframe_tx) &&  UE_mac_inst[ue_Mod_id].SI_Decoded == 1) {
-                // The one working strangely...
-                //if (is_prach_subframe(&UE->frame_parms,proc->frame_tx, proc->subframe_tx && Mod_id == (module_id_t) init_ra_UE) ) {
-                PRACH_RESOURCES_t *prach_resources = ue_get_rach(ue_Mod_id, 0, proc->frame_tx, 0, proc->subframe_tx);
-
-                if(prach_resources!=NULL ) {
-                  UE_mac_inst[ue_Mod_id].ra_frame = proc->frame_rx;
-                  LOG_D(MAC, "UE_phy_stub_thread_rxn_txnp4 before RACH, Mod_id: %d frame %d subframe %d\n", ue_Mod_id,proc->frame_tx, proc->subframe_tx);
-                  fill_rach_indication_UE_MAC(ue_Mod_id, proc->frame_tx,proc->subframe_tx, UL_INFO, prach_resources->ra_PreambleIndex, prach_resources->ra_RNTI);
-                  Msg1_transmitted(ue_Mod_id, 0, proc->frame_tx, 0);
-                  UE_mac_inst[ue_Mod_id].UE_mode[0] = RA_RESPONSE;
-                  next_Mod_id = ue_Mod_id + 1;
-                  //next_ra_frame = (proc->frame_rx + 20)%1000;
-                  next_ra_frame = 0;
-                }
 
-                //ue_prach_procedures(ue,proc,eNB_id,abstraction_flag,mode);
+        // We make the start of RA between consecutive UEs differ by 20 frames
+        //if ((UE_mac_inst[Mod_id].UE_mode[0] == PRACH  && Mod_id == 0) || (UE_mac_inst[Mod_id].UE_mode[0] == PRACH && Mod_id>0 && proc->frame_rx >= UE_mac_inst[Mod_id-1].ra_frame + 20) ) {
+        if (UE_mac_inst[ue_Mod_id].UE_mode[0] == PRACH  && ue_Mod_id == next_Mod_id) {
+          next_ra_frame++;
+
+          if(next_ra_frame > 500) {
+            // check if we have PRACH opportunity
+            if (is_prach_subframe(&UE->frame_parms,proc->frame_tx, proc->subframe_tx) &&  UE_mac_inst[ue_Mod_id].SI_Decoded == 1) {
+              // The one working strangely...
+              //if (is_prach_subframe(&UE->frame_parms,proc->frame_tx, proc->subframe_tx && Mod_id == (module_id_t) init_ra_UE) ) {
+              PRACH_RESOURCES_t *prach_resources = ue_get_rach(ue_Mod_id, 0, proc->frame_tx, 0, proc->subframe_tx);
+
+              if(prach_resources!=NULL ) {
+                UE_mac_inst[ue_Mod_id].ra_frame = proc->frame_rx;
+                LOG_D(MAC, "UE_phy_stub_thread_rxn_txnp4 before RACH, Mod_id: %d frame %d subframe %d\n", ue_Mod_id,proc->frame_tx, proc->subframe_tx);
+                fill_rach_indication_UE_MAC(ue_Mod_id, proc->frame_tx,proc->subframe_tx, UL_INFO, prach_resources->ra_PreambleIndex, prach_resources->ra_RNTI);
+                Msg1_transmitted(ue_Mod_id, 0, proc->frame_tx, 0);
+                UE_mac_inst[ue_Mod_id].UE_mode[0] = RA_RESPONSE;
+                next_Mod_id = ue_Mod_id + 1;
+                //next_ra_frame = (proc->frame_rx + 20)%1000;
+                next_ra_frame = 0;
               }
-            }
-          } // mode is PRACH
 
-          // Substitute call to phy_procedures Tx with call to phy_stub functions in order to trigger
-          // UE Tx procedures directly at the MAC layer, based on the received ul_config requests from the vnf (eNB).
-          // Generate UL_indications which correspond to UL traffic.
-          if(ul_config_req!=NULL) { //&& UE_mac_inst[Mod_id].ul_config_req->ul_config_request_body.ul_config_pdu_list != NULL){
-            ul_config_req_UE_MAC(ul_config_req, timer_frame, timer_subframe, ue_Mod_id);
+              //ue_prach_procedures(ue,proc,eNB_id,abstraction_flag,mode);
+            }
           }
-        }
+        } // mode is PRACH
 
-      phy_procedures_UE_SL_RX(UE,proc);
+      // Substitute call to phy_procedures Tx with call to phy_stub functions in order to trigger
+      // UE Tx procedures directly at the MAC layer, based on the received ul_config requests from the vnf (eNB).
+      // Generate UL_indications which correspond to UL traffic.
+      if(ul_config_req!=NULL) { //&& UE_mac_inst[Mod_id].ul_config_req->ul_config_request_body.ul_config_pdu_list != NULL){
+        ul_config_req_UE_MAC(ul_config_req, timer_frame, timer_subframe, ue_Mod_id);
+      }
     } //for (Mod_id=0; Mod_id<NB_UE_INST; Mod_id++)
 
     phy_stub_ticking->num_single_thread[ue_thread_id] = -1;
@@ -1709,6 +1683,7 @@ static void *UE_phy_stub_single_thread_rxn_txnp4(void *arg)
             tx_req_pdu_list[i].segments[j].segment_data = NULL;
           }
         }
+
         tx_req_num_elems = 0;
         free(tx_req_pdu_list);
         tx_req_pdu_list = NULL;
@@ -1752,7 +1727,6 @@ static void *UE_phy_stub_single_thread_rxn_txnp4(void *arg)
   free(UL_INFO);
   UL_INFO = NULL;
 #endif // disabled UE_phy_stub_single_thread_rxn_txnp4
-
   // thread finished
   free(arg);
   return NULL;
@@ -1767,9 +1741,8 @@ static void *UE_phy_stub_single_thread_rxn_txnp4(void *arg)
  * \returns a pointer to an int. The storage is not on the heap and must not be freed.
  */
 
-static void *UE_phy_stub_thread_rxn_txnp4(void *arg)
-{
-  #if 0
+static void *UE_phy_stub_thread_rxn_txnp4(void *arg) {
+#if 0
   thread_top_init("UE_phy_stub_thread_rxn_txnp4",1,870000L,1000000L,1000000L);
   module_id_t Mod_id = 0;
   static __thread int UE_thread_rxtx_retval;
@@ -1880,45 +1853,42 @@ static void *UE_phy_stub_thread_rxn_txnp4(void *arg)
 
     if ((subframe_select( &UE->frame_parms, proc->subframe_tx) == SF_UL) ||
         (UE->frame_parms.frame_type == FDD) )
-      if (UE->mode != loop_through_memory) {
-        if ((UE_mac_inst[Mod_id].UE_mode[0] == PRACH) ) {
-          // check if we have PRACH opportunity
-          if (is_prach_subframe(&UE->frame_parms,proc->frame_tx, proc->subframe_tx)) {
-            PRACH_RESOURCES_t *prach_resources = ue_get_rach(Mod_id, 0, proc->frame_tx, 0, proc->subframe_tx);
-
-            if(prach_resources!=NULL) {
-              fill_rach_indication_UE_MAC(Mod_id, proc->frame_tx,proc->subframe_tx, UL_INFO, prach_resources->ra_PreambleIndex, prach_resources->ra_RNTI);
-              Msg1_transmitted(Mod_id, 0, proc->frame_tx, 0);
-              UE_mac_inst[Mod_id].UE_mode[0] = RA_RESPONSE;
-            }
-
-            //ue_prach_procedures(ue,proc,eNB_id,abstraction_flag,mode);
+      if ((UE_mac_inst[Mod_id].UE_mode[0] == PRACH) ) {
+        // check if we have PRACH opportunity
+        if (is_prach_subframe(&UE->frame_parms,proc->frame_tx, proc->subframe_tx)) {
+          PRACH_RESOURCES_t *prach_resources = ue_get_rach(Mod_id, 0, proc->frame_tx, 0, proc->subframe_tx);
+
+          if(prach_resources!=NULL) {
+            fill_rach_indication_UE_MAC(Mod_id, proc->frame_tx,proc->subframe_tx, UL_INFO, prach_resources->ra_PreambleIndex, prach_resources->ra_RNTI);
+            Msg1_transmitted(Mod_id, 0, proc->frame_tx, 0);
+            UE_mac_inst[Mod_id].UE_mode[0] = RA_RESPONSE;
           }
-        } // mode is PRACH
 
-        // Substitute call to phy_procedures Tx with call to phy_stub functions in order to trigger
-        // UE Tx procedures directly at the MAC layer, based on the received ul_config requests from the vnf (eNB).
-        // Generate UL_indications which correspond to UL traffic.
-        if(ul_config_req!= NULL && ul_config_req->ul_config_request_body.ul_config_pdu_list != NULL) {
-          //LOG_I(MAC, "UE_phy_stub_thread_rxn_txnp4 ul_config_req is not NULL \n");
-          ul_config_req_UE_MAC(ul_config_req, timer_frame, timer_subframe, Mod_id);
+          //ue_prach_procedures(ue,proc,eNB_id,abstraction_flag,mode);
+        }
+      } // mode is PRACH
 
-          if(ul_config_req->ul_config_request_body.ul_config_pdu_list != NULL) {
-            free(ul_config_req->ul_config_request_body.ul_config_pdu_list);
-            ul_config_req->ul_config_request_body.ul_config_pdu_list = NULL;
-          }
+    // Substitute call to phy_procedures Tx with call to phy_stub functions in order to trigger
+    // UE Tx procedures directly at the MAC layer, based on the received ul_config requests from the vnf (eNB).
+    // Generate UL_indications which correspond to UL traffic.
+    if(ul_config_req!= NULL && ul_config_req->ul_config_request_body.ul_config_pdu_list != NULL) {
+      //LOG_I(MAC, "UE_phy_stub_thread_rxn_txnp4 ul_config_req is not NULL \n");
+      ul_config_req_UE_MAC(ul_config_req, timer_frame, timer_subframe, Mod_id);
 
-          free(ul_config_req);
-          ul_config_req = NULL;
-        } else if(ul_config_req!=NULL) {
-          free(ul_config_req);
-          ul_config_req = NULL;
-        }
+      if(ul_config_req->ul_config_request_body.ul_config_pdu_list != NULL) {
+        free(ul_config_req->ul_config_request_body.ul_config_pdu_list);
+        ul_config_req->ul_config_request_body.ul_config_pdu_list = NULL;
       }
 
-    phy_procedures_UE_SL_RX(UE,proc);
+      free(ul_config_req);
+      ul_config_req = NULL;
+    } else if(ul_config_req!=NULL) {
+      free(ul_config_req);
+      ul_config_req = NULL;
+    }
   }
-  #endif // disabled
+
+#endif // disabled
   // thread finished
   free(arg);
   return NULL; //return &UE_thread_rxtx_retval;
@@ -1938,22 +1908,21 @@ void write_dummy(PHY_VARS_UE *UE,  openair0_timestamp timestamp) {
   // we have to write to tell explicitly to the eNB, else it will wait for us forever
   // we write the next subframe (always write in future of what we received)
   //
-  struct complex16 v= {0};
+  c16_t v= {0};
   void *samplesVoid[UE->frame_parms.nb_antennas_tx];
-  
+
   for ( int i=0; i < UE->frame_parms.nb_antennas_tx; i++)
     samplesVoid[i]=(void *)&v;
-  
+
   AssertFatal( 1 == UE->rfdevice.trx_write_func(&UE->rfdevice,
-						timestamp+2*UE->frame_parms.samples_per_tti,
-						samplesVoid, 
-						1,
-						UE->frame_parms.nb_antennas_tx,
-						1),"");
+               timestamp+2*UE->frame_parms.samples_per_tti,
+               samplesVoid,
+               1,
+               UE->frame_parms.nb_antennas_tx,
+               1),"");
 }
 
-void *UE_thread(void *arg)
-{
+void *UE_thread(void *arg) {
   PHY_VARS_UE *UE = (PHY_VARS_UE *) arg;
   //  int tx_enabled = 0;
   int dummy_rx[UE->frame_parms.nb_antennas_rx][UE->frame_parms.samples_per_tti] __attribute__((aligned(32)));
@@ -1966,10 +1935,11 @@ void *UE_thread(void *arg)
   int ret;
   cpu_set_t cpuset;
   CPU_ZERO(&cpuset);
+
   if ( threads.main != -1 )
     CPU_SET(threads.main, &cpuset);
-  init_thread(100000, 500000, FIFO_PRIORITY, &cpuset, "UHD Threads");
 
+  init_thread(100000, 500000, FIFO_PRIORITY, &cpuset, "UHD Threads");
   /*
   while (sync_var<0)
     pthread_cond_wait(&sync_cond, &sync_mutex);
@@ -1996,46 +1966,45 @@ void *UE_thread(void *arg)
     int instance_cnt_synch = UE->proc.instance_cnt_synch;
     int is_synchronized    = UE->is_synchronized;
     AssertFatal ( 0== pthread_mutex_unlock(&UE->proc.mutex_synch), "");
-    
+
     if (is_synchronized == 0) {
       if (instance_cnt_synch < 0) {  // we can invoke the synch
 
-	// we shift in time flow because the UE doesn't detect sync when frame alignment is not easy
-	for (int i=0; i<UE->frame_parms.nb_antennas_rx; i++)
-            rxp[i] = (void *)&dummy_rx[i][0];
-	UE->rfdevice.trx_read_func(&UE->rfdevice,
-				   &timestamp,
-				   rxp,
-				   UE->frame_parms.samples_per_tti/2,
-				   UE->frame_parms.nb_antennas_rx);
-	
+        // we shift in time flow because the UE doesn't detect sync when frame alignment is not easy
+        for (int i=0; i<UE->frame_parms.nb_antennas_rx; i++)
+          rxp[i] = (void *)&dummy_rx[i][0];
+
+        UE->rfdevice.trx_read_func(&UE->rfdevice,
+                                   &timestamp,
+                                   rxp,
+                                   UE->frame_parms.samples_per_tti/2,
+                                   UE->frame_parms.nb_antennas_rx);
+
         // grab 10 ms of signal and wakeup synch thread
-	
-        if (UE->mode != loop_through_memory) {
-          if (IS_SOFTMODEM_RFSIM ) {
-	    for(int sf=0; sf<10; sf++) {
-	      for (int i=0; i<UE->frame_parms.nb_antennas_rx; i++)
-		rxp[i] = (void *)&UE->common_vars.rxdata[i][UE->frame_parms.samples_per_tti*sf];
-	      
-              AssertFatal(UE->frame_parms.samples_per_tti == UE->rfdevice.trx_read_func(&UE->rfdevice,
-						      &timestamp,
-						      rxp,
-						      UE->frame_parms.samples_per_tti,
-						      UE->frame_parms.nb_antennas_rx), "");
-	      write_dummy(UE, timestamp);
-	    }
-	  } else {
-	    for (int i=0; i<UE->frame_parms.nb_antennas_rx; i++)
-	      rxp[i] = (void *)&UE->common_vars.rxdata[i][0];
-	    
-	    AssertFatal( UE->frame_parms.samples_per_tti*10 ==
-                         UE->rfdevice.trx_read_func(&UE->rfdevice,
-                                                    &timestamp,
-                                                    rxp,
-                                                    UE->frame_parms.samples_per_tti*10,
-                                                    UE->frame_parms.nb_antennas_rx), "");
-	      }
-	}
+
+        if (IS_SOFTMODEM_RFSIM ) {
+          for(int sf=0; sf<10; sf++) {
+            for (int i=0; i<UE->frame_parms.nb_antennas_rx; i++)
+              rxp[i] = (void *)&UE->common_vars.rxdata[i][UE->frame_parms.samples_per_tti*sf];
+
+            AssertFatal(UE->frame_parms.samples_per_tti == UE->rfdevice.trx_read_func(&UE->rfdevice,
+                        &timestamp,
+                        rxp,
+                        UE->frame_parms.samples_per_tti,
+                        UE->frame_parms.nb_antennas_rx), "");
+            write_dummy(UE, timestamp);
+          }
+        } else {
+          for (int i=0; i<UE->frame_parms.nb_antennas_rx; i++)
+            rxp[i] = (void *)&UE->common_vars.rxdata[i][0];
+
+          AssertFatal( UE->frame_parms.samples_per_tti*10 ==
+                       UE->rfdevice.trx_read_func(&UE->rfdevice,
+                                                  &timestamp,
+                                                  rxp,
+                                                  UE->frame_parms.samples_per_tti*10,
+                                                  UE->frame_parms.nb_antennas_rx), "");
+        }
 
         AssertFatal ( 0== pthread_mutex_lock(&UE->proc.mutex_synch), "");
         instance_cnt_synch = ++UE->proc.instance_cnt_synch;
@@ -2049,69 +2018,62 @@ void *UE_thread(void *arg)
 
         AssertFatal ( 0== pthread_mutex_unlock(&UE->proc.mutex_synch), "");
       } else {
-#if OAISIM
-        (void)dummy_rx; /* avoid gcc warnings */
-        usleep(500);
-#else
         // grab 10 ms of signal into dummy buffer
-        if (UE->mode != loop_through_memory) {
-          for (int i=0; i<UE->frame_parms.nb_antennas_rx; i++)
-            rxp[i] = (void *)&dummy_rx[i][0];
-
-          for (int sf=0; sf<10; sf++) {
-            //      printf("Reading dummy sf %d\n",sf);
-            UE->rfdevice.trx_read_func(&UE->rfdevice,
-                                       &timestamp,
-                                       rxp,
-                                       UE->frame_parms.samples_per_tti,
-                                       UE->frame_parms.nb_antennas_rx);
-	    if (IS_SOFTMODEM_RFSIM )
-	      write_dummy(UE, timestamp);
-	  }
-	  }
-#endif
+        for (int i=0; i<UE->frame_parms.nb_antennas_rx; i++)
+          rxp[i] = (void *)&dummy_rx[i][0];
+
+        for (int sf=0; sf<10; sf++) {
+          //      printf("Reading dummy sf %d\n",sf);
+          UE->rfdevice.trx_read_func(&UE->rfdevice,
+                                     &timestamp,
+                                     rxp,
+                                     UE->frame_parms.samples_per_tti,
+                                     UE->frame_parms.nb_antennas_rx);
+
+          if (IS_SOFTMODEM_RFSIM )
+            write_dummy(UE, timestamp);
+        }
       }
     } // UE->is_synchronized==0
     else {
       if (start_rx_stream==0) {
         start_rx_stream=1;
 
-        if (UE->mode != loop_through_memory) {
-          if (UE->no_timing_correction==0) {
-            LOG_I(PHY,"Resynchronizing RX by %d samples (mode = %d)\n",UE->rx_offset,UE->mode);
-	    while ( UE->rx_offset ) {
-	      size_t s=min(UE->rx_offset,UE->frame_parms.samples_per_tti);
-              AssertFatal(s == UE->rfdevice.trx_read_func(&UE->rfdevice,
-						     &timestamp,
-						     (void **)UE->common_vars.rxdata,
-						     s,
-						     UE->frame_parms.nb_antennas_rx),"");
-	      if (IS_SOFTMODEM_RFSIM )
-		write_dummy(UE, timestamp);
-	      UE->rx_offset-=s;
-	    }
-          }
+        if (UE->no_timing_correction==0) {
+          LOG_I(PHY,"Resynchronizing RX by %d samples (mode = %d)\n",UE->rx_offset,UE->mode);
 
-          UE->rx_offset=0;
-          UE->time_sync_cell=0;
+          while ( UE->rx_offset ) {
+            size_t s=min(UE->rx_offset,UE->frame_parms.samples_per_tti);
+            AssertFatal(s == UE->rfdevice.trx_read_func(&UE->rfdevice,
+                        &timestamp,
+                        (void **)UE->common_vars.rxdata,
+                        s,
+                        UE->frame_parms.nb_antennas_rx),"");
 
-          //UE->proc.proc_rxtx[0].frame_rx++;
-          //UE->proc.proc_rxtx[1].frame_rx++;
-          for (th_id=0; th_id < RX_NB_TH; th_id++) {
-            UE->proc.proc_rxtx[th_id].frame_rx++;
+            if (IS_SOFTMODEM_RFSIM )
+              write_dummy(UE, timestamp);
+
+            UE->rx_offset-=s;
           }
+        }
 
-          // read in first symbol
-          AssertFatal (UE->frame_parms.ofdm_symbol_size+UE->frame_parms.nb_prefix_samples0 ==
-                       UE->rfdevice.trx_read_func(&UE->rfdevice,
-                                                  &timestamp,
-                                                  (void **)UE->common_vars.rxdata,
-                                                  UE->frame_parms.ofdm_symbol_size+UE->frame_parms.nb_prefix_samples0,
-                                                  UE->frame_parms.nb_antennas_rx),"");
-          slot_fep(UE,0, 0, 0, 0, 0);
-        } //UE->mode != loop_through_memory
-        else
-          rt_sleep_ns(1000*1000);
+        UE->rx_offset=0;
+        UE->time_sync_cell=0;
+
+        //UE->proc.proc_rxtx[0].frame_rx++;
+        //UE->proc.proc_rxtx[1].frame_rx++;
+        for (th_id=0; th_id < RX_NB_TH; th_id++) {
+          UE->proc.proc_rxtx[th_id].frame_rx++;
+        }
+
+        // read in first symbol
+        AssertFatal (UE->frame_parms.ofdm_symbol_size+UE->frame_parms.nb_prefix_samples0 ==
+                     UE->rfdevice.trx_read_func(&UE->rfdevice,
+                                                &timestamp,
+                                                (void **)UE->common_vars.rxdata,
+                                                UE->frame_parms.ofdm_symbol_size+UE->frame_parms.nb_prefix_samples0,
+                                                UE->frame_parms.nb_antennas_rx),"");
+        slot_fep(UE,0, 0, 0, 0, 0);
       } else {
         sub_frame++;
         sub_frame%=10;
@@ -2130,7 +2092,8 @@ void *UE_thread(void *arg)
 
             pthread_mutex_unlock(&proc->mutex_rxtx);
           }
-	  usleep(300);
+
+          usleep(300);
         }
 
         LOG_D(PHY,"Process Subframe %d thread Idx %d \n", sub_frame, UE->current_thread_id[sub_frame]);
@@ -2139,130 +2102,129 @@ void *UE_thread(void *arg)
         if(thread_idx>=RX_NB_TH)
           thread_idx = 0;
 
-        if (UE->mode != loop_through_memory) {
-          for (i=0; i<UE->frame_parms.nb_antennas_rx; i++)
-            rxp[i] = (void *)&UE->common_vars.rxdata[i][UE->frame_parms.ofdm_symbol_size+
-                     UE->frame_parms.nb_prefix_samples0+
-                     sub_frame*UE->frame_parms.samples_per_tti];
-
-          for (i=0; i<UE->frame_parms.nb_antennas_tx; i++)
-            txp[i] = (void *)&UE->common_vars.txdata[i][((sub_frame+2)%10)*UE->frame_parms.samples_per_tti];
+        for (i=0; i<UE->frame_parms.nb_antennas_rx; i++)
+          rxp[i] = (void *)&UE->common_vars.rxdata[i][UE->frame_parms.ofdm_symbol_size+
+                   UE->frame_parms.nb_prefix_samples0+
+                   sub_frame*UE->frame_parms.samples_per_tti];
 
-          int readBlockSize, writeBlockSize;
+        for (i=0; i<UE->frame_parms.nb_antennas_tx; i++)
+          txp[i] = (void *)&UE->common_vars.txdata[i][((sub_frame+2)%10)*UE->frame_parms.samples_per_tti];
 
-          if (sub_frame<9) {
-            readBlockSize=UE->frame_parms.samples_per_tti;
-            writeBlockSize=UE->frame_parms.samples_per_tti;
-          } else {
-            // set TO compensation to zero
-            UE->rx_offset_diff = 0;
+        int readBlockSize, writeBlockSize;
 
-            // compute TO compensation that should be applied for this frame
+        if (sub_frame<9) {
+          readBlockSize=UE->frame_parms.samples_per_tti;
+          writeBlockSize=UE->frame_parms.samples_per_tti;
+        } else {
+          // set TO compensation to zero
+          UE->rx_offset_diff = 0;
 
-            if (UE->no_timing_correction == 0) {
-              if ( UE->rx_offset < 5*UE->frame_parms.samples_per_tti  &&
-                   UE->rx_offset > 0 )
-                UE->rx_offset_diff = -1 ;
+          // compute TO compensation that should be applied for this frame
 
-              if ( UE->rx_offset > 5*UE->frame_parms.samples_per_tti &&
-                   UE->rx_offset < 10*UE->frame_parms.samples_per_tti )
-                UE->rx_offset_diff = 1;
-            }
+          if (UE->no_timing_correction == 0) {
+            if ( UE->rx_offset < 5*UE->frame_parms.samples_per_tti  &&
+                 UE->rx_offset > 0 )
+              UE->rx_offset_diff = -1 ;
 
-            LOG_D(PHY,"AbsSubframe %d.%d SET rx_off_diff to %d rx_offset %d \n",proc->frame_rx,sub_frame,UE->rx_offset_diff,UE->rx_offset);
-            readBlockSize=UE->frame_parms.samples_per_tti -
-                          UE->frame_parms.ofdm_symbol_size -
-                          UE->frame_parms.nb_prefix_samples0 -
-                          UE->rx_offset_diff;
-            writeBlockSize=UE->frame_parms.samples_per_tti -
-                           UE->rx_offset_diff;
+            if ( UE->rx_offset > 5*UE->frame_parms.samples_per_tti &&
+                 UE->rx_offset < 10*UE->frame_parms.samples_per_tti )
+              UE->rx_offset_diff = 1;
           }
 
-          AssertFatal(readBlockSize ==
-                      UE->rfdevice.trx_read_func(&UE->rfdevice,
-                                                 &timestamp,
-                                                 rxp,
-                                                 readBlockSize,
-                                                 UE->frame_parms.nb_antennas_rx),"");
-          AssertFatal( writeBlockSize ==
-                       UE->rfdevice.trx_write_func(&UE->rfdevice,
-                           timestamp+
-                           (2*UE->frame_parms.samples_per_tti) -
-                           UE->frame_parms.ofdm_symbol_size-UE->frame_parms.nb_prefix_samples0 -
-                           openair0_cfg[0].tx_sample_advance,
-                           txp,
-                           writeBlockSize,
-                           UE->frame_parms.nb_antennas_tx,
-                           1),"");
-
-          if( sub_frame==9) {
-            // read in first symbol of next frame and adjust for timing drift
-            int first_symbols=writeBlockSize-readBlockSize;
-
-            if ( first_symbols > 0 )
-              AssertFatal(first_symbols ==
-                          UE->rfdevice.trx_read_func(&UE->rfdevice,
-                                                     &timestamp1,
-                                                     (void **)UE->common_vars.rxdata,
-                                                     first_symbols,
-                                                     UE->frame_parms.nb_antennas_rx),"");
-
-            if ( first_symbols <0 )
-              LOG_E(PHY,"can't compensate: diff =%d\n", first_symbols);
-          }
+          LOG_D(PHY,"AbsSubframe %d.%d SET rx_off_diff to %d rx_offset %d \n",proc->frame_rx,sub_frame,UE->rx_offset_diff,UE->rx_offset);
+          readBlockSize=UE->frame_parms.samples_per_tti -
+                        UE->frame_parms.ofdm_symbol_size -
+                        UE->frame_parms.nb_prefix_samples0 -
+                        UE->rx_offset_diff;
+          writeBlockSize=UE->frame_parms.samples_per_tti -
+                         UE->rx_offset_diff;
+        }
 
-          /* no timeout in IS_SOFTMODEM_RFSIM mode */
-          if (IS_SOFTMODEM_RFSIM) {
-            ret = pthread_mutex_lock(&proc->mutex_rxtx);
-          } else {
-            struct timespec tv;
-            if (clock_gettime(CLOCK_REALTIME, &tv) != 0) {
-              perror("clock_gettime");
-              exit(1);
-            }
-            tv.tv_nsec += 10*1000;
-            if (tv.tv_nsec >= 1000 * 1000 * 1000) {
-              tv.tv_sec++;
-              tv.tv_nsec -= 1000 * 1000 * 1000;
-            }
-            ret = pthread_mutex_timedlock(&proc->mutex_rxtx, &tv);
+        AssertFatal(readBlockSize ==
+                    UE->rfdevice.trx_read_func(&UE->rfdevice,
+                                               &timestamp,
+                                               rxp,
+                                               readBlockSize,
+                                               UE->frame_parms.nb_antennas_rx),"");
+        AssertFatal( writeBlockSize ==
+                     UE->rfdevice.trx_write_func(&UE->rfdevice,
+                         timestamp+
+                         (2*UE->frame_parms.samples_per_tti) -
+                         UE->frame_parms.ofdm_symbol_size-UE->frame_parms.nb_prefix_samples0 -
+                         openair0_cfg[0].tx_sample_advance,
+                         txp,
+                         writeBlockSize,
+                         UE->frame_parms.nb_antennas_tx,
+                         1),"");
+
+        if( sub_frame==9) {
+          // read in first symbol of next frame and adjust for timing drift
+          int first_symbols=writeBlockSize-readBlockSize;
+
+          if ( first_symbols > 0 )
+            AssertFatal(first_symbols ==
+                        UE->rfdevice.trx_read_func(&UE->rfdevice,
+                                                   &timestamp1,
+                                                   (void **)UE->common_vars.rxdata,
+                                                   first_symbols,
+                                                   UE->frame_parms.nb_antennas_rx),"");
+
+          if ( first_symbols <0 )
+            LOG_E(PHY,"can't compensate: diff =%d\n", first_symbols);
+        }
+
+        /* no timeout in IS_SOFTMODEM_RFSIM mode */
+        if (IS_SOFTMODEM_RFSIM) {
+          ret = pthread_mutex_lock(&proc->mutex_rxtx);
+        } else {
+          struct timespec tv;
+
+          if (clock_gettime(CLOCK_REALTIME, &tv) != 0) {
+            perror("clock_gettime");
+            exit(1);
           }
 
-          // operate on thread sf mod 2
-          if (ret != 0) {
-            if (ret == ETIMEDOUT) {
-              LOG_E(PHY,"Missed real time\n");
-              continue;
-            } else {
-              LOG_E(PHY,"System error %s (%d)\n",strerror(errno),errno);
-              abort();
-            }
+          tv.tv_nsec += 10*1000;
+
+          if (tv.tv_nsec >= 1000 * 1000 * 1000) {
+            tv.tv_sec++;
+            tv.tv_nsec -= 1000 * 1000 * 1000;
           }
 
-          //          usleep(3000);
-          if(sub_frame == 0) {
-            //UE->proc.proc_rxtx[0].frame_rx++;
-            //UE->proc.proc_rxtx[1].frame_rx++;
-            for (th_id=0; th_id < RX_NB_TH; th_id++) {
-              UE->proc.proc_rxtx[th_id].frame_rx++;
-            }
+          ret = pthread_mutex_timedlock(&proc->mutex_rxtx, &tv);
+        }
+
+        // operate on thread sf mod 2
+        if (ret != 0) {
+          if (ret == ETIMEDOUT) {
+            LOG_E(PHY,"Missed real time\n");
+            continue;
+          } else {
+            LOG_E(PHY,"System error %s (%d)\n",strerror(errno),errno);
+            abort();
           }
+        }
 
-          proc->subframe_rx=sub_frame;
-          proc->subframe_tx=(sub_frame+4)%10;
-          proc->frame_tx = proc->frame_rx + (proc->subframe_rx>5?1:0);
-          proc->timestamp_tx = timestamp+
-                               (4*UE->frame_parms.samples_per_tti)-
-                               UE->frame_parms.ofdm_symbol_size-UE->frame_parms.nb_prefix_samples0;
-          proc->instance_cnt_rxtx++;
-          LOG_D( PHY, "[SCHED][UE %d] UE RX instance_cnt_rxtx %d subframe %d !!\n", UE->Mod_id, proc->instance_cnt_rxtx,proc->subframe_rx);
-          T(T_UE_MASTER_TICK, T_INT(0), T_INT(proc->frame_rx%1024), T_INT(proc->subframe_rx));
-          AssertFatal (pthread_cond_signal(&proc->cond_rxtx) ==0,"");
-          AssertFatal(pthread_mutex_unlock(&proc->mutex_rxtx) ==0,"");
-        } else {
-          printf("Processing subframe %d",proc->subframe_rx);
-          getchar();
+        //          usleep(3000);
+        if(sub_frame == 0) {
+          //UE->proc.proc_rxtx[0].frame_rx++;
+          //UE->proc.proc_rxtx[1].frame_rx++;
+          for (th_id=0; th_id < RX_NB_TH; th_id++) {
+            UE->proc.proc_rxtx[th_id].frame_rx++;
+          }
         }
+
+        proc->subframe_rx=sub_frame;
+        proc->subframe_tx=(sub_frame+4)%10;
+        proc->frame_tx = proc->frame_rx + (proc->subframe_rx>5?1:0);
+        proc->timestamp_tx = timestamp+
+                             (4*UE->frame_parms.samples_per_tti)-
+                             UE->frame_parms.ofdm_symbol_size-UE->frame_parms.nb_prefix_samples0;
+        proc->instance_cnt_rxtx++;
+        LOG_D( PHY, "[SCHED][UE %d] UE RX instance_cnt_rxtx %d subframe %d !!\n", UE->Mod_id, proc->instance_cnt_rxtx,proc->subframe_rx);
+        T(T_UE_MASTER_TICK, T_INT(0), T_INT(proc->frame_rx%1024), T_INT(proc->subframe_rx));
+        AssertFatal (pthread_cond_signal(&proc->cond_rxtx) ==0,"");
+        AssertFatal(pthread_mutex_unlock(&proc->mutex_rxtx) ==0,"");
       } // start_rx_stream==1
     } // UE->is_synchronized==1
   } // while !oai_exit
@@ -2283,8 +2245,7 @@ void *UE_thread(void *arg)
  * - UE_thread_dlsch_proc_slot1
  * and the locking between them.
  */
-void init_UE_threads(int inst)
-{
+void init_UE_threads(int inst) {
   struct rx_tx_thread_data *rtd;
   PHY_VARS_UE *UE;
   AssertFatal(PHY_vars_UE_g!=NULL,"PHY_vars_UE_g is NULL\n");
@@ -2339,8 +2300,7 @@ void init_UE_threads(int inst)
  * - UE_thread_dlsch_proc_slot1
  * and the locking between them.
  */
-void init_UE_single_thread_stub(int nb_inst)
-{
+void init_UE_single_thread_stub(int nb_inst) {
   struct rx_tx_thread_data *rtd;
   PHY_VARS_UE *UE;
 
@@ -2368,8 +2328,8 @@ void init_UE_single_thread_stub(int nb_inst)
   // In phy_stub_UE mode due to less heavy processing operations we don't need two threads
   //int nb_threads=RX_NB_TH;
   int nb_threads=1;
+  void *(*task_func)(void *);
 
-  void* (*task_func)(void*);
   if (NFAPI_MODE == NFAPI_MODE_STANDALONE_PNF) {
     task_func = UE_phy_stub_standalone_pnf_task;
   } else {
@@ -2413,8 +2373,7 @@ void init_UE_single_thread_stub(int nb_inst)
  * - UE_thread_dlsch_proc_slot1
  * and the locking between them.
  */
-void init_UE_threads_stub(int inst)
-{
+void init_UE_threads_stub(int inst) {
   struct rx_tx_thread_data *rtd;
   PHY_VARS_UE *UE;
   AssertFatal(PHY_vars_UE_g!=NULL,"PHY_vars_UE_g is NULL\n");
@@ -2451,8 +2410,7 @@ void init_UE_threads_stub(int inst)
 }
 
 
-void fill_ue_band_info(void)
-{
+void fill_ue_band_info(void) {
   LTE_UE_EUTRA_Capability_t *UE_EUTRA_Capability = UE_rrc_inst[0].UECap->UE_EUTRA_Capability;
   int i,j;
   bands_to_scan.nbands = UE_EUTRA_Capability->rf_Parameters.supportedBandListEUTRA.list.count;
@@ -2477,8 +2435,7 @@ void fill_ue_band_info(void)
 }
 
 int setup_ue_buffers(PHY_VARS_UE **phy_vars_ue,
-                     openair0_config_t *openair0_cfg)
-{
+                     openair0_config_t *openair0_cfg) {
   int i, CC_id;
   LTE_DL_FRAME_PARMS *frame_parms;
 
@@ -2486,23 +2443,18 @@ int setup_ue_buffers(PHY_VARS_UE **phy_vars_ue,
     AssertFatal( phy_vars_ue[CC_id] !=0, "");
     frame_parms = &(phy_vars_ue[CC_id]->frame_parms);
     // replace RX signal buffers with mmaped HW versions
-    rxdata = (int32_t **)malloc16( frame_parms->nb_antennas_rx*sizeof(int32_t *) );
-    txdata = (int32_t **)malloc16( frame_parms->nb_antennas_tx*sizeof(int32_t *) );
-
     for (i=0; i<frame_parms->nb_antennas_rx; i++) {
       LOG_I(PHY, "Mapping UE CC_id %d, rx_ant %d, freq %lu on card %d, chain %d\n",
             CC_id, i, downlink_frequency[CC_id][i], phy_vars_ue[CC_id]->rf_map.card, (phy_vars_ue[CC_id]->rf_map.chain)+i );
       free( phy_vars_ue[CC_id]->common_vars.rxdata[i] );
-      rxdata[i] = (int32_t *)malloc16_clear( 307200*sizeof(int32_t) );
-      phy_vars_ue[CC_id]->common_vars.rxdata[i] = rxdata[i]; // what about the "-N_TA_offset" ? // N_TA offset for TDD
+      phy_vars_ue[CC_id]->common_vars.rxdata[i] = malloc16_clear( 307200*sizeof(int32_t) ); // what about the "-N_TA_offset" ? // N_TA offset for TDD
     }
 
     for (i=0; i<frame_parms->nb_antennas_tx; i++) {
       LOG_I(PHY, "Mapping UE CC_id %d, tx_ant %d, freq %lu on card %d, chain %d\n",
             CC_id, i, downlink_frequency[CC_id][i], phy_vars_ue[CC_id]->rf_map.card, (phy_vars_ue[CC_id]->rf_map.chain)+i );
       free( phy_vars_ue[CC_id]->common_vars.txdata[i] );
-      txdata[i] = (int32_t *)malloc16_clear( 307200*sizeof(int32_t) );
-      phy_vars_ue[CC_id]->common_vars.txdata[i] = txdata[i];
+      phy_vars_ue[CC_id]->common_vars.txdata[i] = malloc16_clear( 307200*sizeof(int32_t) );
     }
 
     // rxdata[x] points now to the same memory region as phy_vars_ue[CC_id]->common_vars.rxdata[x]
@@ -2520,8 +2472,7 @@ int setup_ue_buffers(PHY_VARS_UE **phy_vars_ue,
 // playing the role of nfapi-pnf.
 
 //02/02/2018
-static void *timer_thread( void *param )
-{
+static void *timer_thread( void *param ) {
   thread_top_init("timer_thread",1,870000L,1000000L,1000000L);
   timer_subframe =9;
   timer_frame    =1023;
@@ -2647,8 +2598,7 @@ static void *timer_thread( void *param )
 }
 
 
-int init_timer_thread(void)
-{
+int init_timer_thread(void) {
   //PHY_VARS_UE *UE=PHY_vars_UE_g[0];
   PHY_VARS_UE *UE=PHY_vars_UE_g[0][0];
   phy_stub_ticking = (SF_ticking *)malloc(sizeof(SF_ticking));
@@ -2670,8 +2620,7 @@ int init_timer_thread(void)
  */
 int8_t find_dlsch(uint16_t rnti,
                   PHY_VARS_eNB *eNB,
-                  find_type_t type)
-{
+                  find_type_t type) {
   printf("you cannot read this\n");
   abort();
 }
diff --git a/targets/RT/USER/lte-uesoftmodem.c b/targets/RT/USER/lte-uesoftmodem.c
index 8cdef647cab5063722aaccf0d3ccbe938677e6ef..089941c7dfc0de799960b9206bf2f771e5564e11 100644
--- a/targets/RT/USER/lte-uesoftmodem.c
+++ b/targets/RT/USER/lte-uesoftmodem.c
@@ -276,7 +276,6 @@ uint16_t node_number;
 static void get_options(void) {
   int CC_id=0;
   int tddflag=0;
-  char *loopfile=NULL;
   int dumpframe=0;
   int timingadv=0;
   uint8_t nfapi_mode = NFAPI_MONOLITHIC;
@@ -293,14 +292,6 @@ static void get_options(void) {
   config_process_cmdline( cmdline_ueparams,sizeof(cmdline_ueparams)/sizeof(paramdef_t),NULL);
   nfapi_setmode(nfapi_mode);
 
-
-  if (loopfile != NULL) {
-    printf("Input file for hardware emulation: %s",loopfile);
-    mode=loop_through_memory;
-    input_fd = fopen(loopfile,"r");
-    AssertFatal(input_fd != NULL,"Please provide a valid input file\n");
-  }
-
   get_softmodem_params()->hw_timing_advance = timingadv;
 
   if ( (cmdline_uemodeparams[CMDLINE_CALIBUERX_IDX].paramflags &  PARAMFLAG_PARAMSET) != 0) mode = rx_calib_ue;