diff --git a/ci-scripts/Jenkinsfile-GitLab-Container b/ci-scripts/Jenkinsfile-GitLab-Container
index f5852bace54c2773d4fbe3eda0bb7be2f9cff3f0..c22e6fabec717bc8f889846ee04c4cc3bcee9916 100644
--- a/ci-scripts/Jenkinsfile-GitLab-Container
+++ b/ci-scripts/Jenkinsfile-GitLab-Container
@@ -222,7 +222,7 @@ pipeline {
           when { expression {doMandatoryTests} }
           steps {
             script {
-              triggerSlaveJob ('RAN-RF-Sim-Test-5G', 'Test-RF-Sim-Container-4G')
+              triggerSlaveJob ('RAN-RF-Sim-Test-5G', 'Test-RF-Sim-Container-5G')
             }
           }
           post {
@@ -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 91d6136e0a55824cff05cc10f36419e815a6dfb0..f5847ff0aab2e45adee158f8f5d8fceda735f209 100644
--- a/ci-scripts/Jenkinsfile-push-registry
+++ b/ci-scripts/Jenkinsfile-push-registry
@@ -55,7 +55,9 @@ pipeline {
     stage ("Push to DockerHub") {
       steps {
         script {
-          WEEK_TAG = sh returnStdout: true, script: 'date +"%Y.w%U"'
+          WEEK_REF = sh returnStdout: true, script: 'date +"%Y.w%V"'
+          WEEK_REF = WEEK_REF.trim()
+          WEEK_TAG = sh returnStdout: true, script: 'python3 ./ci-scripts/provideUniqueImageTag.py --start_tag ' + WEEK_REF
           WEEK_TAG = WEEK_TAG.trim()
 
           withCredentials([
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/ci_ueinfra.yaml b/ci-scripts/ci_ueinfra.yaml
index 0a915740f243cbb114120ed6971140ee7c3e5ee6..89bda5fa920008349644726ab08146ceee7631d9 100644
--- a/ci-scripts/ci_ueinfra.yaml
+++ b/ci-scripts/ci_ueinfra.yaml
@@ -39,6 +39,53 @@ nrmodule2_quectel:
   StartCommands :
     - sudo -S ip link set dev wwan1 mtu 1500
   MTU : 1500
+
+#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 : ''
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 fdc2bc1597078728190e669bf71e39e14b824f04..8092febe39666ada6ac15a5c49a8e8af8e69708e 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 = ''
@@ -606,6 +607,8 @@ class Containerize():
 		if containerToKill:
 			mySSH.command('docker kill --signal INT ' + containerName, '\$', 30)
 			time.sleep(5)
+			mySSH.command('docker kill --signal KILL ' + containerName, '\$', 30)
+			time.sleep(5)
 			mySSH.command('docker logs ' + containerName + ' > ' + lSourcePath + '/cmake_targets/' + self.eNB_logFile[self.eNB_instance], '\$', 30)
 			mySSH.command('docker rm -f ' + containerName, '\$', 30)
 		# Forcing the down now to remove the networks and any artifacts
@@ -680,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:
@@ -696,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')
@@ -721,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('/')
@@ -779,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)
@@ -849,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)
@@ -861,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('/')
diff --git a/ci-scripts/cls_module_ue.py b/ci-scripts/cls_module_ue.py
index cabd0a045de63385c7a0cc159b2e536fe06f0855..fb107007980d53059da297e06bcb396a80922480 100644
--- a/ci-scripts/cls_module_ue.py
+++ b/ci-scripts/cls_module_ue.py
@@ -76,7 +76,8 @@ class Module_UE:
 			logging.debug('Starting ' + self.Process['Name'])
 			mySSH = sshconnection.SSHConnection()
 			mySSH.open(self.HostIPAddress, self.HostUsername, self.HostPassword)
-			mySSH.command('echo $USER; echo ' + self.HostPassword + ' | nohup sudo -S ' + self.Process['Cmd'] + ' ' +  self.Process['Apn'][CNType]  + ' > /dev/null 2>&1 &','\$',5)
+			mySSH.command('echo ' + self.HostPassword + ' | sudo -S rm -f /tmp/quectel-cm.log','\$',5)
+			mySSH.command('echo $USER; echo ' + self.HostPassword + ' | nohup sudo -S stdbuf -o0 ' + self.Process['Cmd'] + ' ' +  self.Process['Apn'][CNType]  + ' > /tmp/quectel-cm.log 2>&1 &','\$',5)
 			mySSH.close()
 			#checking the process
 			time.sleep(5)
diff --git a/ci-scripts/cls_oaicitest.py b/ci-scripts/cls_oaicitest.py
index 5d89a7b2e0bdac3c4bb442d1695d93c0cefdd173..33910f1f9bd5dbe8ebe0e025d1745c9a3d61baba 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)
@@ -122,6 +123,7 @@ def GetPingTimeAnalysis(RAN,ping_log_file,ping_rttavg_threshold):
 		try:
 			mySSH = sshconnection.SSHConnection()
 			mySSH.copyout(RAN.eNBIPAddress, RAN.eNBUserName, RAN.eNBPassword, ping_log_file+'.png', RAN.eNBSourceCodePath + '/cmake_targets/')
+			mySSH.copyout(RAN.eNBIPAddress, RAN.eNBUserName, RAN.eNBPassword, ping_log_file, RAN.eNBSourceCodePath + '/cmake_targets/')
 		except:
 			logging.debug('\u001B[1;37;41m Ping PNG SCP to eNB FAILED\u001B[0m')
 
@@ -418,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)
-
-				# 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")
+		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(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
 
-				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):
@@ -534,7 +550,7 @@ class OaiCiTest():
 		while (doOutterLoop):
 			SSH.command('cd ' + self.UESourceCodePath + '/cmake_targets/ran_build/build', '\$', 5)
 			SSH.command('echo ' + self.UEPassword + ' | sudo -S rm -Rf ' + self.UESourceCodePath + '/cmake_targets/ue_' + self.testCase_id + '.log', '\$', 5)
-			SSH.command('echo $USER; nohup sudo -E ./my-lte-uesoftmodem-run' + str(self.UE_instance) + '.sh' + ' > ' + self.UESourceCodePath + '/cmake_targets/ue_' + self.testCase_id + '.log ' + ' 2>&1 &', self.UEUserName, 5)
+			SSH.command('echo $USER; nohup sudo -E stdbuf -o0 ./my-lte-uesoftmodem-run' + str(self.UE_instance) + '.sh' + ' > ' + self.UESourceCodePath + '/cmake_targets/ue_' + self.testCase_id + '.log ' + ' 2>&1 &', self.UEUserName, 5)
 			time.sleep(6)
 			SSH.command('cd ../..', '\$', 5)
 			doLoop = True
@@ -1569,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)
@@ -1596,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 + ' 2>&1 > ping_' + self.testCase_id + '_' + device_id + '.log' 
+					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')
@@ -1613,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):
@@ -1623,15 +1647,29 @@ class OaiCiTest():
 					else:
 						Target = EPC.IPAddress
 					#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  + ' 2>&1 > ping_' + self.testCase_id + '_' + self.ue_id + '.log' 
+					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:
@@ -1679,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')
@@ -1728,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):
@@ -1855,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
@@ -1870,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()
@@ -2084,7 +2136,8 @@ class OaiCiTest():
 			statusQueue.put(UE_IPAddress)
 			statusQueue.put(report_msg)
 			logging.debug('\u001B[1;37;45m TCP Bidir Iperf Result (' + UE_IPAddress + ') \u001B[0m')
-			logging.debug('\u001B[1;35m    ' + report_msg + '\u001B[0m')
+			for rLine in report_msg.split('\n'):
+				logging.debug('\u001B[1;35m    ' + rLine + '\u001B[0m')
 			lock.release()
 		else:
 			self.ping_iperf_wrong_exit(lock, UE_IPAddress, device_id, statusQueue, 'Bidir TCP : Could not analyze from Log file')
@@ -2379,10 +2432,12 @@ class OaiCiTest():
 			SSH.copyout(EPC.IPAddress, EPC.UserName, EPC.Password, 'iperf_' + self.testCase_id + '_' + device_id + '.log', EPC.SourceCodePath + '/scripts')
 
 
-	def Iperf_Module(self, lock, UE_IPAddress, device_id, idx, ue_num, statusQueue,EPC, Module_UE):
+	def Iperf_Module(self, lock, UE_IPAddress, device_id, idx, ue_num, statusQueue,EPC, Module_UE, RAN):
+		SSH = sshconnection.SSHConnection()
+		server_filename = 'iperf_server_' + self.testCase_id + '_' + self.ue_id + '.log'
+		client_filename = 'iperf_client_' + self.testCase_id + '_' + self.ue_id + '.log'
 		if (re.match('OAI-Rel14-Docker', EPC.Type, re.IGNORECASE)) or (re.match('OAICN5G', EPC.Type, re.IGNORECASE)):
 			#retrieve trf-gen container IP address
-			SSH = sshconnection.SSHConnection()
 			SSH.open(EPC.IPAddress, EPC.UserName, EPC.Password)
 			SSH.command('docker inspect --format="TRF_IP_ADDR = {{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}" prod-trf-gen', '\$', 5)
 			result = re.search('TRF_IP_ADDR = (?P<trf_ip_addr>[0-9\.]+)', SSH.getBefore())
@@ -2404,20 +2459,18 @@ class OaiCiTest():
 			if self.iperf_direction=="DL":
 				logging.debug("Iperf for Module in DL mode detected")
 				##server side UE
-				server_filename='iperf_server_' + self.testCase_id + '_' + self.ue_id + '.log'
 				SSH.open(Module_UE.HostIPAddress, Module_UE.HostUsername, Module_UE.HostPassword)
 				cmd = 'rm ' + server_filename
 				SSH.command(cmd,'\$',5)
-				cmd = 'echo $USER; nohup iperf -s -B ' + UE_IPAddress + ' -u 2>&1 > ' + server_filename + ' &'
+				cmd = 'echo $USER; nohup iperf -s -B ' + UE_IPAddress + ' -u -i 1 > ' + server_filename + ' 2>&1 &'
 				SSH.command(cmd,'\$',5)
 				SSH.close()
 				##client side EPC
 				SSH.open(EPC.IPAddress, EPC.UserName, EPC.Password)
-				client_filename = 'iperf_client_' + self.testCase_id + '_' + self.ue_id + '.log'
 				#remove old client file in EPC.SourceCodePath
 				cmd = 'rm ' + EPC.SourceCodePath + '/' + client_filename 
 				SSH.command(cmd,'\$',5)
-				iperf_cmd = 'bin/iperf -c ' + UE_IPAddress + ' ' + self.iperf_args + ' 2>&1 > ' + client_filename
+				iperf_cmd = 'bin/iperf -c ' + UE_IPAddress + ' ' + self.iperf_args + ' > ' + client_filename + ' 2>&1'
 				cmd = 'docker exec -w /iperf-2.0.13 -it prod-trf-gen /bin/bash -c \"' + iperf_cmd + '\"' 
 				SSH.command(cmd,'\$',int(iperf_time)*5.0)
 				SSH.command('docker cp prod-trf-gen:/iperf-2.0.13/'+ client_filename + ' ' + EPC.SourceCodePath, '\$', 5)
@@ -2433,19 +2486,17 @@ class OaiCiTest():
 				logging.debug("Iperf for Module in UL mode detected")
 				#server side EPC
 				SSH.open(EPC.IPAddress, EPC.UserName, EPC.Password)
-				server_filename = 'iperf_server_' + self.testCase_id + '_' + self.ue_id + '.log'
 
-				iperf_cmd = 'echo $USER; nohup bin/iperf -s -u 2>&1 > ' + server_filename
+				iperf_cmd = 'echo $USER; nohup bin/iperf -s -u -i 1 > ' + server_filename + ' 2>&1'
 				cmd = 'docker exec -d -w /iperf-2.0.13 prod-trf-gen /bin/bash -c \"' + iperf_cmd + '\"' 
 				SSH.command(cmd,'\$',5)
 				SSH.close()
 
 				#client side UE
 				SSH.open(Module_UE.HostIPAddress, Module_UE.HostUsername, Module_UE.HostPassword)
-				client_filename = 'iperf_client_' + self.testCase_id + '_' + self.ue_id + '.log'
 				cmd = 'rm '+ client_filename
 				SSH.command(cmd,'\$',5)
-				SSH.command('iperf -B ' + UE_IPAddress + ' -c ' +  trf_gen_IP + ' '  + self.iperf_args + ' 2>&1 > ' + client_filename, '\$', int(iperf_time)*5.0)
+				SSH.command('iperf -B ' + UE_IPAddress + ' -c ' +  trf_gen_IP + ' '  + self.iperf_args + ' > ' + client_filename + ' 2>&1', '\$', int(iperf_time)*5.0)
 				SSH.close()
 
 				#once client is done, retrieve the server file from container to EPC Host
@@ -2461,12 +2512,10 @@ class OaiCiTest():
 
 			elif self.iperf_direction=="BIDIR":
 				logging.debug("Iperf for Module in BIDIR mode detected")
-				server_filename = 'iperf_server_' + self.testCase_id + '_' + self.ue_id + '.log'
-				client_filename = 'iperf_client_' + self.testCase_id + '_' + self.ue_id + '.log'
 
 				#server side EPC
 				SSH.open(EPC.IPAddress, EPC.UserName, EPC.Password)
-				iperf_cmd = 'echo $USER; nohup /usr/local/bin/iperf3 -s 2>&1 > ' + server_filename
+				iperf_cmd = 'echo $USER; nohup /usr/local/bin/iperf3 -s -i 1 > ' + server_filename + ' 2>&1'
 				cmd = 'docker exec -d -w /iperf-2.0.13 prod-trf-gen /bin/bash -c \"' + iperf_cmd + '\"' 
 				SSH.command(cmd,'\$',5)
 				SSH.close()
@@ -2475,7 +2524,7 @@ class OaiCiTest():
 				SSH.open(Module_UE.HostIPAddress, Module_UE.HostUsername, Module_UE.HostPassword)
 				cmd = 'rm '+ client_filename
 				SSH.command(cmd,'\$',5)
-				SSH.command('iperf3 -B ' + UE_IPAddress + ' -c ' +  trf_gen_IP + ' '  + self.iperf_args + ' 2>&1 > ' + client_filename, '\$', int(iperf_time)*5.0)
+				SSH.command('iperf3 -B ' + UE_IPAddress + ' -c ' +  trf_gen_IP + ' '  + self.iperf_args + ' > ' + client_filename + ' 2>&1', '\$', int(iperf_time)*5.0)
 				SSH.close()
 
 				#once client is done, retrieve the server file from container to EPC Host
@@ -2499,8 +2548,6 @@ class OaiCiTest():
 
 		else: 		#default is ltebox
 
-			SSH = sshconnection.SSHConnection()
-
 			#kill iperf processes before (in case there are still some remaining)
 			SSH.open(Module_UE.HostIPAddress, Module_UE.HostUsername, Module_UE.HostPassword)
 			cmd = 'killall --signal=SIGKILL iperf'
@@ -2524,14 +2571,14 @@ class OaiCiTest():
 				SSH.open(Module_UE.HostIPAddress, Module_UE.HostUsername, Module_UE.HostPassword)
 				cmd = 'rm iperf_server_' +  self.testCase_id + '_' + self.ue_id + '.log'
 				SSH.command(cmd,'\$',5)
-				cmd = 'echo $USER; nohup /opt/iperf-2.0.10/iperf -s -B ' + UE_IPAddress + ' -u 2>&1 > iperf_server_' + self.testCase_id + '_' + self.ue_id + '.log &' 
+				cmd = 'echo $USER; nohup /opt/iperf-2.0.10/iperf -s -B ' + UE_IPAddress + ' -u -i 1 > iperf_server_' + self.testCase_id + '_' + self.ue_id + '.log 2>&1 &' 
 				SSH.command(cmd,'\$',5)
 				SSH.close()
 				#client side EPC
 				SSH.open(EPC.IPAddress, EPC.UserName, EPC.Password)
 				cmd = 'rm iperf_client_' + self.testCase_id + '_' + self.ue_id + '.log'
 				SSH.command(cmd,'\$',5)
-				cmd = 'iperf -c ' + UE_IPAddress + ' ' + self.iperf_args + ' 2>&1 > iperf_client_' + self.testCase_id + '_' + self.ue_id + '.log' 
+				cmd = 'iperf -c ' + UE_IPAddress + ' ' + self.iperf_args + ' > iperf_client_' + self.testCase_id + '_' + self.ue_id + '.log 2>&1' 
 				SSH.command(cmd,'\$',int(iperf_time)*5.0)
 				SSH.close()
 				#copy the 2 resulting files locally
@@ -2547,7 +2594,7 @@ class OaiCiTest():
 				SSH.open(EPC.IPAddress, EPC.UserName, EPC.Password)
 				cmd = 'rm iperf_server_' + self.testCase_id + '_' + self.ue_id + '.log'
 				SSH.command(cmd,'\$',5)
-				cmd = 'echo $USER; nohup iperf -s -u 2>&1 > iperf_server_' + self.testCase_id + '_' + self.ue_id + '.log  &'
+				cmd = 'echo $USER; nohup iperf -s -u -i 1 > iperf_server_' + self.testCase_id + '_' + self.ue_id + '.log 2>&1 &'
 				SSH.command(cmd,'\$',5)
 				SSH.close()
 
@@ -2555,7 +2602,7 @@ class OaiCiTest():
 				SSH.open(Module_UE.HostIPAddress, Module_UE.HostUsername, Module_UE.HostPassword)
 				cmd = 'rm iperf_client_' + self.testCase_id + '_' + self.ue_id + '.log'
 				SSH.command(cmd,'\$',5)
-				SSH.command('/opt/iperf-2.0.10/iperf -c 192.172.0.1 ' + self.iperf_args + ' 2>&1 > iperf_client_' + self.testCase_id + '_' + self.ue_id + '.log', '\$', int(iperf_time)*5.0)
+				SSH.command('/opt/iperf-2.0.10/iperf -c 192.172.0.1 ' + self.iperf_args + ' > iperf_client_' + self.testCase_id + '_' + self.ue_id + '.log 2>&1', '\$', int(iperf_time)*5.0)
 				SSH.close()
 
 				#copy the 2 resulting files locally
@@ -2566,15 +2613,13 @@ class OaiCiTest():
 				self.Iperf_analyzeV2Server(lock, UE_IPAddress, device_id, statusQueue, self.iperf_args,filename,1)
 			elif self.iperf_direction=="BIDIR":
 				logging.debug("Iperf for Module in BIDIR mode detected")
-				server_filename = 'iperf_server_' + self.testCase_id + '_' + self.ue_id + '.log'
-				client_filename = 'iperf_client_' + self.testCase_id + '_' + self.ue_id + '.log'
 
 
 				#server side EPC
 				SSH.open(EPC.IPAddress, EPC.UserName, EPC.Password)
 				cmd = 'rm ' + server_filename
 				SSH.command(cmd,'\$',5)
-				cmd = 'echo $USER; nohup iperf3 -s 2>&1 > '+server_filename+' &'
+				cmd = 'echo $USER; nohup iperf3 -s -i 1 > '+server_filename+' 2>&1 &'
 				SSH.command(cmd,'\$',5)
 				SSH.close()
 
@@ -2582,7 +2627,7 @@ class OaiCiTest():
 				SSH.open(Module_UE.HostIPAddress, Module_UE.HostUsername, Module_UE.HostPassword)
 				cmd = 'rm ' + client_filename
 				SSH.command(cmd,'\$',5)
-				SSH.command('iperf3 -c 192.172.0.1 ' + self.iperf_args + ' 2>&1 > '+client_filename, '\$', int(iperf_time)*5.0)
+				SSH.command('iperf3 -c 192.172.0.1 ' + self.iperf_args + ' > '+client_filename + ' 2>&1', '\$', int(iperf_time)*5.0)
 				SSH.close()
 
 				#copy the 2 resulting files locally
@@ -2593,6 +2638,7 @@ class OaiCiTest():
 			else :
 				logging.debug("Incorrect or missing IPERF direction in XML")
 
+
 			#kill iperf processes after to be clean
 			SSH.open(Module_UE.HostIPAddress, Module_UE.HostUsername, Module_UE.HostPassword)
 			cmd = 'killall --signal=SIGKILL iperf'
@@ -2606,7 +2652,12 @@ class OaiCiTest():
 			cmd = 'killall --signal=SIGKILL iperf3'
 			SSH.command(cmd,'\$',5)
 			SSH.close()
-			return
+
+		# Copying to xNB server for Jenkins artifacting
+		if (os.path.isfile(server_filename)):
+			SSH.copyout(RAN.eNBIPAddress, RAN.eNBUserName, RAN.eNBPassword, server_filename, RAN.eNBSourceCodePath + '/cmake_targets/')
+		if (os.path.isfile(client_filename)):
+			SSH.copyout(RAN.eNBIPAddress, RAN.eNBUserName, RAN.eNBPassword, client_filename, RAN.eNBSourceCodePath + '/cmake_targets/')
 
 	def Iperf_common(self, lock, UE_IPAddress, device_id, idx, ue_num, statusQueue,EPC):
 		try:
@@ -2804,12 +2855,12 @@ class OaiCiTest():
 				else:
 					SSH.copyin(self.ADBIPAddress, self.ADBUserName, self.ADBPassword, EPC.SourceCodePath + '/scripts/iperf_server_' + self.testCase_id + '_' + device_id + '.log', '.')
 				# fromdos has to be called on the python executor not on ADB server
-				cmd = 'fromdos -o iperf_server_' + self.testCase_id + '_' + device_id + '.log 2>&1 > /dev/null'
+				cmd = 'fromdos -o iperf_server_' + self.testCase_id + '_' + device_id + '.log > /dev/null 2>&1'
 				try:
 					subprocess.run(cmd, shell=True)
 				except:
 					pass
-				cmd = 'dos2unix -o iperf_server_' + self.testCase_id + '_' + device_id + '.log 2>&1 > /dev/null'
+				cmd = 'dos2unix -o iperf_server_' + self.testCase_id + '_' + device_id + '.log > /dev/null 2>&1'
 				try:
 					subprocess.run(cmd, shell=True)
 				except:
@@ -2995,7 +3046,7 @@ class OaiCiTest():
         	#special quick and dirty treatment for modules, iperf to be restructured
 			if self.ue_id!="": #is module
 				device_id = Module_UE.ID + "-" + Module_UE.Kind
-				p = Process(target = self.Iperf_Module ,args = (lock, UE_IPAddress, device_id, i, ue_num, status_queue, EPC, Module_UE,))
+				p = Process(target = self.Iperf_Module ,args = (lock, UE_IPAddress, device_id, i, ue_num, status_queue, EPC, Module_UE, RAN, ))
 			else: #legacy code
 				p = Process(target = self.Iperf_common, args = (lock, UE_IPAddress, device_id, i, ue_num, status_queue, EPC, ))
 			p.daemon = True
@@ -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_static_code_analysis.py b/ci-scripts/cls_static_code_analysis.py
index c899a9aabd678d8a0e107197a2e6f49e070ceb34..d6796ad414e1577e0c9d233e322e46f570f8838f 100644
--- a/ci-scripts/cls_static_code_analysis.py
+++ b/ci-scripts/cls_static_code_analysis.py
@@ -35,6 +35,7 @@ import sys              # arg
 import re               # reg
 import logging
 import os
+from pathlib import Path
 import time
 
 #-----------------------------------------------------------
@@ -51,7 +52,7 @@ class CppCheckResults():
 
 	def __init__(self):
 
-		self.variants = ['xenial', 'bionic']
+		self.variants = ['bionic', 'focal']
 		self.versions = ['','']
 		self.nbErrors = [0,0]
 		self.nbWarnings = [0,0]
@@ -116,12 +117,22 @@ class StaticCodeAnalysis():
 		# if the commit ID is provided use it to point to it
 		if self.ranCommitID != '':
 			mySSH.command('git checkout -f ' + self.ranCommitID, '\$', 30)
-
-		mySSH.command('docker image rm oai-cppcheck:bionic oai-cppcheck:xenial || true', '\$', 60)
-		mySSH.command('docker build --tag oai-cppcheck:xenial --file ci-scripts/docker/Dockerfile.cppcheck.xenial . > cmake_targets/log/cppcheck-xenial.txt 2>&1', '\$', 600)
+		# if the branch is not develop, then it is a merge request and we need to do
+		# the potential merge. Note that merge conflicts should already been checked earlier
+		if (self.ranAllowMerge):
+			if self.ranTargetBranch == '':
+				if (self.ranBranch != 'develop') and (self.ranBranch != 'origin/develop'):
+					mySSH.command('git merge --ff origin/develop -m "Temporary merge for CI"', '\$', 5)
+			else:
+				logging.debug('Merging with the target branch: ' + self.ranTargetBranch)
+				mySSH.command('git merge --ff origin/' + self.ranTargetBranch + ' -m "Temporary merge for CI"', '\$', 5)
+
+		mySSH.command('docker image rm oai-cppcheck:bionic oai-cppcheck:focal || true', '\$', 60)
 		mySSH.command('sed -e "s@xenial@bionic@" ci-scripts/docker/Dockerfile.cppcheck.xenial > ci-scripts/docker/Dockerfile.cppcheck.bionic', '\$', 6)
 		mySSH.command('docker build --tag oai-cppcheck:bionic --file ci-scripts/docker/Dockerfile.cppcheck.bionic . > cmake_targets/log/cppcheck-bionic.txt 2>&1', '\$', 600)
-		mySSH.command('docker image rm oai-cppcheck:bionic oai-cppcheck:xenial || true', '\$', 30)
+		mySSH.command('sed -e "s@xenial@focal@" ci-scripts/docker/Dockerfile.cppcheck.xenial > ci-scripts/docker/Dockerfile.cppcheck.focal', '\$', 6)
+		mySSH.command('docker build --tag oai-cppcheck:focal --file ci-scripts/docker/Dockerfile.cppcheck.focal . > cmake_targets/log/cppcheck-focal.txt 2>&1', '\$', 600)
+		mySSH.command('docker image rm oai-cppcheck:bionic oai-cppcheck:focal || true', '\$', 30)
 
 		# Analyzing the logs
 		mySSH.command('cd ' + lSourcePath + '/cmake_targets', '\$', 5)
@@ -131,8 +142,22 @@ class StaticCodeAnalysis():
 
 		mySSH.copyin(lIpAddr, lUserName, lPassWord, lSourcePath + '/cmake_targets/build_log_' + self.testCase_id + '/*', '.')
 		CCR = CppCheckResults()
+		CCR_ref = CppCheckResults()
 		vId = 0
 		for variant in CCR.variants:
+			refAvailable = False
+			if self.ranAllowMerge:
+				refFolder = str(Path.home()) + '/cppcheck-references'
+				if (os.path.isfile(refFolder + '/cppcheck-'+ variant + '.txt')):
+					refAvailable = True
+					with open(refFolder + '/cppcheck-'+ variant + '.txt', 'r') as refFile:
+						for line in refFile:
+							ret = re.search(' (?P<nb_errors>[0-9\.]+) errors', str(line))
+							if ret is not None:
+								CCR_ref.nbErrors[vId] = int(ret.group('nb_errors'))
+							ret = re.search(' (?P<nb_warnings>[0-9\.]+) warnings', str(line))
+							if ret is not None:
+								CCR_ref.nbWarnings[vId] = int(ret.group('nb_warnings'))
 			if (os.path.isfile('./cppcheck-'+ variant + '.txt')):
 				xmlStart = False
 				with open('./cppcheck-'+ variant + '.txt', 'r') as logfile:
@@ -167,21 +192,43 @@ class StaticCodeAnalysis():
 								CCR.nbPtrAddNotNull[vId] += 1
 							if re.search('id="oppositeInnerCondition"', str(line)) is not None:
 								CCR.nbOppoInnerCondition[vId] += 1
-			logging.debug('========  Variant ' + variant + ' - ' + CCR.versions[vId] + ' ========')
-			logging.debug('   ' + str(CCR.nbErrors[vId]) + ' errors')
-			logging.debug('   ' + str(CCR.nbWarnings[vId]) + ' warnings')
-			logging.debug('  -- Details --')
-			logging.debug('   Memory leak:                     ' + str(CCR.nbMemLeaks[vId]))
-			logging.debug('   Possible null pointer deference: ' + str(CCR.nbNullPtrs[vId]))
-			logging.debug('   Uninitialized variable:          ' + str(CCR.nbUninitVars[vId]))
-			logging.debug('   Undefined behaviour shifting:    ' + str(CCR.nbTooManyBitsShift[vId]))
-			logging.debug('   Signed integer overflow:         ' + str(CCR.nbIntegerOverflow[vId]))
-			logging.debug('')
-			logging.debug('   Printf formatting issue:         ' + str(CCR.nbInvalidPrintf[vId]))
-			logging.debug('   Modulo result is predetermined:  ' + str(CCR.nbModuloAlways[vId]))
-			logging.debug('   Opposite Condition -> dead code: ' + str(CCR.nbOppoInnerCondition[vId]))
-			logging.debug('   Wrong Scanf Nb Args:             ' + str(CCR.nbWrongScanfArg[vId]))
-			logging.debug('')
+			vMsg  = ''
+			vMsg += '========  Variant ' + variant + ' - ' + CCR.versions[vId] + ' ========\n'
+			vMsg += '   ' + str(CCR.nbErrors[vId]) + ' errors\n'
+			vMsg += '   ' + str(CCR.nbWarnings[vId]) + ' warnings\n'
+			vMsg += '  -- Details --\n'
+			vMsg += '   Memory leak:                     ' + str(CCR.nbMemLeaks[vId]) + '\n'
+			vMsg += '   Possible null pointer deference: ' + str(CCR.nbNullPtrs[vId]) + '\n'
+			vMsg += '   Uninitialized variable:          ' + str(CCR.nbUninitVars[vId]) + '\n'
+			vMsg += '   Undefined behaviour shifting:    ' + str(CCR.nbTooManyBitsShift[vId]) + '\n'
+			vMsg += '   Signed integer overflow:         ' + str(CCR.nbIntegerOverflow[vId]) + '\n'
+			vMsg += '\n'
+			vMsg += '   Printf formatting issue:         ' + str(CCR.nbInvalidPrintf[vId]) + '\n'
+			vMsg += '   Modulo result is predetermined:  ' + str(CCR.nbModuloAlways[vId]) + '\n'
+			vMsg += '   Opposite Condition -> dead code: ' + str(CCR.nbOppoInnerCondition[vId]) + '\n'
+			vMsg += '   Wrong Scanf Nb Args:             ' + str(CCR.nbWrongScanfArg[vId]) + '\n'
+			for vLine in vMsg.split('\n'):
+				logging.debug(vLine)
+			if self.ranAllowMerge and refAvailable:
+				if CCR_ref.nbErrors[vId] == CCR.nbErrors[vId]:
+					logging.debug('   No change in number of errors')
+				elif CCR_ref.nbErrors[vId] > CCR.nbErrors[vId]:
+					logging.debug('   Good! Decrease in number of errors')
+				else:
+					logging.debug('   Bad! increase in number of errors')
+				if CCR_ref.nbWarnings[vId] == CCR.nbWarnings[vId]:
+					logging.debug('   No change in number of warnings')
+				elif CCR_ref.nbWarnings[vId] > CCR.nbWarnings[vId]:
+					logging.debug('   Good! Decrease in number of warnings')
+				else:
+					logging.debug('   Bad! increase in number of warnings')
+			# Create new reference file
+			if not self.ranAllowMerge:
+				refFolder = str(Path.home()) + '/cppcheck-references'
+				if not os.path.isdir(refFolder):
+					os.mkdir(refFolder)
+				with open(refFolder + '/cppcheck-'+ variant + '.txt', 'w') as refFile:
+					refFile.write(vMsg)
 			vId += 1
 
 		HTML.CreateHtmlTestRow('N/A', 'OK', CONST.ALL_PROCESSES_OK)
diff --git a/ci-scripts/conf_files/benetel-5g.conf b/ci-scripts/conf_files/benetel-5g.conf
index bfe61188b64514fcbff501725624a9330e7a05a9..8f3b03fddc52948faeabdb00de9826daaeb21c96 100644
--- a/ci-scripts/conf_files/benetel-5g.conf
+++ b/ci-scripts/conf_files/benetel-5g.conf
@@ -22,9 +22,7 @@ gNBs =
     ////////// Physical parameters:
 
     ssb_SubcarrierOffset                                      = 31; //0;
-    pdsch_AntennaPorts                                        = 1;
-    pusch_AntennaPorts                                        = 1;
-	
+
     servingCellConfigCommon = (
     {
  #spCellConfigCommon
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 24c35dedbf07d8afed9075df7179eb3a2d64d678..fe2e031acb6d0a000b68a973ba54c89867f85783 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
@@ -211,8 +211,8 @@ MACRLCs = (
         bler_target_upper = 20.0;
         bler_target_lower = 10.0;
         max_ul_rb_index   = 27;
-        puSch10xSnr     =  200;
-        puCch10xSnr     =  150;
+        puSch10xSnr     =  190;
+        puCch10xSnr     =  160;
         }  
 );
 
@@ -231,8 +231,8 @@ RUs = (
        local_rf       = "yes"
          nb_tx          = 2
          nb_rx          = 2
-         att_tx         = 0
-         att_rx         = 0;
+         att_tx         = 10
+         att_rx         = 5;
          bands          = [38];
          max_pdschReferenceSignalPower = -27;
          max_rxgain                    = 75;
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 4a16a641058d2a4316e355db37b5b1ca8b8526ce..a0742c57a69022c74ec2e244ea320ea0ff0f83d7 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
@@ -211,8 +211,8 @@ MACRLCs = (
         bler_target_upper = 20.0;
         bler_target_lower = 10.0;
         max_ul_rb_index   = 27;
-        puSch10xSnr     =  200;
-        puCch10xSnr     =  150;
+        puSch10xSnr     =  190;
+        puCch10xSnr     =  160;
         }  
 );
 
@@ -231,8 +231,8 @@ RUs = (
        local_rf       = "yes"
          nb_tx          = 2
          nb_rx          = 2
-         att_tx         = 0
-         att_rx         = 0;
+         att_tx         = 10
+         att_rx         = 5;
          bands          = [38];
          max_pdschReferenceSignalPower = -27;
          max_rxgain                    = 75;
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 bccd37abe98dc20c033ca4808164adce1821a5d2..dfc9beda715c695b17672f780d7344af3f46572b 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
@@ -211,8 +211,8 @@ MACRLCs = (
         bler_target_upper = 20.0;
         bler_target_lower = 10.0;
         max_ul_rb_index   = 27;
-        puSch10xSnr     =  200;
-        puCch10xSnr     =  150;
+        puSch10xSnr     =  190;
+        puCch10xSnr     =  160;
         }  
 );
 
@@ -231,8 +231,8 @@ RUs = (
        local_rf       = "yes"
          nb_tx          = 2
          nb_rx          = 2
-         att_tx         = 0
-         att_rx         = 0;
+         att_tx         = 10
+         att_rx         = 5;
          bands          = [38];
          max_pdschReferenceSignalPower = -27;
          max_rxgain                    = 75;
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..40f6f911b16f017ef20b1f552ce449f35323f461 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;
 
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..edcd4f06ffcf66f06868cf321fba144c6026bd94 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;
 
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 c30805a2d9b6021db0df7b3c38186a0fd70b0e3d..f95bdf91aee97e2c4c02f8b89db251622bacaf0c 100644
--- a/ci-scripts/conf_files/gNB_SA_DU.conf
+++ b/ci-scripts/conf_files/gNB_SA_DU.conf
@@ -37,10 +37,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/conf_files/gNB_SA_n78_106PRB.2x2_usrpn310.conf b/ci-scripts/conf_files/gNB_SA_n78_106PRB.2x2_usrpn310.conf
index 8b14b7455681031550803aaeb63ed19c81f52ada..33ab30887f6a11df307cbaac8e61e8d288515309 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
@@ -38,7 +38,7 @@ gNBs =
     ////////// Physical parameters:
 
     ssb_SubcarrierOffset                                      = 0;
-    pdsch_AntennaPorts                                        = 1;
+    pdsch_AntennaPorts_N1                                     = 2;
     pusch_AntennaPorts                                        = 2;
 
     pdcch_ConfigSIB1 = (
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 02035ea827c2965a4c96314b28f7316ddf31e494..4a5eaec89b5f2faa7518e5c3a8fd60473f40ecc6 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
@@ -39,7 +39,7 @@ gNBs =
     ////////// Physical parameters:
 
     ssb_SubcarrierOffset                                      = 0;
-    pdsch_AntennaPorts                                        = 1;
+    pdsch_AntennaPorts_N1                                     = 2;
     pusch_AntennaPorts                                        = 2;
 
     pdcch_ConfigSIB1 = (
diff --git a/ci-scripts/conf_files/gnb.band261.tm1.32PRB.usrpn300.conf b/ci-scripts/conf_files/gnb.band261.tm1.32PRB.usrpn300.conf
index e8c6cab1b496ac0e6295cd2b5ef53c216328e9a8..9353bd12d26ed802af0bad7f42f8bc7e79ba7621 100644
--- a/ci-scripts/conf_files/gnb.band261.tm1.32PRB.usrpn300.conf
+++ b/ci-scripts/conf_files/gnb.band261.tm1.32PRB.usrpn300.conf
@@ -22,8 +22,6 @@ gNBs =
     ////////// Physical parameters:
 
     ssb_SubcarrierOffset                                      = 0;
-    pdsch_AntennaPorts                                        = 1;
-    pusch_AntennaPorts                                        = 1;
     min_rxtxtime                                              = 6;
 	
     servingCellConfigCommon = (
diff --git a/ci-scripts/conf_files/gnb.band66.tm1.106PRB.usrpn300.conf b/ci-scripts/conf_files/gnb.band66.tm1.106PRB.usrpn300.conf
index 7d3409d4d490cfe99fbe1969315ec257547bdc4a..1019ec75ade5bb36558e7bb49bcfae9e0ffb6002 100644
--- a/ci-scripts/conf_files/gnb.band66.tm1.106PRB.usrpn300.conf
+++ b/ci-scripts/conf_files/gnb.band66.tm1.106PRB.usrpn300.conf
@@ -22,8 +22,6 @@ gNBs =
     ////////// Physical parameters:
 
     ssb_SubcarrierOffset                                      = 0;
-    pdsch_AntennaPorts                                        = 1;
-    pusch_AntennaPorts                                        = 1;
     min_rxtxtime                                              = 6;
 
     servingCellConfigCommon = (
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 84b66060d978b97862af6291e6cf1bef10065399..21863dcfc7bf99cbe6ba36501f36d192d8209f56 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
@@ -20,10 +20,8 @@ gNBs =
     ////////// Physical parameters:
 
     ssb_SubcarrierOffset                                      = 31; //0;
-    pdsch_AntennaPorts                                        = 1;
+    pdsch_AntennaPorts_N1                                     = 2;
     pusch_AntennaPorts                                        = 2;
-    pusch_TargetSNRx10                                        = 200;
-    pucch_TargetSNRx10                                        = 200;
     ul_prbblacklist                                           = "51,52,53,54"
 
     servingCellConfigCommon = (
@@ -239,8 +237,7 @@ RUs = (
 THREAD_STRUCT = (
   {
     #three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT"
-    parallel_config    = "PARALLEL_RU_L1_TRX_SPLIT";
-    //parallel_config    = "PARALLEL_SINGLE_THREAD";
+    parallel_config    = "PARALLEL_SINGLE_THREAD";
     #two option for worker "WORKER_DISABLE" or "WORKER_ENABLE"
     worker_config      = "WORKER_ENABLE";
   }
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..60fb16318fc9011e69007a08364aae58b021c525
--- /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=192.168.18.252,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 9f5c2875b39c80e73c59efdbb22815ca3e64d524..1d7c4b57f08ec1a7b396097959cf1a9dac2aacf2 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
@@ -38,7 +38,7 @@ gNBs =
     ////////// Physical parameters:
 
     ssb_SubcarrierOffset                                      = 0;
-    pdsch_AntennaPorts                                        = 1;
+    pdsch_AntennaPorts_N1                                     = 2;
     pusch_AntennaPorts                                        = 2;
     ul_prbblacklist                                           = "51,52,53,54"
     do_SRS                                                    = 1;
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 594bd5e4c82dc0a1db81e39e61cc9ad392060e66..e2b331939b99082d2b90d2f7cb1b98688cf3061d 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
@@ -38,8 +38,6 @@ gNBs =
     ////////// Physical parameters:
 
     ssb_SubcarrierOffset                                      = 0;
-    pdsch_AntennaPorts                                        = 1;
-    pusch_AntennaPorts                                        = 1;
     #pusch_TargetSNRx10                                        = 200;
     #pucch_TargetSNRx10                                        = 200;
     ul_prbblacklist                                           = "51,52,53,54"
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 2361437f7c7c1b4004850bd1e0252d5f8dea823d..324b3d2ce1c36556816d128fd7cfef0fbe92e39a 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
@@ -38,8 +38,10 @@ gNBs =
     ////////// Physical parameters:
 
     ssb_SubcarrierOffset                                      = 0;
-    pdsch_AntennaPorts                                        = 1;
+    pdsch_AntennaPorts_N1                                     = 2;
     pusch_AntennaPorts                                        = 2;
+    #pusch_TargetSNRx10                                        = 200;
+    #pucch_TargetSNRx10                                        = 200;
     ul_prbblacklist                                           = "79,80,81,82"
 
     pdcch_ConfigSIB1 = (
@@ -83,7 +85,7 @@ gNBs =
      #initialDownlinkBWP
       #genericParameters
         # this is RBstart=0,L=106 (275*(L-1))+RBstart
-        initialDLBWPlocationAndBandwidth                                        = 31899;
+        initialDLBWPlocationAndBandwidth                                        = 31624;
 # subcarrierSpacing
 # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
         initialDLBWPsubcarrierSpacing                                           = 1;
@@ -103,7 +105,7 @@ gNBs =
       pMax                                                          = 20;
      #initialUplinkBWP
       #genericParameters
-        initialULBWPlocationAndBandwidth                                        = 31899;
+        initialULBWPlocationAndBandwidth                                        = 31624;
 # subcarrierSpacing
 # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
         initialULBWPsubcarrierSpacing                                           = 1;
diff --git a/ci-scripts/conf_files/gnb.band78.tm1.106PRB.usrpn300.conf b/ci-scripts/conf_files/gnb.band78.tm1.106PRB.usrpn300.conf
index d21cf90cd93a51e58405419ead809a0c3f883e23..0c7508039856bb00cff9b70ad7a8eb96d4266589 100644
--- a/ci-scripts/conf_files/gnb.band78.tm1.106PRB.usrpn300.conf
+++ b/ci-scripts/conf_files/gnb.band78.tm1.106PRB.usrpn300.conf
@@ -22,8 +22,6 @@ gNBs =
     ////////// Physical parameters:
 
     ssb_SubcarrierOffset = 0;
-    pdsch_AntennaPorts = 1;
-    pusch_AntennaPorts = 1;
     min_rxtxtime = 6;
 
     servingCellConfigCommon = (
@@ -221,8 +219,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 = "addr=192.168.30.2,mgmt_addr=192.168.30.2,second_addr=192.168.50.2";
-         clock_src = "external";
+         sdr_addrs = "addr=192.168.10.2,second_addr=192.168.20.2,mgmt_addr=192.168.18.85";
     }
 );  
 
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 55cb7b36c4dc495678847f78fb41b52f6be64746..af581453229280fbb425992a4e5023c408f1f5b3 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
@@ -20,8 +20,6 @@ gNBs =
     ////////// Physical parameters:
 
     ssb_SubcarrierOffset                                      = 31; //0;
-    pdsch_AntennaPorts                                        = 1;
-    pusch_AntennaPorts                                        = 1;
  
     servingCellConfigCommon = (
     {
diff --git a/ci-scripts/conf_files/gnb.band78.tm1.fr1.106PRB.usrpn310.conf b/ci-scripts/conf_files/gnb.band78.tm1.fr1.106PRB.usrpn310.conf
index 7c4bb9cc59d5f6dc5374188ab78672f3c1033353..8f480d375717f5af5ea711ab5102bd93e9fbe080 100644
--- a/ci-scripts/conf_files/gnb.band78.tm1.fr1.106PRB.usrpn310.conf
+++ b/ci-scripts/conf_files/gnb.band78.tm1.fr1.106PRB.usrpn310.conf
@@ -21,8 +21,6 @@ gNBs =
     ////////// Physical parameters:
 
     ssb_SubcarrierOffset                                      = 31; //0;
-    pdsch_AntennaPorts                                        = 1;
-    pusch_AntennaPorts                                        = 1;
     min_rxtxtime = 6;
  
     servingCellConfigCommon = (
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..c838c3740d9cb3482b8b2e19d9bc593f8242fbbd 100644
--- a/ci-scripts/main.py
+++ b/ci-scripts/main.py
@@ -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
@@ -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
new file mode 100644
index 0000000000000000000000000000000000000000..ee8306402fb7bdac08977a9f392c1c6f04de1f85
--- /dev/null
+++ b/ci-scripts/provideUniqueImageTag.py
@@ -0,0 +1,54 @@
+import argparse
+import os
+import re
+import subprocess
+import sys
+
+AUTH_SERVICE = 'registry.docker.io'
+AUTH_SCOPE   = 'repository:rdefosseoai/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"'
+    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 .'
+    listOfTags = subprocess.check_output(cmd, shell=True, universal_newlines=True)
+
+    foundTag = False
+    for tag in listOfTags.split('\n'):
+        if re.search('"' + args.start_tag + '"', tag) is not None:
+            foundTag = True
+
+    if not foundTag:
+        print (args.start_tag)
+        sys.exit(0)
+
+    proposedVariants = ['a', 'b', 'c', 'd']
+    for variant in proposedVariants:
+        foundTag = False
+        currentVariant = variant
+        for tag in listOfTags.split('\n'):
+            if re.search('"' + args.start_tag + variant + '"', tag) is not None:
+                foundTag = True
+                break
+        if not foundTag:
+            break
+
+    if not foundTag:
+        print (args.start_tag + currentVariant)
+
+def _parse_args() -> argparse.Namespace:
+    parser = argparse.ArgumentParser(description='Provides an unique new image tag for DockerHub')
+
+    parser.add_argument(
+        '--start_tag', '-st',
+        action='store',
+        required=True,
+        help='Proposed Starting Tag',
+    )
+    return parser.parse_args()
+
+if __name__ == '__main__':
+    main()
diff --git a/ci-scripts/ran.py b/ci-scripts/ran.py
index 3b32a75542db080ea50a91ffdc13e530709010a1..287a0a3c09b0af23497254827aa193603a20fe2f 100644
--- a/ci-scripts/ran.py
+++ b/ci-scripts/ran.py
@@ -485,7 +485,7 @@ class RANManagement():
 
 		mySSH.command('chmod 775 ./my-lte-softmodem-run' + str(self.eNB_instance) + '.sh', '\$', 5)
 		mySSH.command('echo ' + lPassWord + ' | sudo -S rm -Rf enb_' + self.testCase_id + '.log', '\$', 5)
-		mySSH.command('echo $USER; nohup sudo -E ./my-lte-softmodem-run' + str(self.eNB_instance) + '.sh > ' + lSourcePath + '/cmake_targets/enb_' + self.testCase_id + '.log 2>&1 &', lUserName, 10)
+		mySSH.command('echo $USER; nohup sudo -E stdbuf -o0 ./my-lte-softmodem-run' + str(self.eNB_instance) + '.sh > ' + lSourcePath + '/cmake_targets/enb_' + self.testCase_id + '.log 2>&1 &', lUserName, 10)
 
 
 		#stats monitoring during runtime
@@ -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)
@@ -756,11 +752,11 @@ class RANManagement():
 		mySSH.command('echo ' + self.eNBPassword + ' | sudo -S mv /tmp/enb_*.pcap .','\$',20)
 		mySSH.command('echo ' + self.eNBPassword + ' | sudo -S mv /tmp/gnb_*.pcap .','\$',20)
 		mySSH.command('echo ' + self.eNBPassword + ' | sudo -S rm -f enb.log.zip', '\$', 5)
-		mySSH.command('echo ' + self.eNBPassword + ' | sudo -S zip enb.log.zip enb*.log enb_*record.raw enb_*.pcap gnb_*.pcap enb_*txt physim_*.log *stats.log *monitor.pickle *monitor*.png ping*.log.png log/*/*.log log/*/*.pcap', '\$', 60)
+		mySSH.command('echo ' + self.eNBPassword + ' | sudo -S zip enb.log.zip enb*.log enb_*record.raw enb_*.pcap gnb_*.pcap enb_*txt physim_*.log *stats.log *monitor.pickle *monitor*.png ping*.log* iperf*.log log/*/*.log log/*/*.pcap', '\$', 60)
 		result = re.search('core.\d+', mySSH.getBefore())
 		if result is not None:
 			mySSH.command('echo ' + self.eNBPassword + ' | sudo -S zip enb.log.zip core* ran_build/build/{lte,nr}-softmodem', '\$', 60) # add core and executable to zip
-		mySSH.command('echo ' + self.eNBPassword + ' | sudo -S rm enb*.log core* enb_*record.raw enb_*.pcap gnb_*.pcap enb_*txt physim_*.log *stats.log *monitor.pickle *monitor*.png ping*.log.png log/*/*.log log/*/*.pcap', '\$', 15)
+		mySSH.command('echo ' + self.eNBPassword + ' | sudo -S rm enb*.log core* enb_*record.raw enb_*.pcap gnb_*.pcap enb_*txt physim_*.log *stats.log *monitor.pickle *monitor*.png ping*.log* iperf*.log log/*/*.log log/*/*.pcap', '\$', 15)
 		mySSH.close()
 
 	def AnalyzeLogFile_eNB(self, eNBlogFile, HTML, checkers={}):
@@ -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 55f8b8638df8c67791e0641fe7f5ad5a90b13d58..610f0b019a447ff5e78e632cd9b016143c054f6b 100644
--- a/ci-scripts/xml_files/container_nsa_b200_quectel.xml
+++ b/ci-scripts/xml_files/container_nsa_b200_quectel.xml
@@ -39,8 +39,9 @@
  050001
  070001
  070000
- 050000
- 050001
+ 070002
+ 050002
+ 050003
  010002
  000001
  030202
@@ -117,10 +118,28 @@
 		<ping_rttavg_threshold>15</ping_rttavg_threshold>
 	</testCase>
 
+	<testCase id="050002">
+		<class>Ping</class>
+		<desc>Ping: 20pings in 20sec</desc>
+		<id>idefix</id>
+		<ping_args>-c 20</ping_args>
+		<ping_packetloss_threshold>1</ping_packetloss_threshold>
+		<ping_rttavg_threshold>15</ping_rttavg_threshold>
+	</testCase>
+
+	<testCase id="050003">
+		<class>Ping</class>
+		<desc>Ping: 100pings in 20sec</desc>
+		<id>idefix</id>
+		<ping_args>-c 100 -i 0.2</ping_args>
+		<ping_packetloss_threshold>1</ping_packetloss_threshold>
+		<ping_rttavg_threshold>15</ping_rttavg_threshold>
+	</testCase>
+
 	<testCase id="070000">
 		<class>Iperf</class>
 		<desc>iperf (DL/40Mbps/UDP)(60 sec)(single-ue profile)</desc>
-		<iperf_args>-u -b 40M -t 60</iperf_args>
+		<iperf_args>-u -b 40M -t 60 -i 1 -fm</iperf_args>
 		<direction>DL</direction>
 		<id>idefix</id>
 		<iperf_packetloss_threshold>20</iperf_packetloss_threshold>
@@ -131,7 +150,7 @@
 	<testCase id="070001">
 		<class>Iperf</class>
 		<desc>iperf (UL/3Mbps/UDP)(60 sec)(single-ue profile)</desc>
-		<iperf_args>-u -b 3M -t 60</iperf_args>
+		<iperf_args>-u -b 3M -t 60 -i 1 -fm</iperf_args>
 		<direction>UL</direction>
 		<id>idefix</id>
 		<iperf_packetloss_threshold>1</iperf_packetloss_threshold>
@@ -139,6 +158,15 @@
 		<iperf_profile>single-ue</iperf_profile>
 	</testCase>
 
+    <testCase id="070002">
+        <class>Iperf</class>
+        <desc>iperf (BIDIR TCP)(10 sec)(single-ue profile)</desc>
+        <iperf_args>-t 10 --bidir</iperf_args>
+        <direction>BIDIR</direction>
+        <id>idefix</id>
+        <iperf_profile>single-ue</iperf_profile>
+    </testCase>
+
     <testCase id="030201">
         <class>Undeploy_Object</class>
         <desc>Undeploy eNB</desc>
diff --git a/ci-scripts/xml_files/fr1_nsa_2x2_quectel.xml b/ci-scripts/xml_files/fr1_nsa_2x2_quectel.xml
index 5dbd36f00d323af2240bb675acfb251827b020f5..56694920ba593fbc6d048c7169e8df00c2940893 100644
--- a/ci-scripts/xml_files/fr1_nsa_2x2_quectel.xml
+++ b/ci-scripts/xml_files/fr1_nsa_2x2_quectel.xml
@@ -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.240</USRP_IPAddress>
+		<USRP_IPAddress>192.168.18.252</USRP_IPAddress>
 	</testCase>
 
 	<testCase id="000001">
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 02544f273baae039405add42c5d89ef67c07cf8c..840521481e82fa69d058b59ed830eeec1dd77f93 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
@@ -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.240</USRP_IPAddress>
+		<USRP_IPAddress>192.168.18.252</USRP_IPAddress>
 	</testCase>
 
 	<testCase id="000001">
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..194ed4e453e072de6e1c66c258b1c0a64590cd86
--- /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>192.168.18.252</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 774d5751c5949fc468cb660dbbbd6fb530555827..55268b909d7451a55345acd44bbfbb157d86d5b0 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.240</USRP_IPAddress>
+		<USRP_IPAddress>192.168.18.252</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 bfa2208d3dc426cc60edf8cebda52a7f3baf0ead..53b696c6eb0fffbd8c198bfefedd445d12297bd8 100644
--- a/ci-scripts/xml_files/fr1_sa_oaiue_n310.xml
+++ b/ci-scripts/xml_files/fr1_sa_oaiue_n310.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.240</USRP_IPAddress>
+		<USRP_IPAddress>192.168.18.252</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 c43bdd2a7c932197bf6a91e4a7a4e6b2105281f2..8c2f7052e4eb52101575ba8646345d59f16f6f76 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.240</USRP_IPAddress>
+		<USRP_IPAddress>192.168.18.252</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 8d15015c0747e4c84d46dcc7322421f7c0d2b080..576456ebc96959cd3e9e4284c84e02ecce1d1685 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.240</USRP_IPAddress>
+		<USRP_IPAddress>192.168.18.252</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 f756083ea6668bf28e64b1fc9d6c357b1410cc29..c5f2ddad5f479a4691330392499fdb1d7226838d 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.240</USRP_IPAddress>
+		<USRP_IPAddress>192.168.18.252</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 0ab8bf6b0845f4a67f37196c84a61ca24ebc2483..2707fd4ebff998441de2c9a23d42458976fdcd05 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.240</USRP_IPAddress>
+		<USRP_IPAddress>192.168.18.252</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 5feed7558657b039d75c1d16ca8b3f9ffce85d40..661bcb32fe0c5112cb437921dce8c79b38ec6cc0 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.240</USRP_IPAddress>
+		<USRP_IPAddress>192.168.18.252</USRP_IPAddress>
 	</testCase>
 
 	<testCase id="000001">
diff --git a/ci-scripts/xml_files/gnb_phytest_usrp_run.xml b/ci-scripts/xml_files/gnb_phytest_usrp_run.xml
index f1185c08c96dd711b547299b36cbe41cc79e6ef0..5705533ab483ac75021d4666ca04bcadf6f05a8c 100644
--- a/ci-scripts/xml_files/gnb_phytest_usrp_run.xml
+++ b/ci-scripts/xml_files/gnb_phytest_usrp_run.xml
@@ -35,7 +35,7 @@
 		<desc>Initialize gNB USRP</desc>
 		<Initialize_eNB_args>-O ci-scripts/conf_files/gnb.band78.tm1.106PRB.usrpn300.conf --phy-test -q -U 787200 -T 106 -t 28 -D 130175 -m 28 -M 106 --log_config.global_log_options level,nocolor,time</Initialize_eNB_args>
 		<air_interface>NR</air_interface>
-		<USRP_IPAddress>192.168.30.2</USRP_IPAddress>
+		<USRP_IPAddress>192.168.20.2</USRP_IPAddress>
 	</testCase>
 
 	<testCase id="000001">
diff --git a/ci-scripts/xml_files/gnb_usrp_build.xml b/ci-scripts/xml_files/gnb_usrp_build.xml
index e2662180c5b8fee0c2974e703328a30673eb5193..97f85c6a339e12edce0feaa9ca570aa4e07332b1 100644
--- a/ci-scripts/xml_files/gnb_usrp_build.xml
+++ b/ci-scripts/xml_files/gnb_usrp_build.xml
@@ -34,7 +34,7 @@
 		<mode>TesteNB</mode>	
 		<class>Build_eNB</class>
 		<desc>Build gNB (USRP)</desc>
-		<Build_eNB_args>--gNB -w USRP --ninja</Build_eNB_args>
+		<Build_eNB_args>--gNB -w USRP --ninja --cmake-opt -DBoost_INCLUDE_DIR=/usr/include/boost169</Build_eNB_args>
 		<forced_workspace_cleanup>True</forced_workspace_cleanup>
 	</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/5g_l2sim_tdd/README.md b/ci-scripts/yaml_files/5g_l2sim_tdd/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..531f2406ef8c622852fec4ef76108e5072ca3932
--- /dev/null
+++ b/ci-scripts/yaml_files/5g_l2sim_tdd/README.md
@@ -0,0 +1,355 @@
+<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 user account `rdefosseoai`.
+
+This may change in the future.
+
+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 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 rdefosseoai/oai-gnb:develop
+$ docker pull rdefosseoai/oai-nr-ue:develop
+$ docker pull rdefosseoai/proxy:latest
+```
+
+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 rdefosseoai/oai-gnb:develop oai-gnb:develop
+$ docker image tag rdefosseoai/oai-nr-ue:develop oai-nr-ue:develop
+$ docker image tag rdefosseoai/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=192.168.18.129
+```
+
+In the `gNB` section, provide your docker-host primary IP address and interface name: in our case `192.168.18.193` and `eno1`.
+
+```yaml
+            GNB_NGA_IF_NAME: eno1
+            GNB_NGA_IP_ADDRESS: 192.168.18.193
+            GNB_NGU_IF_NAME: eno1
+            GNB_NGU_IP_ADDRESS: 192.168.18.193
+```
+
+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..c899f8cc7e2076593e8f848cf2d3dbd36bb75c53
--- /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=192.168.18.129
+            - 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: 192.168.18.193
+            GNB_NGU_IF_NAME: eno1
+            GNB_NGU_IP_ADDRESS: 192.168.18.193
+            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 5eb2a789a94c30ae294a65680cd1864f0d476ffc..64c9084500ce58c964875b8ad78313cb0506cab4 100644
--- a/ci-scripts/yaml_files/5g_rfsimulator/README.md
+++ b/ci-scripts/yaml_files/5g_rfsimulator/README.md
@@ -234,7 +234,7 @@ Making sure the OAI UE is connected:
 $ docker exec -it rfsim5g-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
+        inet 192.168.71.150  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
@@ -270,7 +270,7 @@ Create entry for Second UE in docker-compose.yaml file as follows:
         privileged: true
         container_name: rfsim5g-oai-nr-ue2
         environment:
-            RFSIMULATOR: 192.168.71.136
+            RFSIMULATOR: 192.168.71.140
             FULL_IMSI: '208990100001101'
             FULL_KEY: 'fec86ba6eb707ed08905757b1bb44b8f'
             OPC: 'C42449363BBAD02B66D16BC975D77CC1'
@@ -282,7 +282,7 @@ Create entry for Second UE in docker-compose.yaml file as follows:
             - oai-gnb
         networks:
             public_net:
-                ipv4_address: 192.168.71.138
+                ipv4_address: 192.168.71.151
         healthcheck:
             test: /bin/bash -c "pgrep nr-uesoftmodem"
             interval: 10s
@@ -326,7 +326,7 @@ Making sure the Second OAI UE is connected:
 $ docker exec -it rfsim5g-oai-nr-ue2 /bin/bash
 root@bb4d400a832d:/opt/oai-nr-ue# ifconfig 
 eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
-        inet 192.168.71.138  netmask 255.255.255.192  broadcast 192.168.71.191
+        inet 192.168.71.151  netmask 255.255.255.192  broadcast 192.168.71.191
         ether 02:42:c0:a8:47:8a  txqueuelen 0  (Ethernet)
         RX packets 3192021  bytes 67784900946 (67.7 GB)
         RX errors 0  dropped 0  overruns 0  frame 0
diff --git a/ci-scripts/yaml_files/5g_rfsimulator/docker-compose.yaml b/ci-scripts/yaml_files/5g_rfsimulator/docker-compose.yaml
index 808be7d83d5f8c370a49c1a91050e2642f700070..f27ec3050dc2116faf97f28d4e25f64abb8fcf02 100644
--- a/ci-scripts/yaml_files/5g_rfsimulator/docker-compose.yaml
+++ b/ci-scripts/yaml_files/5g_rfsimulator/docker-compose.yaml
@@ -279,6 +279,30 @@ services:
             timeout: 5s
             retries: 5
 
+    oai-nr-ue2:
+        image: oai-nr-ue:develop
+        privileged: true
+        container_name: rfsim5g-oai-nr-ue2
+        environment: 
+            RFSIMULATOR: 192.168.71.140
+            FULL_IMSI: '208990100001101'
+            FULL_KEY: 'fec86ba6eb707ed08905757b1bb44b8f'
+            OPC: 'C42449363BBAD02B66D16BC975D77CC1'
+            DNN: oai
+            NSSAI_SST: 1
+            NSSAI_SD: 1
+            USE_ADDITIONAL_OPTIONS: -E --sa --rfsim -r 106 --numerology 1 -C 3619200000 --nokrnmod --log_config.global_log_options level,nocolor,time
+        depends_on:
+            - oai-gnb
+        networks:
+            public_net:
+                ipv4_address: 192.168.71.151
+        healthcheck:
+            test: /bin/bash -c "pgrep nr-uesoftmodem"
+            interval: 10s
+            timeout: 5s
+            retries: 5
+
 networks:
     public_net:
         driver: bridge
diff --git a/ci-scripts/yaml_files/5g_rfsimulator/oai_db.sql b/ci-scripts/yaml_files/5g_rfsimulator/oai_db.sql
index fbd7907a71edd41cc32016f91176b270b8b5bd11..75f586c299c93afd9d62ac3dee0a4b82084b8710 100755
--- a/ci-scripts/yaml_files/5g_rfsimulator/oai_db.sql
+++ b/ci-scripts/yaml_files/5g_rfsimulator/oai_db.sql
@@ -192,6 +192,7 @@ LOCK TABLES `users` WRITE;
 /*!40000 ALTER TABLE `users` DISABLE KEYS */;
 INSERT INTO `users` VALUES ('20834123456789','380561234567','35609204079300',NULL,'PURGED',50,40000000,100000000,47,0000000000,1,'+�E��ų\0�,IH��H',0,0,00000000000000000096,'Px�X \Z1��x��','^��K�����FeU���'),('20810000001234','33611123456','35609204079299',NULL,'PURGED',120,40000000,100000000,47,0000000000,1,'��G?/�Д����	|hb',1,0,00000281454575616225,'\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0','�4�s@���z��~�'),('31002890832150','33638060059','35611302209414',NULL,'PURGED',120,40000000,100000000,47,0000000000,1,'��G?/�Д����	|hb',1,0,00000000000000012416,'`�F�݆��D��ϛ���','�4�s@���z��~�'),('001010123456789','33600101789','35609204079298',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'\0	\n\r',1,0,00000000000000000351,'\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0','L�*\\�����^��]� '),('208930000000001','33638030001','35609204079301',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д����	|hb',1,0,00000000000000006103,'��wq��gzW�Ё��Z]','�4�s@���z��~�'),('208950000000002','33638050002','35609204079502',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д����	|hb',1,0,00000000000000020471,'\0	\n\r','�4�s@���z��~�'),('208950000000003','33638050003','35609204079503',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д����	|hb',1,0,00000000000000012343,'\0	\n\r','�4�s@���z��~�'),('208950000000004','33638050004','35609204079504',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д����	|hb',1,0,00000000000000012215,'56f0261d9d051063','�4�s@���z��~�'),('208950000000005','33638050005','35609204079505',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д����	|hb',1,0,00000000000000012215,'56f0261d9d051063','�4�s@���z��~�'),('208950000000001','33638050001','35609204079501',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д����	|hb',1,0,00000000000000006103,'��wq��gzW�Ё��Z]','�4�s@���z��~�'),('208950000000006','33638050006','35609204079506',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д����	|hb',1,0,00000000000000012215,'56f0261d9d051063','�4�s@���z��~�'),('208950000000007','33638050007','35609204079507',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д����	|hb',1,0,00000000000000012215,'56f0261d9d051063','�4�s@���z��~�'),('208930000000002','33638030002','35609204079302',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д����	|hb',1,0,00000000000000006103,'��wq��gzW�Ё��Z]','�4�s@���z��~�'),('208930000000003','33638030003','35609204079303',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д����	|hb',1,0,00000000000000006103,'��wq��gzW�Ё��Z]','�4�s@���z��~�'),('208930000000004','33638030004','35609204079304',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д����	|hb',1,0,00000000000000006103,'��wq��gzW�Ё��Z]','�4�s@���z��~�'),('208930000000005','33638030005','35609204079305',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д����	|hb',1,0,00000000000000006103,'��wq��gzW�Ё��Z]','�4�s@���z��~�'),('208930000000006','33638030006','35609204079306',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д����	|hb',1,0,00000000000000006103,'��wq��gzW�Ё��Z]','�4�s@���z��~�'),('208930000000007','33638030007','35609204079307',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д����	|hb',1,0,00000000000000006103,'��wq��gzW�Ё��Z]','�4�s@���z��~�'),('208940000000007','33638040007','35609204079407',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д����	|hb',1,0,00000000000000006103,'��wq��gzW�Ё��Z]','�4�s@���z��~�'),('208940000000006','33638040006','35609204079406',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д����	|hb',1,0,00000000000000006103,'��wq��gzW�Ё��Z]','�4�s@���z��~�'),('208940000000005','33638040005','35609204079405',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д����	|hb',1,0,00000000000000006103,'��wq��gzW�Ё��Z]','�4�s@���z��~�'),('208940000000004','33638040004','35609204079404',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д����	|hb',1,0,00000000000000006103,'��wq��gzW�Ё��Z]','�4�s@���z��~�'),('208940000000003','33638040003','35609204079403',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д����	|hb',1,0,00000000000000006103,'��wq��gzW�Ё��Z]','�4�s@���z��~�'),('208940000000002','33638040002','35609204079402',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д����	|hb',1,0,00000000000000006103,'��wq��gzW�Ё��Z]','�4�s@���z��~�'),('208940000000001','33638040001','35609204079401',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д����	|hb',1,0,00000000000000006103,'��wq��gzW�Ё��Z]','�4�s@���z��~�'),('208920100001100','33638020001','35609204079201',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д����	|hb',1,0,00000000000000006103,'ebd07771ace8677a','�4�s@���z��~�'),('208920100001101','33638020001','35609204079201',NULL,'NOT_PURGED',120,50000000,100000000,47,0000000000,1,'��k��p~Љu{�K�',1,0,00000281044204937234,'\0	\n\r','�$I6;��+f�k�u�|�'),('208920100001102','33638020002','35609204079202',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д����	|hb',1,0,00000000000000006103,'ebd07771ace8677a','�4�s@���z��~�'),('208920100001103','33638020003','35609204079203',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д����	|hb',1,0,00000000000000006103,'ebd07771ace8677a','�4�s@���z��~�'),('208920100001104','33638020004','35609204079204',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д����	|hb',1,0,00000000000000006103,'ebd07771ace8677a','�4�s@���z��~�'),('208920100001105','33638020005','35609204079205',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д����	|hb',1,0,00000000000000006103,'ebd07771ace8677a','�4�s@���z��~�'),('208920100001106','33638020006','35609204079206',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��k��p~Љu{�K�',1,0,00000000000000006103,'ebd07771ace8677a','�$I6;��+f�k�u�|�'),('208920100001107','33638020007','35609204079207',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д����	|hb',1,0,00000000000000006103,'ebd07771ace8677a','�4�s@���z��~�'),('208920100001108','33638020008','35609204079208',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д����	|hb',1,0,00000000000000006103,'ebd07771ace8677a','�4�s@���z��~�'),('208920100001109','33638020009','35609204079209',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д����	|hb',1,0,00000000000000006103,'ebd07771ace8677a','�4�s@���z��~�'),('208920100001110','33638020010','35609204079210',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д����	|hb',1,0,00000000000000006103,'ebd07771ace8677a','�4�s@���z��~�'),('208930100001111','33638030011','35609304079211',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д����	|hb',1,0,00000000000000006103,'ebd07771ace8677a','�4�s@���z��~�'),('208930100001112','33638030012','35609304079212',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д����	|hb',1,0,00000000000000006103,'ebd07771ace8677a','�4�s@���z��~�'),('208930100001113','33638030013','35609304079213',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д����	|hb',1,0,00000000000000006263,'�SNܒ�Iv��e�6','�4�s@���z��~�'),('208950000000008','33638050008','35609204079508',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д����	|hb',1,0,00000000000000012215,'56f0261d9d051063','�4�s@���z��~�'),('208950000000009','33638050009','35609204079509',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д����	|hb',1,0,00000000000000012215,'56f0261d9d051063','�4�s@���z��~�'),('208950000000010','33638050010','35609204079510',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д����	|hb',1,0,00000000000000012215,'56f0261d9d051063','�4�s@���z��~�'),('208950000000011','33638050011','35609204079511',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д����	|hb',1,0,00000000000000012215,'56f0261d9d051063','�4�s@���z��~�'),('208950000000012','33638050012','35609204079512',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д����	|hb',1,0,00000000000000012215,'56f0261d9d051063','�4�s@���z��~�'),('208950000000013','33638050013','35609204079513',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д����	|hb',1,0,00000000000000012215,'56f0261d9d051063','�4�s@���z��~�'),('208950000000014','33638050014','35609204079514',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д����	|hb',1,0,00000000000000012215,'56f0261d9d051063','�4�s@���z��~�'),('208950000000015','33638050015','35609204079515',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д����	|hb',1,0,00000000000000000000,'3536663032363164','�4�s@���z��~�'),('208920100001118','33638020010','35609204079210',NULL,'NOT_PURGED',120,50000000,100000000,47,0000000000,1,'��k��p~Љu{�K�',1,0,00000281044204934762,'~?03�u-%�ey�y�','�$I6;��+f�k�u�|�'),('208920100001121','33638020010','35609204079210',NULL,'NOT_PURGED',120,50000000,100000000,47,0000000000,1,'��k��p~Љu{�K�',1,0,00000281044204935293,'&��@xg�]���\n��Vp','�$I6;��+f�k�u�|�'),('208920100001119','33638020010','35609204079210',NULL,'NOT_PURGED',120,50000000,100000000,47,0000000000,1,'��k��p~Љu{�K�',1,0,00000281044204935293,'269482407867805d','�$I6;��+f�k�u�|�'),('208920100001120','33638020010','35609204079210',NULL,'NOT_PURGED',120,50000000,100000000,47,0000000000,1,'��k��p~Љu{�K�',1,0,00000281044204935293,'3236393438323430','�$I6;��+f�k�u�|�');
 INSERT INTO `users` VALUES ('208990100001100','1','55000000000000',NULL,'PURGED',50,40000000,100000000,47,0000000000,1,0xfec86ba6eb707ed08905757b1bb44b8f,0,0,0x40,'ebd07771ace8677a',0xc42449363bbad02b66d16bc975d77cc1);
+INSERT INTO `users` VALUES ('208990100001101','1','55000000000000',NULL,'PURGED',50,40000000,100000000,47,0000000000,1,0xfec86ba6eb707ed08905757b1bb44b8f,0,0,0x40,'ebd07771ace8677a',0xc42449363bbad02b66d16bc975d77cc1);
 INSERT INTO `users` VALUES ('208950000000031','380561234567','55000000000001',NULL,'PURGED',50,40000000,100000000,47,0000000000,1,0x0C0A34601D4F07677303652C0462535B,0,0,0x40,'ebd07771ace8677a',0x63bfa50ee6523365ff14c1f45f88737d);
 INSERT INTO `users` VALUES ('208950000000032','380561234567','55000000000001',NULL,'PURGED',50,40000000,100000000,47,0000000000,1,0x0C0A34601D4F07677303652C0462535B,0,0,0x40,'ebd07771ace8677a',0x63bfa50ee6523365ff14c1f45f88737d);
 INSERT INTO `users` VALUES ('208950000000033','380561234567','55000000000001',NULL,'PURGED',50,40000000,100000000,47,0000000000,1,0x0C0A34601D4F07677303652C0462535B,0,0,0x40,'ebd07771ace8677a',0x63bfa50ee6523365ff14c1f45f88737d);
diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt
index 46e33e880334ba7e8b8ab4858e4b6a7b62525832..80c0408e1398821f09275f7909eef8ba68295dee 100644
--- a/cmake_targets/CMakeLists.txt
+++ b/cmake_targets/CMakeLists.txt
@@ -53,7 +53,6 @@ include_directories("/usr/local/include/")
 add_list2_option(RF_BOARD "None" "RF head type" "None" "OAI_USRP" "OAI_BLADERF" "OAI_LMSSDR" "OAI_SIMU" "EXMIMO")
 if (${RF_BOARD} STREQUAL "OAI_USRP")
   find_package(Boost REQUIRED)
-  include_directories(${LIBBOOST_INCLUDE_DIR})
 
 elseif (${RF_BOARD} STREQUAL "OAI_IRIS")
     include_directories("${OPENAIR_TARGETS}/ARCH/IRIS/USERSPACE/LIB/")
@@ -705,11 +704,14 @@ set (SHLIB_LOADER_SOURCES
 # include RF devices / transport protocols library modules
 ######################################################################
 
-include_directories("${OPENAIR_TARGETS}/ARCH/USRP/USERSPACE/LIB/")
 set(HWLIB_USRP_SOURCE
   ${OPENAIR_TARGETS}/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp
   )
 add_library(oai_usrpdevif MODULE ${HWLIB_USRP_SOURCE} )
+target_include_directories(oai_usrpdevif PRIVATE
+  "${OPENAIR_TARGETS}/ARCH/USRP/USERSPACE/LIB/"
+  ${Boost_INCLUDE_DIR}
+)
 target_link_libraries(oai_usrpdevif uhd)
 
 include_directories("${OPENAIR_TARGETS}/ARCH/BLADERF/USERSPACE/LIB/")
@@ -1779,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
@@ -1865,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/build_oai b/cmake_targets/build_oai
index c65728a41d623917680f3be13205369e1ae3e3bb..5cafb95cba61913ec9535bfcdb9aef9ddb5a79b3 100755
--- a/cmake_targets/build_oai
+++ b/cmake_targets/build_oai
@@ -59,19 +59,24 @@ BUILD_ECLIPSE=0
 NR="False"
 OPTIONAL_LIBRARIES="telnetsrv enbscope uescope nrscope"
 RU=0
-trap handle_ctrl_c INT
+CMAKE_C_FLAGS=()
+CMAKE_CXX_FLAGS=()
 
 function print_help() {
   echo_info "
-This program installs OpenAirInterface Software
-You should have ubuntu 16.xx or 18.04 updated
-Options
+This script compiles OpenAirInterface Software, and can install dependencies
+for a number of distributions (Ubuntu 18-22, Fedora, RHEL7/8).
+Options:
+--arch-native
+   Passes -march=native to the compiler.
 -c | --clean
    Erase all files to make a rebuild from start
 -C | --clean-all
    Erase all files made by previous compilations, installations
 --clean-kernel
    Erase previously installed features in kernel: iptables, drivers, ...
+--cmake-opt
+   Pass the supplied option verbatim to cmake.
 -d | --build-dir
    Sets build directory (will be <oai-root>/cmake_targets/<build-dir>/build)
 -I | --install-external-packages
@@ -183,6 +188,10 @@ function main() {
   until [ -z "$1" ]
   do
     case "$1" in
+       --arch-native)
+            CMAKE_C_FLAGS+=("-march=native")
+            CMAKE_CXX_FLAGS+=("-march=native")
+            shift;;
        -c | --clean)
             CLEAN=1
             shift;;
@@ -193,9 +202,12 @@ function main() {
             clean_kernel
             echo_info "Erased iptables config and removed modules from kernel"
             shift;;
+       --cmake-opt)
+            CMAKE_CMD="$CMAKE_CMD $2"
+            shift 2;;
        -d | --build-dir)
             BUILD_DIR=$2
-            shift;;
+            shift 2;;
        -I | --install-external-packages)
             INSTALL_EXTERNAL=1
             echo_info "Will install external packages"
@@ -565,8 +577,7 @@ function main() {
       #fi
     fi
     echo_info "Installing protobuf/protobuf-c for flexran agent support"
-    install_protobuf_from_source
-    install_protobuf_c_from_source
+    install_protobuf_c
     echo_success "protobuf/protobuf-c installation successful"
   fi
 
@@ -575,19 +586,6 @@ function main() {
     check_install_additional_tools
   fi
 
-  
-  
-  echo_info "3. building the compilation directives ..."
-
-  DIR=$OPENAIR_DIR/cmake_targets
-
-  [ "$CLEAN" = "1" ] && rm -rf $DIR/$BUILD_DIR/build
-  mkdir -p $DIR/$BUILD_DIR/build
-
-  cd  $DIR/$BUILD_DIR/build
-  echo_info "running $CMAKE_CMD"
-  eval $CMAKE_CMD ../..
-
   execlist=""
   if [ "$eNB" = "1" ] ; then
       execlist="$execlist lte-softmodem"
@@ -607,10 +605,27 @@ function main() {
   if [ "$nrUE" = 1 ] ; then
       execlist="$execlist nr-uesoftmodem"
   fi
-  
   if [ "$ittiSIM" = "1" ] ; then
       execlist="$execlist nr-ittisim"
   fi
+
+  if [[ "$execlist" == "" && "$SIMUS_PHY" != "1" ]]; then
+    echo_success "installing dependencies successful"
+    exit
+  fi
+
+  echo_info "3. building the compilation directives ..."
+
+  DIR=$OPENAIR_DIR/cmake_targets
+
+  [ "$CLEAN" = "1" ] && rm -rf $DIR/$BUILD_DIR/build
+  mkdir -p $DIR/$BUILD_DIR/build
+
+  cd  $DIR/$BUILD_DIR/build
+  if [[ ${#CMAKE_C_FLAGS[@]} > 0 ]]; then CMAKE_CMD="$CMAKE_CMD -DCMAKE_C_FLAGS=\"${CMAKE_C_FLAGS[*]}\""; fi
+  if [[ ${#CMAKE_CXX_FLAGS[@]} > 0 ]]; then CMAKE_CMD="$CMAKE_CMD -DCMAKE_CXX_FLAGS=\"${CMAKE_CXX_FLAGS[*]}\""; fi
+  echo_info "running $CMAKE_CMD"
+  eval $CMAKE_CMD ../..
   
   for f in $execlist ; do
       echo_info "Compiling $f..."
diff --git a/cmake_targets/install_external_packages.ubuntu20 b/cmake_targets/install_external_packages.ubuntu20
deleted file mode 100755
index a2f6a9709c31e001bc3772ce9b4ff0dd4e5bfe18..0000000000000000000000000000000000000000
--- a/cmake_targets/install_external_packages.ubuntu20
+++ /dev/null
@@ -1,499 +0,0 @@
-#!/bin/bash
-#/*
-# * 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
-# */
-
-# brief
-# authors Laurent Thomas
-#
-#######################################
-
-if [ ! -f /etc/os-release ]; then
-    echo "No /etc/os-release file found. You're likely on an unsupported distro."
-    exit 1
-fi
-OS_DISTRO=$(grep "^ID=" /etc/os-release | sed "s/ID=//" | sed "s/\"//g")
-OS_RELEASE=$(grep "^VERSION_ID=" /etc/os-release | sed "s/VERSION_ID=//" | sed "s/\"//g")
-case "$OS_DISTRO" in
-    ubuntu) OS_BASEDISTRO="debian"; INSTALLER="apt"; CMAKE="cmake" ;;
-esac
-
-SUDO='sudo -E'
-
-###############################
-## echo and  family
-###############################
-black='\E[30m'
-red='\E[31m'
-green='\E[32m'
-yellow='\E[33m'
-blue='\E[1;34m'
-magenta='\E[35m'
-cyan='\E[36m'
-white='\E[37m'
-reset_color='\E[00m'
-COLORIZE=1
-
-cecho()  {
-    # Color-echo
-    # arg1 = message
-    # arg2 = color
-    local default_msg="No Message."
-    message=${1:-$default_msg}
-    color=${2:-$green}
-    [ "$COLORIZE" = "1" ] && message="$color$message$reset_color"
-    echo -e "$message"
-    return
-}
-
-echo_error()   { cecho "$* $red"          ;}
-echo_fatal()   { cecho "$* $red"; exit 1  ;}
-echo_warning() { cecho "$* $yellow"       ;}
-echo_success() { cecho "$* $green"        ;}
-echo_info()    { cecho "$* $blue"         ;}
-
-########################
-# distribution helpers #
-########################
-
-# This function return a string to identify the distribution we are running
-# Examples:
-#   ubuntu16.04
-#   debian8.5
-get_distribution_release() {
-    echo "$OS_DISTRO$OS_RELEASE"
-}
-
-check_supported_distribution() {
-    case $(get_distribution_release) in
-        "ubuntu20.04") return 0 ;;
-        "ubuntu20.10") return 0 ;;
-        "ubuntu21.04") return 0 ;;
-        "ubuntu21.10") return 0 ;;
-    esac
-    return 1
-}
-
-##################
-# Error handlers #
-##################
-
-handler_EXIT() {
-    local exit_code=$?
-    [ "$exit_code" -eq 0 ] || echo_error "build have failed"
-    exit $exit_code
-}
-
-trap handler_EXIT EXIT
-
-###########################
-# Cleaners
-###########################
-
-clean_kernel() {
-    $SUDO modprobe ip_tables
-    $SUDO modprobe x_tables
-    $SUDO iptables -P INPUT ACCEPT
-    $SUDO iptables -F INPUT
-    $SUDO iptables -P OUTPUT ACCEPT
-    $SUDO iptables -F OUTPUT
-    $SUDO iptables -P FORWARD ACCEPT
-    $SUDO iptables -F FORWARD
-    $SUDO iptables -t nat -F
-    $SUDO iptables -t mangle -F
-    $SUDO iptables -t filter -F
-    $SUDO iptables -t raw -F
-    echo_info "Flushed iptables"
-    $SUDO rmmod nasmesh > /dev/null 2>&1
-    $SUDO rmmod oai_nw_drv  > /dev/null 2>&1
-    $SUDO rmmod openair_rf > /dev/null 2>&1
-    $SUDO rmmod ue_ip > /dev/null 2>&1
-    echo_info "removed drivers from kernel"
-}
-
-clean_all_files() {
-    set_openair_env
-    rm -rf "$OPENAIR_DIR"/targets/bin/*
-    dir="$OPENAIR_DIR/cmake_targets"
-    rm -rf "$dir"/log/*
-    rm -rf "$dir"/ran_build/build
-    rm -rf "$dir"/ran_build_noLOG/build
-    rm -rf "$dir"/lte-simulators/build 
-    rm -rf "$dir"/nas_sim_tools/build 
-    rm -rf "$dir"/oaisim_build_oai/build
-    rm -rf "$dir"/oaisim_build_oai/CMakeLists.txt
-    rm -rf "$dir"/autotests/bin
-    rm -rf "$dir"/autotests/log
-    rm -rf "$dir"/autotests/*/build
-}
-
-############################################
-# External packages installers
-############################################
-
-install_protobuf_from_source(){
-    protobuf_install_log=$OPENAIR_DIR/cmake_targets/log/protobuf_install_log.txt
-    echo_info "\nInstalling Google Protobuf from sources. The log file for Protobuf installation is here: $protobuf_install_log "
-    (
-	cd /tmp || exit
-	echo "Downloading protobuf"
-	#rm -rf /tmp/protobuf-2.6.1.tar.gz* /tmp/protobuf-2.6.1
-	#wget https://github.com/protocolbuffers/protobuf/releases/download/v2.6.1/protobuf-2.6.1.tar.gz
-	#tar -xzvf protobuf-2.6.1.tar.gz --owner $USER --group $USER --no-same-owner
-	#cd protobuf-2.6.1/
-	rm -rf /tmp/protobuf-cpp-3.3.0.tar.gz* /tmp/protobuf-3.3.0
-	wget --tries=3 --retry-connrefused https://github.com/protocolbuffers/protobuf/releases/download/v3.3.0/protobuf-cpp-3.3.0.tar.gz
-	tar -xzvf protobuf-cpp-3.3.0.tar.gz --owner "$USER" --group "$(groups | cut -d" " -f1)" --no-same-owner
-	cd protobuf-3.3.0/ || exit
-	./configure
-	echo "Compiling protobuf"
-	make -j"$(nproc)"
-	$SUDO make install
-	$SUDO ldconfig
-    ) >& "$protobuf_install_log"
-}
-
-install_protobuf_c_from_source(){
-    protobuf_c_install_log=$OPENAIR_DIR/cmake_targets/log/protobuf_c_install_log.txt
-    echo_info "\nInstalling Google Protobuf_C from sources. The log file for Protobuf_C installation is here: $protobuf_c_install_log "
-    (
-	if [[ "$OS_DISTRO" == "rhel" ]] || [[ "$OS_DISTRO" == "centos" ]]; then
-            export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig
-	fi
-	cd /tmp || exit
-	echo "Downloading protobuf-c"
-	rm -rf /tmp/protobuf-c
-	git clone https://github.com/protobuf-c/protobuf-c.git
-	cd protobuf-c || exit
-	git checkout 2a46af42784abf86804d536f6e0122d47cfeea45
-	./autogen.sh
-	./configure
-	echo "Compiling protobuf-c"
-	make -j"$(nproc)"
-	$SUDO make install
-	$SUDO ldconfig
-    ) >& "$protobuf_c_install_log"
-}
-
-install_usrp_uhd_driver_from_source(){
-    uhd_install_log=$OPENAIR_DIR/cmake_targets/log/uhd_install_log.txt
-    echo_info "\nInstalling UHD driver from sources. The log file for UHD driver installation is here: $uhd_install_log "
-    (
-	cd /tmp || exit
-	echo "Downloading UHD driver"
-	rm -rf /tmp/uhd
-	git clone https://github.com/EttusResearch/uhd.git
-	cd uhd || exit
-	git checkout UHD-3.15.LTS
-	mkdir -p host/build
-	cd host/build || exit
-	$CMAKE ../ -GNinja
-	echo "Compiling UHD"
-	ninja
-	$SUDO ninja install
-	$SUDO ldconfig
-        $SUDO /usr/lib/uhd/utils/uhd_images_downloader.py
-    ) >& "$uhd_install_log"
-}
-
-install_bladerf_driver_from_source(){
-    bladerf_install_log=$OPENAIR_DIR/cmake_targets/log/bladerf_install_log.txt
-    echo_info "\nInstalling BladeRF driver from sources. The log file for BladeRF driver installation is here: $bladerf_install_log "
-    (
-	cd /tmp || exit
-	echo "Downloading BladeRF driver"
-	rm -rf /tmp/bladeRF
-	git clone https://github.com/Nuand/bladeRF.git
-	cd bladeRF || exit
-	git checkout tags/2016.06
-	mkdir -p build
-	cd build || exit
-	$CMAKE ../
-	echo "Compiling BladeRF driver"
-	make -j"$(nproc)"
-	$SUDO make install
-	$SUDO ldconfig
-	echo "Downloading FPGA and firmware images"
-	cd /tmp/bladeRF || exit
-	wget --tries=3 --retry-connrefused https://www.nuand.com/fx3/bladeRF_fw_latest.img
-	wget --tries=3 --retry-connrefused https://www.nuand.com/fpga/hostedx40-latest.rbf
-	sudo mkdir -p /usr/share/Nuand/bladeRF
-	sudo mv bladeRF_fw_latest.img /usr/share/Nuand/bladeRF/bladeRF_fw.img
-	sudo mv hostedx40-latest.rbf /usr/share/Nuand/bladeRF/hostedx40.rbf
-    ) >& "$bladerf_install_log"
-}
-
-check_install_bladerf_driver(){
-    if [[ "$OS_DISTRO" == "ubuntu" ]]; then
-        $SUDO apt-get install -y  bladerf libbladerf-dev
-        $SUDO apt-get install -y bladerf-firmware-fx3
-        $SUDO apt-get install -y bladerf-fpga-hostedx40
-    elif [[ "$OS_BASEDISTRO" == "fedora" ]]; then
-        install_bladerf_driver_from_source
-    else
-        echo_error "BladeRF Installer for OAI does not support automatic build. Install BladeRF compiling sources manually from BladeRF website"
-    fi
-}
-
-flash_firmware_bladerf() {
-    $SUDO bladeRF-cli --flash-firmware /usr/share/Nuand/bladeRF/bladeRF_fw.img
-}
-
-install_soapy_from_source(){
-    soapy_install_log=$OPENAIR_DIR/cmake_targets/log/soapy_install_log.txt
-    echo_info "\nInstalling Soapy EcoSystem from source. The log file for Soapy installation is here: $soapy_install_log "
-    (
-	cd /tmp || exit
-	echo "Downloading SoapySDR"
-	rm -rf /tmp/soapysdr
-	git clone -b soapy-sdr-0.7.0 --single-branch https://github.com/pothosware/SoapySDR.git
-	cd SoapySDR || exit
-	#git checkout tags/release_003_010_001_001
-	mkdir -p build
-	cd build || exit
-	$CMAKE ../
-	echo "Compiling SoapySDR"
-	make -j"$(nproc)"
-	$SUDO make install
-	$SUDO ldconfig
-	cd /tmp || exit
-	echo "Downloading SoapyRemote"
-	rm -rf /tmp/soapyremote
-	git clone -b soapy-remote-0.5.0 --single-branch https://github.com/pothosware/SoapyRemote.git
-	cd SoapyRemote || exit
-	#git checkout tags/release_003_010_001_001
-	mkdir -p build
-	cd build || exit
-	cmake ../
-	echo "Compiling SoapyRemote"
-	make -j"$(nproc)"
-	$SUDO make install
-	$SUDO ldconfig
-    ) >& "$soapy_install_log"
-}
-
-install_soapy_iris_from_source(){
-    iris_install_log=$OPENAIR_DIR/cmake_targets/log/iris_install_log.txt
-    echo_info "\nInstalling Iris driver from source. The log file for Iris driver installation is here: $iris_install_log "
-    (
-	cd /tmp || exit
-	echo "Downloading SoapyIris"
-	rm -rf /tmp/sklk-soapyiris
-	git clone -b soapy-iris-2018.08.0.1 --single-branch https://github.com/skylarkwireless/sklk-soapyiris.git
-	cd sklk-soapyiris || exit
-	mkdir -p build
-	cd build ||exit
-	cmake ../
-	echo "Compiling SoapyIris"
-	make -j"$(nproc)"
-	$SUDO make install
-	$SUDO ldconfig
-    ) >& "$iris_install_log"
-}
-
-check_install_soapy () {
-    #if [[ "$OS_DISTRO" == "ubuntu" ]]; then
-    #first we remove old installation
-    $SUDO apt-get remove -y soapysdr soapysdr-server libsoapysdr-dev python-soapysdr python3-soapysdr soapysdr-module-remote || true
-    #$SUDO add-apt-repository -y ppa:myriadrf/drivers
-    #$SUDO apt-get update
-    #$SUDO apt-get install -y soapysdr soapysdr-server libsoapysdr-dev python-soapysdr python3-soapysdr soapysdr-module-remote
-
-    #elif [[ "$OS_BASEDISTRO" == "fedora" ]]; then
-    #    $SUDO $INSTALLER -y install software-properties-common python3-software-properties python-software-properties subversion git python3 python-numpy python3-numpy cmake swig python-dev
-    install_soapy_from_source
-    #fi
-    install_soapy_iris_from_source
-    
-}
-
-check_install_ubuntu_packages() {
-    $SUDO $INSTALLER update -y
-    if [[ "$OS_DISTRO" == "ubuntu" ]]; then
-	local LAPACK_LIBNAME="liblapack.so"
-	local LAPACK_TARGET="/usr/lib/atlas-base/atlas/liblapack.so"
-	$SUDO apt install -y software-properties-common
-	case "$(get_distribution_release)" in
-            "ubuntu20.04")
-		specific_packages="libtasn1-6-dev libgnutls28-dev iproute2 libconfig-dev"
-		LAPACK_LIBNAME="liblapack.so-x86_64-linux-gnu"
-		LAPACK_TARGET="/usr/lib/x86_64-linux-gnu/atlas/liblapack.so"
-		;;
-            "ubuntu21.04")
-		specific_packages="libtasn1-6-dev libgnutls28-dev iproute2 libconfig-dev"
-		LAPACK_LIBNAME="liblapack.so-x86_64-linux-gnu"
-		LAPACK_TARGET="/usr/lib/x86_64-linux-gnu/atlas/liblapack.so"
-		;;
-	esac
-	$SUDO $INSTALLER install -y \
-	      $specific_packages \
-	      check  \
-              dialog \
-              dkms \
-              gawk \
-              libboost-all-dev \
-              libpthread-stubs0-dev \
-              openvpn \
-              pkg-config \
-              python3-dev  \
-              sshfs \
-              swig  \
-              tshark \
-              uml-utilities \
-              unzip  \
-              valgrind  \
-              vlan      \
-              exuberant-ctags \
-              ntpdate \
-              iperf3 \
-              android-tools-adb \
-              wvdial \
-              sshpass \
-              nscd \
-              bc \
-              ntp \
-              python3-scipy \
-              python3-matplotlib \
-	      bison  \
-	      build-essential \
-	      cmake \
-	      cmake-curses-gui  \
-              ninja-build \
-	      doxygen \
-	      doxygen-gui \
-	      texlive-latex-base \
-	      ethtool \
-	      flex  \
-	      gdb  \
-	      git \
-	      graphviz \
-	      gtkwave \
-	      iperf \
-	      iptables \
-	      libxtables-dev \
-	      libatlas-base-dev \
-	      libblas-dev \
-	      liblapack-dev\
-	      liblapacke-dev\
-	      libffi-dev \
-	      libforms-bin \
-	      libforms-dev \
-	      libgcrypt20-dev \
-	      libgmp-dev \
-	      libgtk-3-dev \
-	      libidn2-0-dev  \
-	      libidn11-dev \
-	      libmysqlclient-dev  \
-	      libpython2.7-dev \
-	      libsctp1  \
-	      libsctp-dev  \
-	      libssl-dev  \
-	      libtool  \
-	      libusb-1.0-0-dev \
-	      libxml2 \
-	      libxml2-dev  \
-	      libxslt1-dev \
-	      octave-signal \
-	      openssh-client \
-	      openssh-server \
-	      openssl \
-	      python3  \
-	      subversion \
-	      xmlstarlet \
-	      python3-pip \
-	      libyaml-dev \
-	      wget \
-	      libxpm-dev \
-              libboost-all-dev \
-	      nettle-dev \
-	      nettle-bin \
-              libreadline-dev
-    fi
-    
-    $SUDO update-alternatives --set "$LAPACK_LIBNAME" "$LAPACK_TARGET"
-    
-}
-
-install_asn1c_from_source(){
-    asn1_install_log=$OPENAIR_DIR/cmake_targets/log/asn1c_install_log.txt
-    echo_info "\nInstalling ASN1. The log file for ASN1 installation is here: $asn1_install_log "
-    (
-	$SUDO rm -rf /tmp/asn1c
-	# GIT_SSL_NO_VERIFY=true git clone https://gitlab.eurecom.fr/oai/asn1c.git /tmp/asn1c
-	git clone https://gitlab.eurecom.fr/oai/asn1c.git /tmp/asn1c
-	cd /tmp/asn1c || exit
-	# better to use a given commit than a branch in case the branch
-	# is updated and requires modifications in the source of OAI
-	#git checkout velichkov_s1ap_plus_option_group
-	git checkout f12568d617dbf48497588f8e227d70388fa217c9
-	autoreconf -iv
-	./configure
-	make -j"$(nproc)"
-	$SUDO make install
-	cd - || exit
-	$SUDO ldconfig
-    ) > "$asn1_install_log" 2>&1
-}
-
-################################
-# set_openair_env
-###############################
-set_openair_env(){
-    fullpath=$(readlink -f "${BASH_SOURCE[0]}")
-    [ -f "/.$fullpath" ] || fullpath=$(readlink -f "$PWD/$fullpath")
-    openair_path=${fullpath%/cmake_targets/*}
-    openair_path=${openair_path%/targets/*}
-    openair_path=${openair_path%/openair[123]/*}
-    export OPENAIR_DIR=$openair_path
-    export OPENAIR1_DIR=$openair_path/openair1
-    export OPENAIR2_DIR=$openair_path/openair2
-    export OPENAIR3_DIR=$openair_path/openair3
-    export OPENAIR_TARGETS=$openair_path/targets
-}
-
-if ! check_supported_distribution; then
-    echo_error "Your distribution $(get_distribution_release) is not supported by oai !"
-    exit 1
-fi
-set_openair_env
-echo_info "Installing packages"
-check_install_ubuntu_packages
-
-echo_info "installing ASN.1 compiler"
-install_asn1c_from_source
-
-echo_info "installing protobuf/protobuf-c for flexran agent support"
-install_protobuf_from_source
-install_protobuf_c_from_source
-
-if [ "$1" == "USRP" ] ; then
-    echo_info "installing packages for USRP support"
-    install_usrp_uhd_driver
-fi
-if [ "$1" == "BLADERF" ] ; then
-    echo_info "installing packages for BLADERF support"
-    check_install_bladerf_driver
-    flash_firmware_bladerf
-fi
-if [ "$1" == "IRIS" ] ; then
-    echo_info "installing packages for IRIS support"
-    check_install_soapy
-    #  flash_firmware_iris
-fi
diff --git a/cmake_targets/tools/build_helper b/cmake_targets/tools/build_helper
index 55a39c6b2b67e2aa47bf2a3f76efc48374990293..554f3ccfe52958d125007b82e8d5c7d4ac9e08b0 100755
--- a/cmake_targets/tools/build_helper
+++ b/cmake_targets/tools/build_helper
@@ -103,12 +103,12 @@ get_distribution_release() {
 check_supported_distribution() {
     local distribution=$(get_distribution_release)
     case "$distribution" in
+        "ubuntu22.04") return 0 ;;
+        "ubuntu21.04") return 0 ;;
+        "ubuntu20.04") return 0 ;;
         "ubuntu18.04") return 0 ;;
-        "ubuntu17.10") return 0 ;;
-        "ubuntu17.04") return 0 ;;
         "ubuntu16.04") return 0 ;;
-        "ubuntu14.04") return 0 ;;
-        "fedora24")    return 0 ;;
+        "fedora35")    return 0 ;;
         "rhel7")       return 0 ;;
         "rhel7.6")     return 0 ;;
         "rhel7.7")     return 0 ;;
@@ -315,6 +315,26 @@ install_protobuf_c_from_source(){
     ) >& $protobuf_c_install_log
 }
 
+install_protobuf_c() {
+  local protobuf_packages=""
+  case "$(get_distribution_release)" in
+    "ubuntu18.04" | "ubuntu20.04" | "ubuntu21.04" | "ubuntu22.04")
+      protobuf_packages="protobuf-c-compiler libprotobuf-c1 libprotobuf-c-dev"
+      ;;
+  esac
+  case "$OS_DISTRO" in
+    "rhel" | "centos" | "fedora") # in EPEL and Fedora repos (at least as of 35)
+      protobuf_packages="protobuf-c-compiler protobuf-c protobuf-c-devel"
+      ;;
+  esac
+  if [[ "$protobuf_packages" == "" ]]; then
+    install_protobuf_from_source
+    install_protobuf_c_from_source
+  else
+    $SUDO $INSTALLER -y install $protobuf_packages
+  fi
+}
+
 install_usrp_uhd_driver_from_source(){
     uhd_install_log=$OPENAIR_DIR/cmake_targets/log/uhd_install_log.txt
     echo_info "\nInstalling UHD driver from sources. The log file for UHD driver installation is here: $uhd_install_log "
@@ -471,10 +491,6 @@ install_bladerf_driver_from_source(){
 
 check_install_bladerf_driver(){
     if [[ "$OS_DISTRO" == "ubuntu" ]]; then
-        if [ "$(get_distribution_release)" == "ubuntu14.04" ] ; then
-            $SUDO add-apt-repository -y ppa:bladerf/bladerf
-            $SUDO apt-get update
-        fi
         $SUDO apt-get install -y  bladerf libbladerf-dev
         $SUDO apt-get install -y bladerf-firmware-fx3
         $SUDO apt-get install -y bladerf-fpga-hostedx40
@@ -574,7 +590,16 @@ check_install_soapy () {
 
 check_install_additional_tools (){
   $SUDO $INSTALLER update -y
+  local optional_packages=""
   if [[ "$OS_DISTRO" == "ubuntu" ]]; then
+    case "$(get_distribution_release)" in
+        "ubuntu16.04"| "ubuntu18.04")
+            optional_packages="python-dev python-pexpect python-numpy python-scipy python-matplotlib ctags"
+            ;;
+        "ubuntu20.04" | "ubuntu21.04" | "ubuntu22.04" )
+            optional_packages="python3 python3-pip python3-dev python3-scipy python3-matplotlib universal-ctags"
+            ;;
+    esac
     PACKAGE_LIST="\
 	check \
 	dialog \
@@ -584,8 +609,6 @@ check_install_additional_tools (){
 	libpthread-stubs0-dev \
 	openvpn \
 	pkg-config \
-	python-dev  \
-	python-pexpect \
 	sshfs \
 	swig  \
 	tshark \
@@ -593,18 +616,14 @@ check_install_additional_tools (){
 	unzip  \
 	valgrind  \
 	vlan	  \
-	ctags \
         ntpdate \
         iperf3 \
         android-tools-adb \
 	wvdial \
-        python-numpy \
         sshpass \
         nscd \
         bc \
-        ntp \
-        python-scipy \
-        python-matplotlib"
+        ntp"
   elif [[ "$OS_DISTRO" == "rhel" ]] || [[ "$OS_DISTRO" == "centos" ]]; then
     PACKAGE_LIST="\
       check \
@@ -650,22 +669,19 @@ check_install_additional_tools (){
       valgrind  \
       vconfig	  \
       ctags \
-      ntpdate \
+      ntpsec \
       iperf3 \
       wvdial \
       python-numpy \
       sshpass \
       nscd \
-      python2-paramiko \
+      python-paramiko \
       python-pyroute2 \
       python-netifaces \
-      python2-scipy \
-      python2-matplotlib"
+      python-scipy \
+      python-matplotlib"
   fi
-    $SUDO $INSTALLER install -y $PACKAGE_LIST
-
-    $SUDO rm -fr /opt/ssh
-    $SUDO GIT_SSL_NO_VERIFY=true git clone https://gitlab.eurecom.fr/oai/ssh.git /opt/ssh
+    $SUDO $INSTALLER install -y $PACKAGE_LIST $optional_packages
 
   #The packages below are already installed for Redhat distros (RHEL, CentOS, Fedora)
   if [[ "$OS_DISTRO" == "ubuntu" ]]; then
@@ -696,25 +712,26 @@ check_install_oai_software() {
     local LAPACK_TARGET="/usr/lib/atlas-base/atlas/liblapack.so"
     $SUDO apt install -y software-properties-common
     case "$(get_distribution_release)" in
-        "ubuntu14.04")
-            specific_packages="libtasn1-3-dev libgnutls-dev libatlas-dev iproute libconfig8-dev"
-            # For iperf3
-            $SUDO add-apt-repository "deb http://archive.ubuntu.com/ubuntu trusty-backports universe"
-            $SUDO apt-get update
-            ;;
         "ubuntu16.04")
-            specific_packages="libtasn1-6-dev libgnutls-dev libatlas-dev iproute libconfig8-dev"
+            specific_packages="libtasn1-6-dev libgnutls-dev libatlas-dev iproute libconfig8-dev iptables-dev libgcrypt11-dev python-pip pydb python guile-2.0-dev"
             ;;
-        "ubuntu17.04")
-            specific_packages="libtasn1-6-dev libgnutls28-dev libatlas-dev iproute libconfig8-dev"
+        "ubuntu18.04")
+            specific_packages="libtasn1-6-dev libgnutls28-dev iproute2 libconfig-dev iptables-dev libgcrypt11-dev python-pip pydb python guile-2.0-dev"
+            LAPACK_LIBNAME="liblapack.so-x86_64-linux-gnu"
+            LAPACK_TARGET="/usr/lib/x86_64-linux-gnu/atlas/liblapack.so"
             ;;
-        "ubuntu17.10")
-            specific_packages="libtasn1-6-dev libgnutls28-dev iproute libconfig8-dev"
+        "ubuntu20.04")
+            specific_packages="libtasn1-6-dev libgnutls28-dev iproute2 libconfig-dev python guile-2.0-dev"
             LAPACK_LIBNAME="liblapack.so-x86_64-linux-gnu"
             LAPACK_TARGET="/usr/lib/x86_64-linux-gnu/atlas/liblapack.so"
             ;;
-        "ubuntu18.04")
-            specific_packages="libtasn1-6-dev libgnutls28-dev iproute2 libconfig-dev"
+         "ubuntu21.04")
+            specific_packages="libtasn1-6-dev libgnutls28-dev iproute2 libconfig-dev python guile-2.0-dev"
+            LAPACK_LIBNAME="liblapack.so-x86_64-linux-gnu"
+            LAPACK_TARGET="/usr/lib/x86_64-linux-gnu/atlas/liblapack.so"
+            ;;
+         "ubuntu22.04")
+            specific_packages="libtasn1-6-dev libgnutls28-dev iproute2 libconfig-dev python2 guile-2.2-dev"
             LAPACK_LIBNAME="liblapack.so-x86_64-linux-gnu"
             LAPACK_TARGET="/usr/lib/x86_64-linux-gnu/atlas/liblapack.so"
             ;;
@@ -734,22 +751,21 @@ check_install_oai_software() {
 	texlive-latex-base \
 	ethtool \
 	flex  \
+        g++ \
+        gcc \
 	gdb  \
 	git \
 	graphviz \
 	gtkwave \
-	guile-2.0-dev  \
 	iperf \
 	iptables \
-	iptables-dev \
 	libatlas-base-dev \
 	libblas-dev \
-  liblapack-dev\
-  liblapacke-dev\
+	liblapack-dev \
+	liblapacke-dev \
 	libffi-dev \
 	libforms-bin \
 	libforms-dev \
-	libgcrypt11-dev \
 	libgmp-dev \
 	libgtk-3-dev \
 	libidn2-0-dev  \
@@ -769,11 +785,8 @@ check_install_oai_software() {
 	openssh-client \
 	openssh-server \
 	openssl \
-	python  \
 	subversion \
 	xmlstarlet \
-	python-pip \
-	pydb \
 	libyaml-dev \
 	wget \
 	libxpm-dev \
@@ -791,8 +804,6 @@ check_install_oai_software() {
         $SUDO $INSTALLER install -y https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
       fi
       $SUDO $INSTALLER install -y python-epdb vim-common
-    else
-      $SUDO $INSTALLER install -y pydb
     fi
 
     $SUDO $INSTALLER install -y \
@@ -804,6 +815,8 @@ check_install_oai_software() {
       doxygen \
       ethtool \
       flex \
+      g++ \
+      gcc \
       gdb \
       git \
       graphviz \
@@ -860,8 +873,6 @@ check_install_oai_software() {
   fi
 
     install_asn1c_from_source $1
-    $SUDO rm -fr /opt/ssh
-    $SUDO git clone https://gist.github.com/2190472.git /opt/ssh
 }
 
 install_asn1c_from_source(){
@@ -955,23 +966,3 @@ do
         fi
 done
 }
-
-
-# get from http://www.linuxjournal.com/content/validating-ip-address-bash-script
-validate_ip() {
-
-local  ip=$1
-local  stat=1
-
-if [[ $ip =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then
-    OIFS=$IFS
-    IFS='.'
-    ip=($ip)
-    IFS=$OIFS
-    [[ ${ip[0]} -le 255 && ${ip[1]} -le 255 \
-        && ${ip[2]} -le 255 && ${ip[3]} -le 255 ]]
-    stat=$?
-fi
-
-return $stat
-}
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/system.c b/common/utils/system.c
index d8970631446dc4b112b65af896f111120b40fcf5..00839b485ca15aa0534c2cfa52d1421ccc375c71 100644
--- a/common/utils/system.c
+++ b/common/utils/system.c
@@ -234,9 +234,10 @@ void threadCreate(pthread_t* t, void * (*func)(void*), void * param, char* name,
   ret=pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
   AssertFatal(ret==0,"ret: %d, errno: %d\n",ret, errno);
   
-  if (system("grep -iq 'ID_LIKE.*fedora' /etc/os-release && uname -a | grep -c rt")==0)
-      if (system("cat /proc/self/cgroup | egrep -c 'libpod|podman|kubepods'")==0)
-	settingPriority = 0;
+  if (checkIfFedoraDistribution())
+    if (checkIfGenericKernelOnFedora())
+      if (checkIfInsideContainer())
+        settingPriority = 0;
   
   if (settingPriority) {
     ret=pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
diff --git a/doc/BUILD.md b/doc/BUILD.md
index 852a2486595740315eb6b6427c43f40e514969a3..a52ce98cb53f7df132d6b55d64902b32fb7c1036 100644
--- a/doc/BUILD.md
+++ b/doc/BUILD.md
@@ -77,7 +77,7 @@ cd cmake_targets/
 ./build_oai -I -w USRP --eNB --UE --nrUE --gNB
 ```
 
-- The `-I` option is to install pre-requisites, you only need it the first time you build the softmodem or when some oai dependencies have changed. Note: for Ubuntu 20 use cmake_targets/install_external_packages.ubuntu20 instead!
+- The `-I` option is to install pre-requisites, you only need it the first time you build the softmodem or when some oai dependencies have changed.
 - The `-w` option is to select the radio head support you want to include in your build. Radio head support is provided via a shared library, which is called the "oai device" The build script creates a soft link from `liboai_device.so` to the true device which will be used at run-time (here the USRP one,`liboai_usrpdevif.so` . USRP is the only hardware tested today in the Continuous Integration process. The RF simulator[RF simulator](../targets/ARCH/rfsimulator/README.md) is implemented as a specific device replacing RF hardware, it can be specifically built using `-w SIMU` option, but is also built during any softmodem build.
 - `--eNB` is to build the `lte-softmodem` executable and all required shared libraries
 - `--gNB` is to build the `nr-softmodem` executable and all required shared libraries
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/docker/Dockerfile.eNB.rhel8.2 b/docker/Dockerfile.eNB.rhel8.2
index 7924f5bd78844f99c7603f79a5f31f218945491b..5296ac21726320bc65c1b847b2aef2d6fd6db0bd 100644
--- a/docker/Dockerfile.eNB.rhel8.2
+++ b/docker/Dockerfile.eNB.rhel8.2
@@ -96,7 +96,7 @@ COPY --from=enb-base \
 
 # Now we are copying from builder-image the UHD files.
 COPY --from=enb-base /usr/local/bin/uhd_find_devices /usr/local/bin
-COPY --from=enb-base /usr/local/lib/libprotobuf-c.so.1 /usr/local/lib
+COPY --from=enb-base /usr/lib64/libprotobuf-c.so.1 /usr/local/lib
 COPY --from=enb-base /usr/local/lib64/libuhd.so.3.15.0 /usr/local/lib64
 COPY --from=enb-base /usr/local/lib64/uhd/utils/uhd_images_downloader.py /opt/oai-enb/bin
 
diff --git a/docker/Dockerfile.eNB.ubuntu18 b/docker/Dockerfile.eNB.ubuntu18
index 222a7f42bbac0cf7f0c61c6fc86cc264f1db6adb..f95a03398a1dbae54847536761ce06cb18053969 100644
--- a/docker/Dockerfile.eNB.ubuntu18
+++ b/docker/Dockerfile.eNB.ubuntu18
@@ -83,7 +83,7 @@ COPY --from=enb-build \
 COPY --from=enb-base /usr/local/bin/uhd_find_devices /usr/local/bin
 COPY --from=enb-base \
      /usr/local/lib/libuhd.so.3.15.0 \
-     /usr/local/lib/libprotobuf-c.so.1 \
+     /usr/lib/x86_64-linux-gnu/libprotobuf-c.so.1 \
      /usr/local/lib/
 COPY --from=enb-base /usr/local/lib/uhd/utils/uhd_images_downloader.py /opt/oai-enb/bin
 COPY --from=enb-base \
diff --git a/docker/Dockerfile.gNB.rhel8.2 b/docker/Dockerfile.gNB.rhel8.2
index 6a1b447a6253941542614a0e49d1f994d727e221..9ec7ee755691ca2ce5a15494e943cd461edf576b 100644
--- a/docker/Dockerfile.gNB.rhel8.2
+++ b/docker/Dockerfile.gNB.rhel8.2
@@ -100,7 +100,7 @@ COPY --from=gnb-base \
 
 # Now we are copying from builder-image the UHD files.
 COPY --from=gnb-base /usr/local/bin/uhd_find_devices /usr/local/bin
-COPY --from=gnb-base /usr/local/lib/libprotobuf-c.so.1 /usr/local/lib
+COPY --from=gnb-base /usr/lib64/libprotobuf-c.so.1 /usr/local/lib
 COPY --from=gnb-base /usr/local/lib64/libuhd.so.3.15.0 /usr/local/lib64
 COPY --from=gnb-base /usr/local/lib64/uhd/utils/uhd_images_downloader.py /opt/oai-gnb/bin
 
diff --git a/docker/Dockerfile.gNB.ubuntu18 b/docker/Dockerfile.gNB.ubuntu18
index 6f990db833575f21f519d1cc6f909c11a636e299..6a98c8d3ce260142d4c459d2bccb01f803b372f3 100644
--- a/docker/Dockerfile.gNB.ubuntu18
+++ b/docker/Dockerfile.gNB.ubuntu18
@@ -84,7 +84,7 @@ COPY --from=gnb-build \
 COPY --from=gnb-base /usr/local/bin/uhd_find_devices /usr/local/bin
 COPY --from=gnb-base \
      /usr/local/lib/libuhd.so.3.15.0 \
-     /usr/local/lib/libprotobuf-c.so.1 \
+     /usr/lib/x86_64-linux-gnu/libprotobuf-c.so.1 \
      /usr/local/lib/
 COPY --from=gnb-base /usr/local/lib/uhd/utils/uhd_images_downloader.py /opt/oai-gnb/bin
 COPY --from=gnb-base \
diff --git a/docker/Dockerfile.lteUE.rhel8.2 b/docker/Dockerfile.lteUE.rhel8.2
index cc1be3d41d5c68e93be5298f89401db25cf59ca3..ab7d22493992daee89a9eec3908aa828b8f4a23d 100644
--- a/docker/Dockerfile.lteUE.rhel8.2
+++ b/docker/Dockerfile.lteUE.rhel8.2
@@ -98,7 +98,7 @@ COPY --from=lte-ue-base \
 
 # Now we are copying from builder-image the UHD files.
 COPY --from=lte-ue-base /usr/local/bin/uhd_find_devices /usr/local/bin
-COPY --from=lte-ue-base /usr/local/lib/libprotobuf-c.so.1 /usr/local/lib
+COPY --from=lte-ue-base /usr/lib64/libprotobuf-c.so.1 /usr/local/lib
 COPY --from=lte-ue-base /usr/local/lib64/libuhd.so.3.15.0 /usr/local/lib64
 COPY --from=lte-ue-base /usr/local/lib64/uhd/utils/uhd_images_downloader.py /opt/oai-lte-ue/bin
 
diff --git a/docker/Dockerfile.lteUE.ubuntu18 b/docker/Dockerfile.lteUE.ubuntu18
index 292ac37e5f0f09520fbfb7fa2cda5ede1ca0291c..b2a0fd6e93dda25990d49a57a9b0452f9061d2b1 100644
--- a/docker/Dockerfile.lteUE.ubuntu18
+++ b/docker/Dockerfile.lteUE.ubuntu18
@@ -86,7 +86,7 @@ COPY --from=lte-ue-build \
 COPY --from=lte-ue-base /usr/local/bin/uhd_find_devices /usr/local/bin
 COPY --from=lte-ue-base \
      /usr/local/lib/libuhd.so.3.15.0 \
-     /usr/local/lib/libprotobuf-c.so.1 \
+     /usr/lib/x86_64-linux-gnu/libprotobuf-c.so.1 \
      /usr/local/lib/
 COPY --from=lte-ue-base /usr/local/lib/uhd/utils/uhd_images_downloader.py /opt/oai-lte-ue/bin
 
diff --git a/docker/Dockerfile.nrUE.rhel8.2 b/docker/Dockerfile.nrUE.rhel8.2
index d38e81bd71eec16ce5782c29ff2a21a8dfc3ad8e..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 \
@@ -103,7 +107,7 @@ COPY --from=nr-ue-base \
 
 # Now we are copying from builder-image the UHD files.
 COPY --from=nr-ue-base /usr/local/bin/uhd_find_devices /usr/local/bin
-COPY --from=nr-ue-base /usr/local/lib/libprotobuf-c.so.1 /usr/local/lib
+COPY --from=nr-ue-base /usr/lib64/libprotobuf-c.so.1 /usr/local/lib
 COPY --from=nr-ue-base /usr/local/lib64/libuhd.so.3.15.0 /usr/local/lib64
 COPY --from=nr-ue-base /usr/local/lib64/uhd/utils/uhd_images_downloader.py /opt/oai-nr-ue/bin
 
@@ -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 0fa219296b7b7e52327b46baf190c630ec5a5b0f..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 \
@@ -88,7 +92,7 @@ COPY --from=nr-ue-build \
 COPY --from=nr-ue-base /usr/local/bin/uhd_find_devices /usr/local/bin
 COPY --from=nr-ue-base \
      /usr/local/lib/libuhd.so.3.15.0 \
-     /usr/local/lib/libprotobuf-c.so.1 \
+     /usr/lib/x86_64-linux-gnu/libprotobuf-c.so.1 \
      /usr/local/lib/
 COPY --from=nr-ue-base /usr/local/lib/uhd/utils/uhd_images_downloader.py /opt/oai-nr-ue/bin
 
@@ -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 4793ef4e95fc7a0e78d280ee0c07bb93ac95f71f..ff0d3c5a4786e6bef0a7016d7ab6ae1ad9e1aac7 100644
--- a/executables/nr-gnb.c
+++ b/executables/nr-gnb.c
@@ -63,7 +63,7 @@
 
 #include "PHY/phy_extern.h"
 
-#include "LAYER2/NR_MAC_COMMON/nr_mac_extern.h"
+#include "common/ran_context.h"
 #include "RRC/LTE/rrc_extern.h"
 #include "PHY_INTERFACE/phy_interface.h"
 #include "common/utils/LOG/log_extern.h"
@@ -75,7 +75,6 @@
 #include "enb_config.h"
 #include "gnb_paramdef.h"
 
-
 #include "s1ap_eNB.h"
 #include "SIMULATION/ETH_TRANSPORT/proto.h"
 #include <executables/softmodem-common.h>
@@ -518,7 +517,8 @@ void init_eNB_afterRU(void) {
     RC.nb_nr_inst = 1;
   for (inst=0; inst<RC.nb_nr_inst; inst++) {
     LOG_I(PHY,"RC.nb_nr_CC[inst:%d]:%p\n", inst, RC.gNB[inst]);
-    gNB                                  =  RC.gNB[inst];
+    gNB = RC.gNB[inst];
+
     phy_init_nr_gNB(gNB,0,0);
 
     // map antennas and PRACH signals to gNB RX
diff --git a/executables/nr-ue.c b/executables/nr-ue.c
index 3cc71b8b3a0f3ef9d577176e64ab1f404557fe3c..65b74a0218a539c504b83b506c6ea7c80e491fa1 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;
 }
diff --git a/executables/nr-uesoftmodem.c b/executables/nr-uesoftmodem.c
index 00f019c03ae82bb64ddd5c18ab897d1575150d71..46fa515e0d2d050d1ccd4679c0beab3afd3b8de8 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 -----------------------------*/
 
@@ -250,7 +254,6 @@ void init_tpools(uint8_t nun_dlsch_threads) {
   free(params);
   init_dlsch_tpool( nun_dlsch_threads);
 }
-
 static void get_options(void) {
 
   nrUE_params.ofdm_offset_divisor = 8;
@@ -396,7 +399,14 @@ void *rrc_enb_process_msg(void *notUsed) {
 
 
 int main( int argc, char **argv ) {
-  set_priority(79);
+  int set_exe_prio = 1;
+  if (checkIfFedoraDistribution())
+    if (checkIfGenericKernelOnFedora())
+      if (checkIfInsideContainer())
+        set_exe_prio = 0;
+  if (set_exe_prio)
+    set_priority(79);
+
   if (mlockall(MCL_CURRENT | MCL_FUTURE) == -1)
   {
     fprintf(stderr, "mlockall: %s\n", strerror(errno));
@@ -465,6 +475,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)
@@ -545,3 +556,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/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 44a816f5c6e66f652f896a19f128632b111b3638..a833d41a829d1881f3b0fd0432325366f3746adb 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
@@ -467,7 +467,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/INIT/nr_init.c b/openair1/PHY/INIT/nr_init.c
index ff3bdf3b8e2a9f91c2434d46901f71e04227c19c..9ffc0f75ad345c7e2b12f77c62fca1885d4025a6 100644
--- a/openair1/PHY/INIT/nr_init.c
+++ b/openair1/PHY/INIT/nr_init.c
@@ -38,7 +38,7 @@
 #include "openair1/PHY/CODING/nrLDPC_extern.h"
 #include "assertions.h"
 #include <math.h>
-
+#include <complex.h>
 #include "PHY/NR_TRANSPORT/nr_ulsch.h"
 #include "PHY/NR_REFSIG/nr_refsig.h"
 #include "SCHED_NR/fapi_nr_l1.h"
@@ -71,6 +71,407 @@ int l1_north_init_gNB() {
   return(0);
 }
 
+int init_codebook_gNB(PHY_VARS_gNB *gNB) {
+
+  if(gNB->frame_parms.nb_antennas_tx>1){
+    int CSI_RS_antenna_ports = gNB->frame_parms.nb_antennas_tx;
+    //NR Codebook Generation for codebook type1 SinglePanel
+    int N1 = gNB->ap_N1;
+    int N2 = gNB->ap_N2;
+    //Uniform Planner Array: UPA
+    //    X X X X ... X
+    //    X X X X ... X
+    // N2 . . . . ... .
+    //    X X X X ... X
+    //   |<-----N1---->|
+    int x_polarization = gNB->ap_XP;
+    //Get the uniform planar array parameters
+    // To be confirmed
+    int O2 = N2 > 1? 4 : 1; //Vertical beam oversampling (1 or 4)
+    int O1 = CSI_RS_antenna_ports > 2 ? 4 : 1; //Horizontal beam oversampling (1 or 4)
+    AssertFatal(CSI_RS_antenna_ports == N1*N2*x_polarization,
+                "Nb of antenna ports at PHY %d does not correspond to what passed down with fapi %d\n",
+                 N1*N2*x_polarization, CSI_RS_antenna_ports);
+
+    // Generation of codebook Type1 with codebookMode 1 (CSI_RS_antenna_ports < 16)
+    if (CSI_RS_antenna_ports < 16) {
+      //Generate DFT vertical beams
+      //ll: index of a vertical beams vector (represented by i1_1 in TS 38.214)
+      double complex v[N1*O1][N1];
+      for (int ll=0; ll<N1*O1; ll++) { //i1_1
+        for (int nn=0; nn<N1; nn++) {
+          v[ll][nn] = cexp(I*(2*M_PI*nn*ll)/(N1*O1));
+          //printf("v[%d][%d] = %f +j %f\n", ll,nn, creal(v[ll][nn]),cimag(v[ll][nn]));
+        }
+      }
+      //Generate DFT Horizontal beams
+      //mm: index of a Horizontal beams vector (represented by i1_2 in TS 38.214)
+      double complex u[N2*O2][N2];
+      for (int mm=0; mm<N2*O2; mm++) { //i1_2
+        for (int nn=0; nn<N2; nn++) {
+          u[mm][nn] = cexp(I*(2*M_PI*nn*mm)/(N2*O2));
+              //printf("u[%d][%d] = %f +j %f\n", mm,nn, creal(u[mm][nn]),cimag(u[mm][nn]));
+        }
+      }
+      //Generate co-phasing angles
+      //i_2: index of a co-phasing vector
+      //i1_1, i1_2, and i_2 are reported from UEs
+      double complex theta_n[4];
+      for (int nn=0; nn<4; nn++) {
+        theta_n[nn] = cexp(I*M_PI*nn/2);
+        //printf("theta_n[%d] = %f +j %f\n", nn, creal(theta_n[nn]),cimag(theta_n[nn]));
+      }
+      //Kronecker product v_lm
+      double complex v_lm[N1*O1][N2*O2][N2*N1];
+      //v_ll_mm_codebook denotes the elements of a precoding matrix W_i1,1_i_1,2
+      for(int ll=0; ll<N1*O1; ll++) { //i_1_1
+        for (int mm=0; mm<N2*O2; mm++) { //i_1_2
+          for (int nn1=0; nn1<N1; nn1++) {
+            for (int nn2=0; nn2<N2; nn2++) {
+              //printf("indx %d \n",nn1*N2+nn2);
+              v_lm[ll][mm][nn1*N2+nn2] = v[ll][nn1]*u[mm][nn2];
+              //printf("v_lm[%d][%d][%d] = %f +j %f\n",ll,mm, nn1*N2+nn2, creal(v_lm[ll][mm][nn1*N2+nn2]),cimag(v_lm[ll][mm][nn1*N2+nn2]));
+            }
+          }
+        }
+      }
+
+      int max_mimo_layers =(CSI_RS_antenna_ports<NR_MAX_NB_LAYERS) ? CSI_RS_antenna_ports : NR_MAX_NB_LAYERS;
+
+      gNB->nr_mimo_precoding_matrix = (int32_t ***)malloc16(max_mimo_layers* sizeof(int32_t **));
+      int32_t ***mat = gNB->nr_mimo_precoding_matrix;
+      double complex res_code;
+
+      //Table 5.2.2.2.1-5:
+      //Codebook for 1-layer CSI reporting using antenna ports 3000 to 2999+PCSI-RS
+      gNB->pmiq_size[0] = N1*O1*N2*O2*4+1;
+      mat[0] = (int32_t **)malloc16(gNB->pmiq_size[0]*sizeof(int32_t *));
+
+      //pmi=0 corresponds to unit matrix
+      mat[0][0] = (int32_t *)calloc(2*N1*N2,sizeof(int32_t));
+      for(int j_col=0; j_col<1; j_col++) { //1 layer
+        for (int i_rows=0; i_rows<2*N1*N2; i_rows++) { //2-x polarized antenna
+          if(j_col==i_rows) {
+            mat[0][0][i_rows+j_col] = 0x7fff;
+          }
+        }
+      }
+
+      for(int ll=0; ll<N1*O1; ll++) { //i_1_1
+        for (int mm=0; mm<N2*O2; mm++) { //i_1_2
+          for (int nn=0; nn<4; nn++) {
+            int pmiq = 1+ll*N2*O2*4+mm*4+nn;
+            mat[0][pmiq] = (int32_t *)malloc16((2*N1*N2)*1*sizeof(int32_t));
+            LOG_D(PHY, "layer 1 Codebook pmiq = %d\n",pmiq);
+            for (int len=0; len<N1*N2; len++) {
+              res_code=sqrt(1/(double)CSI_RS_antenna_ports)*v_lm[ll][mm][len];
+              if (creal(res_code)>0)
+                ((short*) &mat[0][pmiq][len])[0] = (short) ((creal(res_code)*32768)+0.5);//convert to Q15
+              else
+                ((short*) &mat[0][pmiq][len])[0] = (short) ((creal(res_code)*32768)-0.5);//convert to Q15
+              if (cimag(res_code)>0)
+                ((short*) &mat[0][pmiq][len])[1] = (short) ((cimag(res_code)*32768)+0.5);//convert to Q15
+              else
+                ((short*) &mat[0][pmiq][len])[1] = (short) ((cimag(res_code)*32768)-0.5);//convert to Q15
+              LOG_D(PHY, "1 Layer Precoding Matrix[0][pmi %d][antPort %d]= %f+j %f -> Fixed Point %d+j %d \n",
+                    pmiq, len, creal(res_code), cimag(res_code),((short*) &mat[0][pmiq][len])[0],((short*) &mat[0][pmiq][len])[1]);
+            }
+
+            for(int len=N1*N2; len<2*N1*N2; len++) {
+              res_code=sqrt(1/(double)CSI_RS_antenna_ports)*theta_n[nn]*v_lm[ll][mm][len-N1*N2];
+              if (creal(res_code)>0)
+                ((short*) &mat[0][pmiq][len])[0] = (short) ((creal(res_code)*32768)+0.5);//convert to Q15
+              else
+                ((short*) &mat[0][pmiq][len])[0] = (short) ((creal(res_code)*32768)-0.5);//convert to Q15
+              if (cimag(res_code)>0)
+                ((short*) &mat[0][pmiq][len])[1] = (short) ((cimag(res_code)*32768)+0.5);//convert to Q15
+              else
+                ((short*) &mat[0][pmiq][len])[1] = (short) ((cimag(res_code)*32768)-0.5);//convert to Q15
+              LOG_D(PHY, "1 Layer Precoding Matrix[0][pmi %d][antPort %d]= %f+j %f -> Fixed Point %d+j %d \n",
+                    pmiq, len, creal(res_code), cimag(res_code),((short*) &mat[0][pmiq][len])[0],((short*) &mat[0][pmiq][len])[1]);
+            }
+          }
+        }
+      }
+
+      int llc;
+      int mmc;
+      double complex phase_sign;
+      //Table 5.2.2.2.1-6:
+      //Codebook for 2-layer CSI reporting using antenna ports 3000 to 2999+PCSI-RS
+      //Compute the code book size for generating 2 layers out of Tx antenna ports
+
+      //pmi_size is computed as follows
+      gNB->pmiq_size[1] = 1;//1 for unity matrix
+      for(int llb=0; llb<N1*O1; llb++) { //i_1_1
+        for (int mmb=0; mmb<N2*O2; mmb++) { //i_1_2
+          for(int ll=0; ll<N1*O1; ll++) { //i_1_1
+            for (int mm=0; mm<N2*O2; mm++) { //i_1_2
+              for (int nn=0; nn<2; nn++) {
+                if((llb != ll) || (mmb != mm) || ((N1 == 1) && (N2 == 1))) gNB->pmiq_size[1] += 1;
+              }
+            }
+          }
+        }
+      }
+      mat[1] = (int32_t **)malloc16(gNB->pmiq_size[1]*sizeof(int32_t *));
+
+      //pmi=0 corresponds to unit matrix
+      mat[1][0] = (int32_t *)calloc((2*N1*N2)*(2),sizeof(int32_t));
+      for(int j_col=0; j_col<2; j_col++) { //2 layers
+        for (int i_rows=0; i_rows<2*N1*N2; i_rows++) { //2-x polarized antenna
+          if(j_col==i_rows) {
+            mat[1][0][i_rows*2+j_col] = 0x7fff;
+          }
+        }
+      }
+
+      //pmi=1,...,pmi_size, we construct
+      int pmiq = 0;
+      for(int llb=0; llb<N1*O1; llb++) { //i_1_1
+        for (int mmb=0; mmb<N2*O2; mmb++) { //i_1_2
+          for(int ll=0; ll<N1*O1; ll++) { //i_1_1
+            for (int mm=0; mm<N2*O2; mm++) { //i_1_2
+              for (int nn=0; nn<2; nn++) {
+                if((llb != ll) || (mmb != mm) || ((N1 == 1) && (N2 == 1))){
+                  pmiq += 1;
+                  mat[1][pmiq] = (int32_t *)malloc16((2*N1*N2)*(2)*sizeof(int32_t));
+                  LOG_I(PHY, "layer 2 Codebook pmiq = %d\n",pmiq);
+                  for(int j_col=0; j_col<2; j_col++) {
+                    if (j_col==0) {
+                      llc = llb;
+                      mmc = mmb;
+                      phase_sign = 1;
+                    }
+                    if (j_col==1) {
+                      llc = ll;
+                      mmc = mm;
+                      phase_sign = -1;
+                    }
+                    for (int i_rows=0; i_rows<N1*N2; i_rows++) {
+                      res_code=sqrt(1/(double)(2*CSI_RS_antenna_ports))*v_lm[llc][mmc][i_rows];
+                      if (creal(res_code)>0)
+                        ((short*) &mat[1][pmiq][i_rows*2+j_col])[0] = (short) ((creal(res_code)*32768)+0.5);//convert to Q15
+                      else
+                        ((short*) &mat[1][pmiq][i_rows*2+j_col])[0] = (short) ((creal(res_code)*32768)-0.5);//convert to Q15
+                      if (cimag(res_code)>0)
+                        ((short*) &mat[1][pmiq][i_rows*2+j_col])[1] = (short) ((cimag(res_code)*32768)+0.5);//convert to Q15
+                      else
+                        ((short*) &mat[1][pmiq][i_rows*2+j_col])[1] = (short) ((cimag(res_code)*32768)-0.5);//convert to Q15
+                      LOG_D(PHY, "2 Layer Precoding Matrix[1][pmi %d][antPort %d][layerIdx %d]= %f+j %f -> Fixed Point %d+j %d \n",
+                            pmiq,i_rows,j_col, creal(res_code), cimag(res_code),((short*) &mat[1][pmiq][i_rows*2+j_col])[0],((short*) &mat[1][pmiq][i_rows*2+j_col])[1]);
+                    }
+                    for (int i_rows=N1*N2; i_rows<2*N1*N2; i_rows++) {
+                      res_code=sqrt(1/(double)(2*CSI_RS_antenna_ports))*(phase_sign)*theta_n[nn]*v_lm[llc][mmc][i_rows-N1*N2];
+                      if (creal(res_code)>0)
+                        ((short*) &mat[1][pmiq][i_rows*2+j_col])[0] = (short) ((creal(res_code)*32768)+0.5);//convert to Q15
+                      else
+                        ((short*) &mat[1][pmiq][i_rows*2+j_col])[0] = (short) ((creal(res_code)*32768)-0.5);//convert to Q15
+                      if (cimag(res_code)>0)
+                        ((short*) &mat[1][pmiq][i_rows*2+j_col])[1] = (short) ((cimag(res_code)*32768)+0.5);//convert to Q15
+                      else
+                        ((short*) &mat[1][pmiq][i_rows*2+j_col])[1] = (short) ((cimag(res_code)*32768)-0.5);//convert to Q15
+                      LOG_D(PHY, "2 Layer Precoding Matrix[1][pmi %d][antPort %d][layerIdx %d]= %f+j %f -> Fixed Point %d+j %d \n",
+                            pmiq,i_rows,j_col, creal(res_code), cimag(res_code),((short*) &mat[1][pmiq][i_rows*2+j_col])[0],((short*) &mat[1][pmiq][i_rows*2+j_col])[1]);
+                    }
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+
+      //Table 5.2.2.2.1-7:
+      //Codebook for 3-layer CSI reporting using antenna ports 3000 to 2999+PCSI-RS
+      if(max_mimo_layers>=3) {
+
+        //pmi_size is computed as follows
+        gNB->pmiq_size[2] = 1;//unity matrix
+        for(int llb=0; llb<N1*O1; llb++) { //i_1_1
+          for (int mmb=0; mmb<N2*O2; mmb++) { //i_1_2
+            for(int ll=0; ll<N1*O1; ll++) { //i_1_1
+              for (int mm=0; mm<N2*O2; mm++) { //i_1_2
+                for (int nn=0; nn<2; nn++) {
+                  if((llb != ll) || (mmb != mm)) gNB->pmiq_size[2] += 1;
+                }
+              }
+            }
+          }
+        }
+        mat[2] = (int32_t **)malloc16(gNB->pmiq_size[2]*sizeof(int32_t *));
+        //pmi=0 corresponds to unit matrix
+        mat[2][0] = (int32_t *)calloc((2*N1*N2)*(3),sizeof(int32_t));
+        for(int j_col=0; j_col<3; j_col++) { //3 layers
+          for (int i_rows=0; i_rows<2*N1*N2; i_rows++) { //2-x polarized antenna
+            if(j_col==i_rows) {
+              mat[2][0][i_rows*3+j_col] = 0x7fff;
+            }
+          }
+        }
+
+        pmiq = 0;
+        //pmi=1,...,pmi_size are computed as follows
+        for(int llb=0; llb<N1*O1; llb++) { //i_1_1
+          for (int mmb=0; mmb<N2*O2; mmb++) { //i_1_2
+            for(int ll=0; ll<N1*O1; ll++) { //i_1_1
+              for (int mm=0; mm<N2*O2; mm++) { //i_1_2
+                for (int nn=0; nn<2; nn++) {
+                  if((llb != ll) || (mmb != mm)){
+                    pmiq += 1;
+                    mat[2][pmiq] = (int32_t *)malloc16((2*N1*N2)*(3)*sizeof(int32_t));
+                    LOG_I(PHY, "layer 3 Codebook pmiq = %d\n",pmiq);
+                    for(int j_col=0; j_col<3; j_col++) {
+                      if (j_col==0) {
+                        llc = llb;
+                        mmc = mmb;
+                        phase_sign = 1;
+                      }
+                      if (j_col==1) {
+                        llc = ll;
+                        mmc = mm;
+                        phase_sign = 1;
+                      }
+                      if (j_col==2) {
+                        llc = ll;
+                        mmc = mm;
+                        phase_sign = -1;
+                      }
+                      for (int i_rows=0; i_rows<N1*N2; i_rows++) {
+                        res_code=sqrt(1/(double)(3*CSI_RS_antenna_ports))*v_lm[llc][mmc][i_rows];
+                        if (creal(res_code)>0)
+                          ((short*) &mat[2][pmiq][i_rows*3+j_col])[0] = (short) ((creal(res_code)*32768)+0.5);//convert to Q15
+                        else
+                          ((short*) &mat[2][pmiq][i_rows*3+j_col])[0] = (short) ((creal(res_code)*32768)-0.5);//convert to Q15
+                        if (cimag(res_code)>0)
+                          ((short*) &mat[2][pmiq][i_rows*3+j_col])[1] = (short) ((cimag(res_code)*32768)+0.5);//convert to Q15
+                        else
+                          ((short*) &mat[2][pmiq][i_rows*3+j_col])[1] = (short) ((cimag(res_code)*32768)-0.5);//convert to Q15
+                        LOG_D(PHY, "3 Layer Precoding Matrix[2][pmi %d][antPort %d][layerIdx %d]= %f+j %f -> Fixed Point %d+j %d \n",
+                              pmiq,i_rows,j_col, creal(res_code), cimag(res_code),((short*) &mat[2][pmiq][i_rows*3+j_col])[0],((short*) &mat[2][pmiq][i_rows*3+j_col])[1]);
+                      }
+                      for (int i_rows=N1*N2; i_rows<2*N1*N2; i_rows++) {
+                        res_code=sqrt(1/(double)(3*CSI_RS_antenna_ports))*(phase_sign)*theta_n[nn]*v_lm[llc][mmc][i_rows-N1*N2];
+                        if (creal(res_code)>0)
+                          ((short*) &mat[2][pmiq][i_rows*3+j_col])[0] = (short) ((creal(res_code)*32768)+0.5);//convert to Q15
+                        else
+                          ((short*) &mat[2][pmiq][i_rows*3+j_col])[0] = (short) ((creal(res_code)*32768)-0.5);//convert to Q15
+                        if (cimag(res_code)>0)
+                          ((short*) &mat[2][pmiq][i_rows*3+j_col])[1] = (short) ((cimag(res_code)*32768)+0.5);//convert to Q15
+                        else
+                          ((short*) &mat[2][pmiq][i_rows*3+j_col])[1] = (short) ((cimag(res_code)*32768)-0.5);//convert to Q15
+                        LOG_D(PHY, "3 Layer Precoding Matrix[2][pmi %d][antPort %d][layerIdx %d]= %f+j %f -> Fixed Point %d+j %d \n",
+                              pmiq,i_rows,j_col, creal(res_code), cimag(res_code),((short*) &mat[2][pmiq][i_rows*3+j_col])[0],((short*) &mat[2][pmiq][i_rows*3+j_col])[1]);
+                      }
+                    }
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+
+      //Table 5.2.2.2.1-8:
+      //Codebook for 4-layer CSI reporting using antenna ports 3000 to 2999+PCSI-RS
+      if(max_mimo_layers>=4) {
+        //pmi_size is computed as follows
+        gNB->pmiq_size[3] = 1;//unity matrix
+        for(int llb=0; llb<N1*O1; llb++) { //i_1_1
+          for (int mmb=0; mmb<N2*O2; mmb++) { //i_1_2
+            for(int ll=0; ll<N1*O1; ll++) { //i_1_1
+              for (int mm=0; mm<N2*O2; mm++) { //i_1_2
+                for (int nn=0; nn<2; nn++) {
+                  if((llb != ll) || (mmb != mm)) gNB->pmiq_size[3] += 1;
+                }
+              }
+            }
+          }
+        }
+
+        mat[3] = (int32_t **)malloc16(gNB->pmiq_size[3]*sizeof(int32_t *));
+        //pmi=0 corresponds to unit matrix
+        mat[3][0] = (int32_t *)calloc((2*N1*N2)*(4),sizeof(int32_t));
+        for(int j_col=0; j_col<4; j_col++) { //4 layers
+          for (int i_rows=0; i_rows<2*N1*N2; i_rows++) { //2-x polarized antenna
+            if(j_col==i_rows) {
+              mat[3][0][i_rows*4+j_col] = 0x7fff;
+            }
+          }
+        }
+
+        pmiq = 0;
+        //pmi=1,...,pmi_size are computed as follows
+        for(int llb=0; llb<N1*O1; llb++) { //i_1_1
+          for (int mmb=0; mmb<N2*O2; mmb++) { //i_1_2
+            for(int ll=0; ll<N1*O1; ll++) { //i_1_1
+              for (int mm=0; mm<N2*O2; mm++) { //i_1_2
+                for (int nn=0; nn<2; nn++) {
+
+                  if((llb != ll) || (mmb != mm)){
+                    pmiq += 1;
+                    mat[3][pmiq] = (int32_t *)malloc16((2*N1*N2)*4*sizeof(int32_t));
+                    LOG_I(PHY, "layer 4 pmiq = %d\n",pmiq);
+                    for(int j_col=0; j_col<4; j_col++) {
+                      if (j_col==0) {
+                        llc = llb;
+                        mmc = mmb;
+                        phase_sign = 1;
+                      }
+                      if (j_col==1) {
+                        llc = ll;
+                        mmc = mm;
+                        phase_sign = 1;
+                      }
+                      if (j_col==2) {
+                        llc = llb;
+                        mmc = mmb;
+                        phase_sign = -1;
+                      }
+                      if (j_col==3) {
+                        llc = ll;
+                        mmc = mm;
+                        phase_sign = -1;
+                      }
+                      for (int i_rows=0; i_rows<N1*N2; i_rows++) {
+                        res_code=sqrt(1/(double)(4*CSI_RS_antenna_ports))*v_lm[llc][mmc][i_rows];
+                        if (creal(res_code)>0)
+                          ((short*) &mat[3][pmiq][i_rows*4+j_col])[0] = (short) ((creal(res_code)*32768)+0.5);//convert to Q15
+                        else
+                          ((short*) &mat[3][pmiq][i_rows*4+j_col])[0] = (short) ((creal(res_code)*32768)-0.5);//convert to Q15
+                        if (cimag(res_code)>0)
+                          ((short*) &mat[3][pmiq][i_rows*4+j_col])[1] = (short) ((cimag(res_code)*32768)+0.5);//convert to Q15
+                        else
+                          ((short*) &mat[3][pmiq][i_rows*4+j_col])[1] = (short) ((cimag(res_code)*32768)-0.5);//convert to Q15
+                        LOG_D(PHY, "4 Layer Precoding Matrix[3][pmi %d][antPort %d][layerIdx %d]= %f+j %f -> Fixed Point %d+j %d \n",
+                              pmiq,i_rows,j_col, creal(res_code), cimag(res_code),((short*) &mat[3][pmiq][i_rows*4+j_col])[0],((short*) &mat[3][pmiq][i_rows*4+j_col])[1]);
+                      }
+
+                      for (int i_rows=N1*N2; i_rows<2*N1*N2; i_rows++) {
+                        res_code=sqrt(1/(double)(4*CSI_RS_antenna_ports))*(phase_sign)*theta_n[nn]*v_lm[llc][mmc][i_rows-N1*N2];
+                        if (creal(res_code)>0)
+                          ((short*) &mat[3][pmiq][i_rows*4+j_col])[0] = (short) ((creal(res_code)*32768)+0.5);//convert to Q15
+                        else
+                          ((short*) &mat[3][pmiq][i_rows*4+j_col])[0] = (short) ((creal(res_code)*32768)-0.5);//convert to Q15
+                        if (cimag(res_code)>0)
+                          ((short*) &mat[3][pmiq][i_rows*4+j_col])[1] = (short) ((cimag(res_code)*32768)+0.5);//convert to Q15
+                        else
+                          ((short*) &mat[3][pmiq][i_rows*4+j_col])[1] = (short) ((cimag(res_code)*32768)-0.5);//convert to Q15
+                        LOG_D(PHY, "4 Layer Precoding Matrix[3][pmi %d][antPort %d][layerIdx %d]= %f+j %f -> Fixed Point %d+j %d \n",
+                              pmiq,i_rows,j_col, creal(res_code), cimag(res_code),((short*) &mat[3][pmiq][i_rows*4+j_col])[0],((short*) &mat[3][pmiq][i_rows*4+j_col])[1]);
+                      }
+                    }
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+  return 0;
+}
 
 int phy_init_nr_gNB(PHY_VARS_gNB *gNB,
                     unsigned char is_secondary_gNB,
@@ -108,6 +509,9 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB,
   init_scrambling_luts();
   init_pucch2_luts();
   load_nrLDPClib(NULL);
+
+  init_codebook_gNB(gNB);
+
   // PBCH DMRS gold sequences generation
   nr_init_pbch_dmrs(gNB);
   //PDCCH DMRS init
@@ -132,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);
 
@@ -145,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);
 
@@ -181,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 **));
@@ -203,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++) {
@@ -240,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));
@@ -317,6 +726,16 @@ void phy_free_nr_gNB(PHY_VARS_gNB *gNB)
   const int max_ul_mimo_layers = 4; // taken from phy_init_nr_gNB()
   const int n_buf = Prx * max_ul_mimo_layers;
 
+  int max_dl_mimo_layers =(fp->nb_antennas_tx<NR_MAX_NB_LAYERS) ? fp->nb_antennas_tx : NR_MAX_NB_LAYERS;
+  if (fp->nb_antennas_tx>1) {
+    for (int nl = 0; nl < max_dl_mimo_layers; nl++) {
+      for(int size = 0; size < gNB->pmiq_size[nl]; size++)
+        free_and_zero(gNB->nr_mimo_precoding_matrix[nl][size]);
+      free_and_zero(gNB->nr_mimo_precoding_matrix[nl]);
+    }
+    free_and_zero(gNB->nr_mimo_precoding_matrix);
+  }
+
   uint32_t ***pdcch_dmrs = gNB->nr_gold_pdcch_dmrs;
   for (int slot = 0; slot < fp->slots_per_frame; slot++) {
     for (int symb = 0; symb < fp->symbols_per_slot; symb++)
@@ -326,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]);
     }
@@ -357,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 75315187d9a7068beb9f2f593e221c7dc76e2aad..e5bf08abf6faca2d12827fc8cee91b468dcb39d1 100644
--- a/openair1/PHY/INIT/nr_init_ue.c
+++ b/openair1/PHY/INIT/nr_init_ue.c
@@ -55,13 +55,11 @@ extern uint16_t beta_cqi[16];
  * \param[in] frame_parms LTE_DL_FRAME_PARMS structure.
  * \note This function is optimistic in that it expects malloc() to succeed.
  */
-void phy_init_nr_ue__PDSCH(NR_UE_PDSCH *const pdsch,
+void phy_init_nr_ue_PDSCH(NR_UE_PDSCH *const pdsch,
                            const NR_DL_FRAME_PARMS *const fp) {
 
   AssertFatal( pdsch, "pdsch==0" );
-  pdsch->pmi_ext = (uint8_t *)malloc16_clear( fp->N_RB_DL );
-  pdsch->llr[0] = (int16_t *)malloc16_clear( (8*(3*8*6144))*sizeof(int16_t) );
-  pdsch->layer_llr[0] = (int16_t *)malloc16_clear( (8*(3*8*6144))*sizeof(int16_t) );
+
   pdsch->llr128 = (int16_t **)malloc16_clear( sizeof(int16_t *) );
   // FIXME! no further allocation for (int16_t*)pdsch->llr128 !!! expect SIGSEGV
   // FK, 11-3-2015: this is only as a temporary pointer, no memory is stored there
@@ -73,8 +71,6 @@ void phy_init_nr_ue__PDSCH(NR_UE_PDSCH *const pdsch,
   pdsch->dl_ch_estimates_ext    = (int32_t **)malloc16_clear( NR_MAX_NB_LAYERS*fp->nb_antennas_rx*sizeof(int32_t *) );
   pdsch->dl_bf_ch_estimates     = (int32_t **)malloc16_clear( NR_MAX_NB_LAYERS*fp->nb_antennas_rx*sizeof(int32_t *) );
   pdsch->dl_bf_ch_estimates_ext = (int32_t **)malloc16_clear( NR_MAX_NB_LAYERS*fp->nb_antennas_rx*sizeof(int32_t *) );
-  //pdsch->dl_ch_rho_ext          = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) );
-  //pdsch->dl_ch_rho2_ext         = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) );
   pdsch->dl_ch_mag0             = (int32_t **)malloc16_clear( NR_MAX_NB_LAYERS*fp->nb_antennas_rx*sizeof(int32_t *) );
   pdsch->dl_ch_magb0            = (int32_t **)malloc16_clear( NR_MAX_NB_LAYERS*fp->nb_antennas_rx*sizeof(int32_t *) );
   pdsch->dl_ch_magr0            = (int32_t **)malloc16_clear( NR_MAX_NB_LAYERS*fp->nb_antennas_rx*sizeof(int32_t *) );
@@ -103,8 +99,6 @@ void phy_init_nr_ue__PDSCH(NR_UE_PDSCH *const pdsch,
       pdsch->dl_ch_estimates_ext[idx]     = (int32_t *)malloc16_clear( sizeof(int32_t) * num );
       pdsch->dl_bf_ch_estimates[idx]      = (int32_t *)malloc16_clear( sizeof(int32_t) * fp->ofdm_symbol_size*7*2);
       pdsch->dl_bf_ch_estimates_ext[idx]  = (int32_t *)malloc16_clear( sizeof(int32_t) * num );
-      //pdsch->dl_ch_rho_ext[idx]           = (int32_t*)malloc16_clear( sizeof(int32_t) * num );
-      //pdsch->dl_ch_rho2_ext[idx]          = (int32_t*)malloc16_clear( sizeof(int32_t) * num );
       pdsch->dl_ch_mag0[idx]              = (int32_t *)malloc16_clear( sizeof(int32_t) * num );
       pdsch->dl_ch_magb0[idx]             = (int32_t *)malloc16_clear( sizeof(int32_t) * num );
       pdsch->dl_ch_magr0[idx]             = (int32_t *)malloc16_clear( sizeof(int32_t) * num );
@@ -136,8 +130,11 @@ void phy_term_nr_ue__PDSCH(NR_UE_PDSCH* pdsch, const NR_DL_FRAME_PARMS *const fp
     free_and_zero(pdsch->rho[i]);
   }
   free_and_zero(pdsch->pmi_ext);
-  free_and_zero(pdsch->llr[0]);
-  free_and_zero(pdsch->layer_llr[0]);
+  int nb_codewords = NR_MAX_NB_LAYERS > 4 ? 2 : 1;
+  for (int i=0; i<nb_codewords; i++)
+    free_and_zero(pdsch->llr[i]);
+  for (int i=0; i<NR_MAX_NB_LAYERS; i++)
+    free_and_zero(pdsch->layer_llr[i]);
   free_and_zero(pdsch->llr128);
   free_and_zero(pdsch->rxdataF_ext);
   free_and_zero(pdsch->rxdataF_uespec_pilots);
@@ -162,13 +159,10 @@ 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,k,l,slot,symb;
+  int i,j,slot,symb, gNB_id, th_id;
 
   NR_UE_SRS **const srs_vars             = ue->srs_vars;
 
-  int gNB_id;
-  int th_id;
-
   LOG_I(PHY, "Initializing UE vars for gNB TXant %u, UE RXant %u\n", fp->nb_antennas_tx, fp->nb_antennas_rx);
 
   phy_init_nr_top(ue);
@@ -216,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);
+      }
     }
   }
 
@@ -304,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));
     }
@@ -348,57 +359,6 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB)
       ue->nr_srs_info->srs_estimated_channel_time_shifted[i] = (int32_t *) malloc16_clear(fp->ofdm_symbol_size*MAX_NUM_NR_SRS_SYMBOLS*sizeof(int32_t));
     }
 
-    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 );
-    }
-
-    for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) {
-      ue->pdsch_vars[th_id][gNB_id]->llr_shifts          = (uint8_t *)malloc16_clear(7*2*fp->N_RB_DL*12);
-      ue->pdsch_vars[th_id][gNB_id]->llr_shifts_p        = ue->pdsch_vars[0][gNB_id]->llr_shifts;
-      ue->pdsch_vars[th_id][gNB_id]->llr[1]              = (int16_t *)malloc16_clear( (8*(3*8*8448))*sizeof(int16_t) );
-      ue->pdsch_vars[th_id][gNB_id]->layer_llr[1]        = (int16_t *)malloc16_clear( (8*(3*8*8448))*sizeof(int16_t) );
-      ue->pdsch_vars[th_id][gNB_id]->llr128_2ndstream    = (int16_t **)malloc16_clear( sizeof(int16_t *) );
-    }
-
-
-    for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) {
-      ue->pdsch_vars[th_id][gNB_id]->dl_ch_rho2_ext      = (int32_t **)malloc16_clear( 4*fp->nb_antennas_rx*sizeof(int32_t *) );
-    }
-
-    for (i=0; i<fp->nb_antennas_rx; i++)
-      for (j=0; j<4; j++) {
-        const int idx = (j*fp->nb_antennas_rx)+i;
-        const size_t num = 7*2*fp->N_RB_DL*12+4;
-
-        for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) {
-          ue->pdsch_vars[th_id][gNB_id]->dl_ch_rho2_ext[idx] = (int32_t *)malloc16_clear( sizeof(int32_t) * num );
-        }
-      }
-
-    //const size_t num = 7*2*fp->N_RB_DL*12+4;
-    for (k=0; k<8; k++) { //harq_pid
-      for (l=0; l<8; l++) { //round
-        for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) {
-          ue->pdsch_vars[th_id][gNB_id]->rxdataF_comp1[k][l] = (int32_t **)malloc16_clear( 4*fp->nb_antennas_rx*sizeof(int32_t *) );
-          ue->pdsch_vars[th_id][gNB_id]->dl_ch_rho_ext[k][l] = (int32_t **)malloc16_clear( 4*fp->nb_antennas_rx*sizeof(int32_t *) );
-          ue->pdsch_vars[th_id][gNB_id]->dl_ch_mag1[k][l]    = (int32_t **)malloc16_clear( 4*fp->nb_antennas_rx*sizeof(int32_t *) );
-          ue->pdsch_vars[th_id][gNB_id]->dl_ch_magb1[k][l]   = (int32_t **)malloc16_clear( 4*fp->nb_antennas_rx*sizeof(int32_t *) );
-        }
-
-        for (int i=0; i<fp->nb_antennas_rx; i++)
-          for (int j=0; j<4; j++) { //frame_parms->nb_antennas_tx; j++)
-            const int idx = (j*fp->nb_antennas_rx)+i;
-
-            for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) {
-              ue->pdsch_vars[th_id][gNB_id]->dl_ch_rho_ext[k][l][idx] = (int32_t *)malloc16_clear(7*2*sizeof(int32_t)*(fp->N_RB_DL*12));
-              ue->pdsch_vars[th_id][gNB_id]->rxdataF_comp1[k][l][idx] = (int32_t *)malloc16_clear(7*2*sizeof(int32_t)*(fp->N_RB_DL*12));
-              ue->pdsch_vars[th_id][gNB_id]->dl_ch_mag1[k][l][idx]    = (int32_t *)malloc16_clear(7*2*sizeof(int32_t)*(fp->N_RB_DL*12));
-              ue->pdsch_vars[th_id][gNB_id]->dl_ch_magb1[k][l][idx]   = (int32_t *)malloc16_clear(7*2*sizeof(int32_t)*(fp->N_RB_DL*12));
-            }
-          }
-      }
-    }
-
     // 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) );
@@ -406,7 +366,6 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB)
       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]->dl_ch_rho_ext       = (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 *) );
@@ -424,7 +383,6 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB)
           //  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]->dl_ch_rho_ext[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);
         }
@@ -437,13 +395,6 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB)
 
   }
 
-  // initialization for the last instance of pdsch_vars (used for MU-MIMO)
-  for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) {
-    ue->pdsch_vars[th_id][gNB_id] = malloc16_clear(sizeof(NR_UE_PDSCH));
-    ue->pdsch_vars[th_id][gNB_id]->llr[1] = malloc16_clear((8*(3*8*8448))*sizeof(int16_t));
-    ue->pdsch_vars[th_id][gNB_id]->layer_llr[1] = malloc16_clear((8*(3*8*8448))*sizeof(int16_t));
-  }
-
   ue->sinr_CQI_dB = (double *) malloc16_clear( fp->N_RB_DL*12*sizeof(double) );
   ue->init_averaging = 1;
 
@@ -475,6 +426,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]);
@@ -508,10 +461,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]);
     }
@@ -519,44 +471,18 @@ 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++) {
-      for (int k = 0; k < 8; k++) { //harq_pid
-        for (int l = 0; l < 8; l++) { //round
-          for (int i = 0; i < fp->nb_antennas_rx; i++) {
-            for (int j = 0; j < 4; j++) { //frame_parms->nb_antennas_tx; j++)
-              const int idx = j * fp->nb_antennas_rx + i;
-              free_and_zero(ue->pdsch_vars[th_id][gNB_id]->dl_ch_rho_ext[k][l][idx]);
-              free_and_zero(ue->pdsch_vars[th_id][gNB_id]->rxdataF_comp1[k][l][idx]);
-              free_and_zero(ue->pdsch_vars[th_id][gNB_id]->dl_ch_mag1[k][l][idx]);
-              free_and_zero(ue->pdsch_vars[th_id][gNB_id]->dl_ch_magb1[k][l][idx]);
-            }
-          }
-
-          free_and_zero(ue->pdsch_vars[th_id][gNB_id]->rxdataF_comp1[k][l]);
-          free_and_zero(ue->pdsch_vars[th_id][gNB_id]->dl_ch_rho_ext[k][l]);
-          free_and_zero(ue->pdsch_vars[th_id][gNB_id]->dl_ch_mag1[k][l]);
-          free_and_zero(ue->pdsch_vars[th_id][gNB_id]->dl_ch_magb1[k][l]);
-        }
-      }
-
-      for (int i = 0; i < fp->nb_antennas_rx; i++) {
-        for (int j = 0; j < 4; j++) {
-          const int idx = (j*fp->nb_antennas_rx)+i;
-          free_and_zero(ue->pdsch_vars[th_id][gNB_id]->dl_ch_rho2_ext[idx]);
-        }
-      }
       free_and_zero(ue->pdsch_vars[th_id][gNB_id]->llr_shifts);
-      free_and_zero(ue->pdsch_vars[th_id][gNB_id]->llr[1]);
-      free_and_zero(ue->pdsch_vars[th_id][gNB_id]->layer_llr[1]);
       free_and_zero(ue->pdsch_vars[th_id][gNB_id]->llr128_2ndstream);
-      free_and_zero(ue->pdsch_vars[th_id][gNB_id]->dl_ch_rho2_ext);
-
       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++) {
@@ -565,7 +491,6 @@ void term_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB)
           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]->dl_ch_rho_ext[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]);
         }
@@ -576,7 +501,6 @@ void term_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB)
       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]->dl_ch_rho_ext);
       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);
@@ -612,13 +536,6 @@ void term_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB)
     free_and_zero(ue->prach_vars[gNB_id]);
   }
 
-  const int gNB_id = ue->n_connected_gNB;
-  for (int th_id = 0; th_id < RX_NB_TH_MAX; th_id++) {
-    free_and_zero(ue->pdsch_vars[th_id][gNB_id]->llr[1]);
-    free_and_zero(ue->pdsch_vars[th_id][gNB_id]->layer_llr[1]);
-    free_and_zero(ue->pdsch_vars[th_id][gNB_id]);
-  }
-
   free_and_zero(ue->sinr_CQI_dB);
 }
 
diff --git a/openair1/PHY/INIT/phy_init.h b/openair1/PHY/INIT/phy_init.h
index 8648dd7d82c70fe4fae0592b1a7636818a54a3cb..29940a4fbe99bd851d5fd7300470169e2775879f 100644
--- a/openair1/PHY/INIT/phy_init.h
+++ b/openair1/PHY/INIT/phy_init.h
@@ -402,6 +402,7 @@ void init_nr_ue_transport(PHY_VARS_NR_UE *ue);
 void init_N_TA_offset(PHY_VARS_NR_UE *ue);
 void nr_dump_frame_parms(NR_DL_FRAME_PARMS *frame_parms);
 int phy_init_nr_gNB(PHY_VARS_gNB *gNB, unsigned char is_secondary_gNB, unsigned char lowmem_flag);
+int init_codebook_gNB(PHY_VARS_gNB *gNB);
 void nr_phy_config_request(NR_PHY_Config_t *gNB);
 void nr_phy_config_request_sim(PHY_VARS_gNB *gNB,int N_RB_DL,int N_RB_UL,int mu,int Nid_cell,uint64_t position_in_burst);
 void phy_free_nr_gNB(PHY_VARS_gNB *gNB);
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/nr_modulation.c b/openair1/PHY/MODULATION/nr_modulation.c
index 4cb3185b67ef5a99eeb624bcf57616220f6329f1..b1a108f24756294a2ce77390db3d667779ae435d 100644
--- a/openair1/PHY/MODULATION/nr_modulation.c
+++ b/openair1/PHY/MODULATION/nr_modulation.c
@@ -719,3 +719,18 @@ int nr_layer_precoder(int16_t **datatx_F_precoding, char *prec_matrix, uint8_t n
   /*  ((int16_t *)precodatatx_F)[0] = (int16_t)((((int16_t *)precodatatx_F)[0]*ONE_OVER_SQRT2_Q15)>>15);
       ((int16_t *)precodatatx_F)[1] = (int16_t)((((int16_t *)precodatatx_F)[1]*ONE_OVER_SQRT2_Q15)>>15);*/
 }
+
+int nr_layer_precoder_cm(int16_t **datatx_F_precoding, int *prec_matrix, uint8_t n_layers, int32_t re_offset)
+{
+  int32_t precodatatx_F = 0;
+  for (int al = 0; al<n_layers; al++) {
+    int16_t antenna_re = datatx_F_precoding[al][re_offset<<1];
+    int16_t antenna_im = datatx_F_precoding[al][(re_offset<<1) +1];
+    //printf("antenna precoding: %d %d\n",((int16_t *)&prec_matrix[al])[0],((int16_t *)&prec_matrix[al])[1]);
+    ((int16_t *) &precodatatx_F)[0] += (int16_t)(((int32_t)(antenna_re*(((int16_t *)&prec_matrix[al])[0])) - (int32_t)(antenna_im* (((int16_t *)&prec_matrix[al])[1])))>>15);
+    ((int16_t *) &precodatatx_F)[1] += (int16_t)(((int32_t)(antenna_re*(((int16_t *)&prec_matrix[al])[1])) + (int32_t)(antenna_im* (((int16_t *)&prec_matrix[al])[0])))>>15);
+  }
+
+  return precodatatx_F;
+}
+
diff --git a/openair1/PHY/MODULATION/nr_modulation.h b/openair1/PHY/MODULATION/nr_modulation.h
index db15e3d9efc5fac5b145e82d5bca19e6735a61a1..65f147fffa2716cd4317b072ac31de34399d55e0 100644
--- a/openair1/PHY/MODULATION/nr_modulation.h
+++ b/openair1/PHY/MODULATION/nr_modulation.h
@@ -135,4 +135,9 @@ int nr_layer_precoder(int16_t **datatx_F_precoding,
 		char *prec_matrix,
 		uint8_t n_layers,
 		int32_t re_offset);
+
+int nr_layer_precoder_cm(int16_t **datatx_F_precoding,
+                int *prec_matrix,
+                uint8_t n_layers,
+                int32_t re_offset);
 #endif
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_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/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..ba7e539429d87717d687009560681bfca0112b8f 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
     }
     
@@ -248,15 +256,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 e0c445d3852eb2cb709e0f83b9d8a2d3c25bf6d9..19b56f6dbab327b194f8febba8a003bbd825e310 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 */
@@ -147,63 +151,61 @@ 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 +224,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 +277,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 +298,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;
@@ -439,8 +441,7 @@ void nr_generate_pdsch(processingData_L1tx_t *msgTx,
     // The same precoding matrix is applied on prg_size RBs, Thus
     //        pmi = prgs_list[rbidx/prg_size].pm_idx, rbidx =0,...,rbSize-1
     // The Precoding matrix:
-    // The Codebook Type I and Type II are not supported yet.
-    // We`adopt the precoding matrices of PUSCH for 4 layers.
+    // The Codebook Type I
     start_meas(&gNB->dlsch_precoding_stats);
 
     for (int ap=0; ap<frame_parms->nb_antennas_tx; ap++) {
@@ -491,47 +492,38 @@ void nr_generate_pdsch(processingData_L1tx_t *msgTx,
             }
           }
           else {
-            //get the precoding matrix weights:
-            char *W_prec;
-            switch (frame_parms->nb_antennas_tx) {
-              case 1://1 antenna port
-                W_prec = nr_W_1l_2p[pmi][ap];
-                break;
-              case 2://2 antenna ports
-                if (rel15->nrOfLayers == 1)//1 layer
-                  W_prec = nr_W_1l_2p[pmi][ap];
-                else//2 layers
-                  W_prec = nr_W_2l_2p[pmi][ap];
-                break;
-              case 4://4 antenna ports
-                if (rel15->nrOfLayers == 1)//1 layer
-                  W_prec = nr_W_1l_4p[pmi][ap];
-                else if (rel15->nrOfLayers == 2)//2 layers
-                  W_prec = nr_W_2l_4p[pmi][ap];
-                else if (rel15->nrOfLayers == 3)//3 layers
-                  W_prec = nr_W_3l_4p[pmi][ap];
-                else//4 layers
-                  W_prec = nr_W_4l_4p[pmi][ap];
-                break;
-              default:
-                LOG_D(PHY,"Precoding 1,2, or 4 antenna ports are currently supported\n");
-                W_prec = nr_W_1l_2p[pmi][ap];
-                break;
-            }
-            for (int i=0; i<NR_NB_SC_PER_RB; i++) {
-              int32_t re_offset = l*frame_parms->ofdm_symbol_size + k;
-              int32_t precodatatx_F = nr_layer_precoder(txdataF_precoding, W_prec, rel15->nrOfLayers, re_offset);
-              ((int16_t*)txdataF[ap])[(re_offset<<1) + (2*txdataF_offset)] = ((int16_t *) &precodatatx_F)[0];
-              ((int16_t*)txdataF[ap])[(re_offset<<1) + 1 + (2*txdataF_offset)] = ((int16_t *) &precodatatx_F)[1];
-#ifdef DEBUG_DLSCH_MAPPING
-              printf("antenna %d\t l %d \t k %d \t txdataF: %d %d\n",
-                     ap, l, k, ((int16_t*)txdataF[ap])[(re_offset<<1) + (2*txdataF_offset)],
-                     ((int16_t*)txdataF[ap])[(re_offset<<1) + 1 + (2*txdataF_offset)]);
-#endif
-              if (++k >= frame_parms->ofdm_symbol_size) {
+            if(frame_parms->nb_antennas_tx==1){//no precoding matrix defined
+              memcpy((void*)&txdataF[ap][l*frame_parms->ofdm_symbol_size + txdataF_offset + k],
+                     (void*)&txdataF_precoding[ap][2*(l*frame_parms->ofdm_symbol_size + k)],
+                     NR_NB_SC_PER_RB*sizeof(int32_t));
+              k += NR_NB_SC_PER_RB;
+              if (k >= frame_parms->ofdm_symbol_size) {
                 k -= frame_parms->ofdm_symbol_size;
               }
             }
+            else {
+              //get the precoding matrix weights:
+              int32_t **mat = gNB->nr_mimo_precoding_matrix[rel15->nrOfLayers-1];
+              //i_row =0,...,dl_antenna_port
+              //j_col =0,...,nrOfLayers
+              //mat[pmi][i_rows*2+j_col]
+              int *W_prec;
+              W_prec = (int32_t *)&mat[pmi][ap*rel15->nrOfLayers];
+              for (int i=0; i<NR_NB_SC_PER_RB; i++) {
+                int32_t re_offset = l*frame_parms->ofdm_symbol_size + k;
+                int32_t precodatatx_F = nr_layer_precoder_cm(txdataF_precoding, W_prec, rel15->nrOfLayers, re_offset);
+                ((int16_t*)txdataF[ap])[(re_offset<<1) + (2*txdataF_offset)] = ((int16_t *) &precodatatx_F)[0];
+                ((int16_t*)txdataF[ap])[(re_offset<<1) + 1 + (2*txdataF_offset)] = ((int16_t *) &precodatatx_F)[1];
+  #ifdef DEBUG_DLSCH_MAPPING
+                printf("antenna %d\t l %d \t k %d \t txdataF: %d %d\n",
+                       ap, l, k, ((int16_t*)txdataF[ap])[(re_offset<<1) + (2*txdataF_offset)],
+                       ((int16_t*)txdataF[ap])[(re_offset<<1) + 1 + (2*txdataF_offset)]);
+  #endif
+                if (++k >= frame_parms->ofdm_symbol_size) {
+                  k -= frame_parms->ofdm_symbol_size;
+                }
+              }
+            }
           }
         } //RB loop
       } // symbol loop
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 90a5c7270aad4617c923e45dada8f961a7e8977c..bcb76f931a69897603f5c32f64b818d6726243ca 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_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..5c415e7d4054bbb8411c56993dc683abc2dcbfcd 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,6 +466,7 @@ 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)
 {
@@ -491,13 +494,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))); 
@@ -664,6 +665,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 +704,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..963a845876d1211fc8c5515bc71df5f9f1c3e07a 100644
--- a/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h
+++ b/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h
@@ -44,6 +44,7 @@ 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);
 
@@ -74,6 +75,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/nr_dlsch_decoding.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c
index 5cdf6f4b19a159368459abcd64f16195309171ff..92a8d13c21374a76886f046ed0c9c8dd148b47ae 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])
@@ -301,132 +297,128 @@ void nr_processDLSegment(void* arg) {
   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;
-    }
+  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);
+  r_offset += E;
 
-      for (int i=0; i<E; i++)
-        LOG_D(PHY,"%d : %d\n",i,harq_process->d[r][i]);
+  if (LOG_DEBUGFLAG(DEBUG_DLSCH_DECOD)) {
+    LOG_D(PHY,"decoder input(segment %u) :",r);
 
-      LOG_D(PHY,"\n");
-    }
+    for (int i=0; i<E; i++)
+      LOG_D(PHY,"%d : %d\n",i,harq_process->d[r][i]);
 
-    memset(harq_process->c[r],0,Kr_bytes);
+    LOG_D(PHY,"\n");
+  }
 
-    if (harq_process->C == 1) {
-      if (A > NR_MAX_PDSCH_TBS)
-        crc_type = CRC24_A;
-      else
-        crc_type = CRC16;
+  memset(harq_process->c[r],0,Kr_bytes);
 
-      length_dec = harq_process->B;
-    } else {
-      crc_type = CRC24_B;
-      length_dec = (harq_process->B+24*harq_process->C)/harq_process->C;
-    }
+  if (harq_process->C == 1) {
+    if (A > NR_MAX_PDSCH_TBS)
+      crc_type = CRC24_A;
+    else
+      crc_type = CRC16;
 
-    {
-      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]);
-      }
+    length_dec = harq_process->B;
+  } else {
+    crc_type = CRC24_B;
+    length_dec = (harq_process->B+24*harq_process->C)/harq_process->C;
+  }
 
-      //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\033[0m",r);
-
-        if (r==0) {
-          for (int i=0; i<10; i++) LOG_D(PHY,"byte %d : %x\n",i,((uint8_t *)llrProcBuf)[i]);
-        }
+  {
+    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]);
+    }
 
-        //Temporary hack
-        no_iteration_ldpc = dlsch->max_ldpc_iterations;
-        rdata->decodeIterations = no_iteration_ldpc;
-      } else {
-        LOG_D(PHY,"CRC NOT OK\n\033[0m");
+    //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_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\033[0m",r);
+
+      if (r==0) {
+        for (int i=0; i<10; i++) LOG_D(PHY,"byte %d : %x\n",i,((uint8_t *)llrProcBuf)[i]);
       }
 
-      nb_total_decod++;
+      //Temporary hack
+      no_iteration_ldpc = dlsch->max_ldpc_iterations;
+      rdata->decodeIterations = no_iteration_ldpc;
+    } else {
+      LOG_D(PHY,"CRC NOT OK\n\033[0m");
+    }
 
-      if (no_iteration_ldpc > dlsch->max_ldpc_iterations) {
-        nb_error_decod++;
-      }
+    nb_total_decod++;
 
-      for (int m=0; m < Kr>>3; m ++) {
-        harq_process->c[r][m]= (uint8_t) llrProcBuf[m];
-      }
+    if (no_iteration_ldpc > dlsch->max_ldpc_iterations) {
+      nb_error_decod++;
+    }
 
-      stop_meas(&rdata->ts_ldpc_decode);
+    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,
diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c
index 52eda10e9e4bc4c370cc4e5698a3840525be86f4..db39bfddc9e5a27ca221c0b73fe0c175e8c8a147 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c
@@ -39,6 +39,7 @@
 #include "PHY/NR_REFSIG/nr_refsig.h"
 #include "PHY/NR_REFSIG/dmrs_nr.h"
 #include "common/utils/nr/nr_common.h"
+#include <complex.h>
 
 /* dynamic shift for LLR computation for TM3/4
  * set as command line argument, see lte-softmodem.c
@@ -79,35 +80,28 @@ unsigned char offset_mumimo_llr_drange[29][3]={{8,8,8},{7,7,7},{7,7,7},{7,7,7},{
 #define print_ints(s,x) printf("%s = %d %d %d %d\n",s,(x)[0],(x)[1],(x)[2],(x)[3])
 #define print_shorts(s,x) printf("%s = [%d+j*%d, %d+j*%d, %d+j*%d, %d+j*%d]\n",s,(x)[0],(x)[1],(x)[2],(x)[3],(x)[4],(x)[5],(x)[6],(x)[7])
 
-static void nr_dlsch_dual_stream_correlation_core(int **dl_ch_estimates_ext,
-						  int **dl_ch_estimates_ext_i,
-						  int **dl_ch_rho_ext,
-						  unsigned char n_tx,
-						  unsigned char n_rx,
-						  unsigned char output_shift,
-						  int length,
-						  int start_point);
-
-uint8_t nr_zero_forcing_rx_2layers(int **rxdataF_comp,
+/* compute H_h_H matrix inversion up to 4x4 matrices */
+uint8_t nr_zero_forcing_rx(int **rxdataF_comp,
                                    int **dl_ch_mag,
                                    int **dl_ch_magb,
                                    int **dl_ch_magr,
                                    int **dl_ch_estimates_ext,
                                    unsigned short nb_rb,
                                    unsigned char n_rx,
+                                   unsigned char n_tx,//number of layer
                                    unsigned char mod_order,
                                    int shift,
                                    unsigned char symbol,
                                    int length);
 
+/* Apply layer demapping */
 static void nr_dlsch_layer_demapping(int16_t **llr_cw,
-				     uint8_t Nl,
-				     uint8_t mod_order,
-				     uint32_t length,
-				     int32_t codeword_TB0,
-				     int32_t codeword_TB1,
-				     int16_t **llr_layers);
-
+                                     uint8_t Nl,
+                                     uint8_t mod_order,
+                                     uint32_t length,
+                                     int32_t codeword_TB0,
+                                     int32_t codeword_TB1,
+                                     int16_t **llr_layers);
 
 /* compute LLR */
 static int nr_dlsch_llr(NR_UE_PDSCH **pdsch_vars,
@@ -130,6 +124,7 @@ static int nr_dlsch_llr(NR_UE_PDSCH **pdsch_vars,
                         uint8_t nr_slot_rx,
                         uint8_t beamforming_mode);
 
+
 /* Main Function */
 int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
                 UE_nr_rxtx_proc_t *proc,
@@ -159,7 +154,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
 
   unsigned char aatx=0,aarx=0;
 
-  unsigned short nb_rb = 0, round;
+  unsigned short round;
   int avgs = 0;// rb;
   NR_DL_UE_HARQ_t *dlsch0_harq, *dlsch1_harq = NULL;
 
@@ -176,9 +171,8 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
   //int16_t  *pllr_symbol_cw0_deint;
   //int16_t  *pllr_symbol_cw1_deint;
   //uint16_t bundle_L = 2;
-  uint16_t n_tx=1, n_rx=1;
   int32_t median[16];
-  uint32_t len;
+  uint32_t nb_re_pdsch;
   uint16_t startSymbIdx=0;
   uint16_t nbSymb=0;
   uint16_t pduBitmap=0x0;
@@ -204,7 +198,6 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
     dlsch0_harq = dlsch[0]->harq_processes[harq_pid];
     if (NR_MAX_NB_LAYERS>4)
       dlsch1_harq = dlsch[1]->harq_processes[harq_pid];
-    beamforming_mode = ue->transmission_mode[gNB_id] < 7 ? 0 :ue->transmission_mode[gNB_id];
     break;
 
   default:
@@ -306,130 +299,92 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
     return(-1);
   }
 
-  if (dlsch0_harq->mimo_mode>NR_DUALSTREAM) {
-    LOG_E(PHY,"This transmission mode is not yet supported!\n");
-    return(-1);
-  }
-
-  if (dlsch0_harq->mimo_mode==NR_DUALSTREAM)  {
-    DevAssert(dlsch1_harq);
-  }
-
   if(symbol > ue->frame_parms.symbols_per_slot>>1)
   {
       slot = 1;
   }
 
-#ifdef DEBUG_HARQ
-  printf("Demod  dlsch0_harq->pmi_alloc %d\n",  dlsch0_harq->pmi_alloc);
-#endif
-
   uint8_t pilots = (dlsch0_harq->dlDmrsSymbPos >> symbol) & 1;
   uint8_t config_type = dlsch0_harq->dmrsConfigType;
-
-  if (beamforming_mode==0) {//No beamforming
-    start_meas(&ue->generic_stat_bis[proc->thread_id][slot]);
-    if (dlsch0_harq->Nl > 1)//More than or equal 2 layers
-      nb_rb = nr_dlsch_extract_rbs_multiple(common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF,
-                                            pdsch_vars[gNB_id]->dl_ch_estimates,
-                                            pdsch_vars[gNB_id]->rxdataF_ext,
-                                            pdsch_vars[gNB_id]->dl_ch_estimates_ext,
-                                            symbol,
-                                            pilots,
-                                            config_type,
-                                            start_rb + dlsch0_harq->BWPStart,
-                                            nb_rb_pdsch,
-                                            dlsch0_harq->n_dmrs_cdm_groups,
-                                            dlsch0_harq->Nl,
-                                            frame_parms,
-                                            dlsch0_harq->dlDmrsSymbPos);
-    else// one layer
-      nb_rb = nr_dlsch_extract_rbs_single(common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF,
-                                          pdsch_vars[gNB_id]->dl_ch_estimates,
-                                          pdsch_vars[gNB_id]->rxdataF_ext,
-                                          pdsch_vars[gNB_id]->dl_ch_estimates_ext,
-                                          symbol,
-                                          pilots,
-                                          config_type,
-                                          start_rb + dlsch0_harq->BWPStart,
-                                          nb_rb_pdsch,
-                                          dlsch0_harq->n_dmrs_cdm_groups,
-                                          frame_parms,
-                                          dlsch0_harq->dlDmrsSymbPos);
-  }
-  else if(beamforming_mode>7) {
-    LOG_W(PHY,"dlsch_demodulation: beamforming mode not supported yet.\n");
-  }
-  
-  //printf("nb_rb = %d, gNB_id %d\n",nb_rb,gNB_id);
-  if (nb_rb==0) {
-    LOG_D(PHY,"dlsch_demodulation.c: nb_rb=0\n");
-    return(-1);
-  }
-
-  len = (pilots==1)? ((config_type==NFAPI_NR_DMRS_TYPE1)?nb_rb*(12-6*dlsch0_harq->n_dmrs_cdm_groups): nb_rb*(12-4*dlsch0_harq->n_dmrs_cdm_groups)):(nb_rb*12);
-
+  //----------------------------------------------------------
+  //--------------------- RBs extraction ---------------------
+  //----------------------------------------------------------
+  start_meas(&ue->generic_stat_bis[proc->thread_id][slot]);
+  nr_dlsch_extract_rbs(common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF,
+                       pdsch_vars[gNB_id]->dl_ch_estimates,
+                       pdsch_vars[gNB_id]->rxdataF_ext,
+                       pdsch_vars[gNB_id]->dl_ch_estimates_ext,
+                       symbol,
+                       pilots,
+                       config_type,
+                       start_rb + dlsch0_harq->BWPStart,
+                       nb_rb_pdsch,
+                       dlsch0_harq->n_dmrs_cdm_groups,
+                       dlsch0_harq->Nl,
+                       frame_parms,
+                       dlsch0_harq->dlDmrsSymbPos);
   stop_meas(&ue->generic_stat_bis[proc->thread_id][slot]);
   if (cpumeas(CPUMEAS_GETSTATE))
     LOG_D(PHY, "[AbsSFN %u.%d] Slot%d Symbol %d type %d: Pilot/Data extraction %5.2f \n",
 	  frame,nr_slot_rx,slot,symbol,type,ue->generic_stat_bis[proc->thread_id][slot].p_time/(cpuf*1000.0));
 
-  
+  int nl = dlsch0_harq->Nl;
+  int n_rx = frame_parms->nb_antennas_rx;
+  nb_re_pdsch = (pilots==1)? ((config_type==NFAPI_NR_DMRS_TYPE1)?nb_rb_pdsch*(12-6*dlsch0_harq->n_dmrs_cdm_groups): nb_rb_pdsch*(12-4*dlsch0_harq->n_dmrs_cdm_groups)) : (nb_rb_pdsch*12);
+  //----------------------------------------------------------
+  //--------------------- Channel Scaling --------------------
+  //----------------------------------------------------------
   start_meas(&ue->generic_stat_bis[proc->thread_id][slot]);
-  n_tx = dlsch0_harq->Nl;
-  n_rx = frame_parms->nb_antennas_rx;
-  
   nr_dlsch_scale_channel(pdsch_vars[gNB_id]->dl_ch_estimates_ext,
                          frame_parms,
-                         n_tx,
+                         nl,
                          n_rx,
                          dlsch,
                          symbol,
                          pilots,
-                         len,
+                         nb_re_pdsch,
                          nb_rb_pdsch);
+  stop_meas(&ue->generic_stat_bis[proc->thread_id][slot]);
 
-    stop_meas(&ue->generic_stat_bis[proc->thread_id][slot]);
-    if (cpumeas(CPUMEAS_GETSTATE))
-      LOG_D(PHY, "[AbsSFN %u.%d] Slot%d Symbol %d: Channel Scale  %5.2f \n",frame,nr_slot_rx,slot,symbol,ue->generic_stat_bis[proc->thread_id][slot].p_time/(cpuf*1000.0));
+  if (cpumeas(CPUMEAS_GETSTATE))
+    LOG_D(PHY, "[AbsSFN %u.%d] Slot%d Symbol %d: Channel Scale  %5.2f \n",
+          frame,nr_slot_rx,slot,symbol,ue->generic_stat_bis[proc->thread_id][slot].p_time/(cpuf*1000.0));
 
-    start_meas(&ue->generic_stat_bis[proc->thread_id][slot]);
+  //----------------------------------------------------------
+  //--------------------- Channel Level Calc. ----------------
+  //----------------------------------------------------------
+  start_meas(&ue->generic_stat_bis[proc->thread_id][slot]);
   if (first_symbol_flag==1) {
-    if (beamforming_mode==0){
-      nr_dlsch_channel_level(pdsch_vars[gNB_id]->dl_ch_estimates_ext,
-                             frame_parms,
-                             n_tx,
-                             avg,
-                             symbol,
-                             len,
-                             nb_rb_pdsch);
-      avgs = 0;
-      for (aatx=0;aatx<n_tx;aatx++)
-        for (aarx=0;aarx<n_rx;aarx++) {
-          //LOG_I(PHY, "nb_rb %d len %d avg_%d_%d Power per SC is %d\n",nb_rb, len,aarx, aatx,avg[aatx*frame_parms->nb_antennas_rx+aarx]);
-          avgs = cmax(avgs,avg[(aatx*frame_parms->nb_antennas_rx)+aarx]);
-          //LOG_I(PHY, "avgs Power per SC is %d\n", avgs);
-          median[(aatx*frame_parms->nb_antennas_rx)+aarx] = avg[(aatx*frame_parms->nb_antennas_rx)+aarx];
-        }
-
-      if (dlsch0_harq->mimo_mode == NR_DUALSTREAM) {
-        nr_dlsch_channel_level_median(pdsch_vars[gNB_id]->dl_ch_estimates_ext,
-                                      median,
-                                      n_tx,
-                                      n_rx,
-                                      len,
-                                      symbol*nb_rb*12);
-
-        for (aatx = 0; aatx < n_tx; aatx++) {
-          for (aarx = 0; aarx < n_rx; aarx++) {
-            avgs = cmax(avgs, median[aatx*n_rx + aarx]);
-          }
+    nr_dlsch_channel_level(pdsch_vars[gNB_id]->dl_ch_estimates_ext,
+                           frame_parms,
+                           nl,
+                           avg,
+                           symbol,
+                           nb_re_pdsch,
+                           nb_rb_pdsch);
+    avgs = 0;
+    for (aatx=0;aatx<nl;aatx++)
+      for (aarx=0;aarx<n_rx;aarx++) {
+        //LOG_I(PHY, "nb_rb %d len %d avg_%d_%d Power per SC is %d\n",nb_rb, len,aarx, aatx,avg[aatx*n_rx+aarx]);
+        avgs = cmax(avgs,avg[(aatx*n_rx)+aarx]);
+        //LOG_I(PHY, "avgs Power per SC is %d\n", avgs);
+        median[(aatx*n_rx)+aarx] = avg[(aatx*n_rx)+aarx];
+      }
+    if (dlsch0_harq->Nl > 1) {
+      nr_dlsch_channel_level_median(pdsch_vars[gNB_id]->dl_ch_estimates_ext,
+                                    median,
+                                    nl,
+                                    n_rx,
+                                    nb_re_pdsch,
+                                    symbol*nb_rb_pdsch*12);
+      for (aatx = 0; aatx < nl; aatx++) {
+        for (aarx = 0; aarx < n_rx; aarx++) {
+          avgs = cmax(avgs, median[aatx*n_rx + aarx]);
         }
       }
-
-      pdsch_vars[gNB_id]->log2_maxh = (log2_approx(avgs)/2) + 1;
-      //LOG_I(PHY, "avgs Power per SC is %d lg2_maxh %d\n", avgs,  pdsch_vars[gNB_id]->log2_maxh);
     }
+    pdsch_vars[gNB_id]->log2_maxh = (log2_approx(avgs)/2) + 1;
+    //LOG_I(PHY, "avgs Power per SC is %d lg2_maxh %d\n", avgs,  pdsch_vars[gNB_id]->log2_maxh);
     LOG_D(PHY,"[DLSCH] AbsSubframe %d.%d log2_maxh = %d [log2_maxh0 %d log2_maxh1 %d] (%d,%d)\n",
           frame%1024,
           nr_slot_rx,
@@ -439,128 +394,83 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
           avg[0],
           avgs);
   }
+  stop_meas(&ue->generic_stat_bis[proc->thread_id][slot]);
 
 #if T_TRACER
-    if (type == PDSCH)
-    {
-      T(T_UE_PHY_PDSCH_ENERGY, T_INT(gNB_id),  T_INT(0), T_INT(frame%1024), T_INT(nr_slot_rx),
-                               T_INT(avg[0]), T_INT(avg[1]),    T_INT(avg[2]),             T_INT(avg[3]));
-    }
+  if (type == PDSCH)
+  {
+    T(T_UE_PHY_PDSCH_ENERGY, T_INT(gNB_id),  T_INT(0), T_INT(frame%1024), T_INT(nr_slot_rx),
+                             T_INT(avg[0]), T_INT(avg[1]),    T_INT(avg[2]),             T_INT(avg[3]));
+  }
 #endif
 
-    stop_meas(&ue->generic_stat_bis[proc->thread_id][slot]);
-    if (cpumeas(CPUMEAS_GETSTATE))
-      LOG_D(PHY, "[AbsSFN %u.%d] Slot%d Symbol %d first_symbol_flag %d: Channel Level  %5.2f \n",frame,nr_slot_rx,slot,symbol,first_symbol_flag,ue->generic_stat_bis[proc->thread_id][slot].p_time/(cpuf*1000.0));
-
-    start_meas(&ue->generic_stat_bis[proc->thread_id][slot]);
-// Now channel compensation
-  if (dlsch0_harq->mimo_mode<NR_DUALSTREAM) {
-    nr_dlsch_channel_compensation(pdsch_vars[gNB_id]->rxdataF_ext,
-                                  pdsch_vars[gNB_id]->dl_ch_estimates_ext,
-                                  pdsch_vars[gNB_id]->dl_ch_mag0,
-                                  pdsch_vars[gNB_id]->dl_ch_magb0,
-                                  pdsch_vars[gNB_id]->dl_ch_magr0,
-                                  pdsch_vars[gNB_id]->rxdataF_comp0,
-                                  (n_tx>1) ? pdsch_vars[gNB_id]->rho : NULL,
-                                  frame_parms,
-                                  n_tx,
-                                  symbol,
-                                  len,
-                                  first_symbol_flag,
-                                  dlsch0_harq->Qm,
-                                  nb_rb_pdsch,
-                                  pdsch_vars[gNB_id]->log2_maxh,
-                                  measurements); // log2_maxh+I0_shift
-    }
-
-  else if (dlsch0_harq->mimo_mode == NR_DUALSTREAM) {
-    nr_dlsch_channel_compensation_core(pdsch_vars[gNB_id]->rxdataF_ext,
-                                       pdsch_vars[gNB_id]->dl_ch_estimates_ext,
-                                       pdsch_vars[gNB_id]->dl_ch_mag0,
-                                       pdsch_vars[gNB_id]->dl_ch_magb0,
-                                       pdsch_vars[gNB_id]->rxdataF_comp0, //rxdataF_comp
-                                       NULL,
-                                       n_tx,
-                                       n_rx,
-                                       dlsch0_harq->Qm,
-                                       pdsch_vars[gNB_id]->log2_maxh,
-                                       2*len, // subcarriers Re Im
-                                       0); // we start from the beginning of the vector
-    // compute correlation between signal and interference channels (rho12 and rho21)
-    nr_dlsch_dual_stream_correlation_core(pdsch_vars[gNB_id]->dl_ch_estimates_ext,
-                                          &(pdsch_vars[gNB_id]->dl_ch_estimates_ext[2]),
-                                          pdsch_vars[gNB_id]->dl_ch_rho_ext[harq_pid][round],
-                                          n_tx,
-                                          n_rx,
-                                          pdsch_vars[gNB_id]->log2_maxh,
-                                          2*len,
-                                          0);
-  }
+  if (cpumeas(CPUMEAS_GETSTATE))
+    LOG_D(PHY, "[AbsSFN %u.%d] Slot%d Symbol %d first_symbol_flag %d: Channel Level  %5.2f \n",frame,nr_slot_rx,slot,symbol,first_symbol_flag,ue->generic_stat_bis[proc->thread_id][slot].p_time/(cpuf*1000.0));
 
+  //----------------------------------------------------------
+  //--------------------- channel compensation ---------------
+  //----------------------------------------------------------
+  // Disable correlation measurement for optimizing UE
+  start_meas(&ue->generic_stat_bis[proc->thread_id][slot]);
+  nr_dlsch_channel_compensation(pdsch_vars[gNB_id]->rxdataF_ext,
+                                pdsch_vars[gNB_id]->dl_ch_estimates_ext,
+                                pdsch_vars[gNB_id]->dl_ch_mag0,
+                                pdsch_vars[gNB_id]->dl_ch_magb0,
+                                pdsch_vars[gNB_id]->dl_ch_magr0,
+                                pdsch_vars[gNB_id]->rxdataF_comp0,
+                                NULL,//NULL:disable meas. pdsch_vars[gNB_id]->rho:enable meas.
+                                frame_parms,
+                                nl,
+                                symbol,
+                                nb_re_pdsch,
+                                first_symbol_flag,
+                                dlsch0_harq->Qm,
+                                nb_rb_pdsch,
+                                pdsch_vars[gNB_id]->log2_maxh,
+                                measurements); // log2_maxh+I0_shift
     stop_meas(&ue->generic_stat_bis[proc->thread_id][slot]);
     if (cpumeas(CPUMEAS_GETSTATE))
       LOG_D(PHY, "[AbsSFN %u.%d] Slot%d Symbol %d log2_maxh %d channel_level %d: Channel Comp  %5.2f \n", frame, nr_slot_rx, slot, symbol, pdsch_vars[gNB_id]->log2_maxh, proc->channel_level, ue->generic_stat_bis[proc->thread_id][slot].p_time/(cpuf*1000.0));
 
     start_meas(&ue->generic_stat_bis[proc->thread_id][slot]);
 
-  if (frame_parms->nb_antennas_rx > 1) {
-    if (dlsch0_harq->mimo_mode<NR_DUALSTREAM) {
-      nr_dlsch_detection_mrc(pdsch_vars[gNB_id]->rxdataF_comp0,
-                             (n_tx>1)? pdsch_vars[gNB_id]->rho : NULL,
-                             pdsch_vars[gNB_id]->dl_ch_mag0,
-                             pdsch_vars[gNB_id]->dl_ch_magb0,
-                             pdsch_vars[gNB_id]->dl_ch_magr0,
-                             n_tx,
-                             n_rx,
-                             symbol,
-                             nb_rb_pdsch,
-                             len);
-      if (n_tx == 2)//Apply zero forcing for 2 Tx layers
-        nr_zero_forcing_rx_2layers(pdsch_vars[gNB_id]->rxdataF_comp0,
-                                   pdsch_vars[gNB_id]->dl_ch_mag0,
-                                   pdsch_vars[gNB_id]->dl_ch_magb0,
-                                   pdsch_vars[gNB_id]->dl_ch_magr0,
-                                   pdsch_vars[gNB_id]->dl_ch_estimates_ext,
-                                   nb_rb_pdsch,
-                                   n_rx,
-                                   dlsch0_harq->Qm,
-                                   pdsch_vars[gNB_id]->log2_maxh,
-                                   symbol,
-                                   len);
-    }
-    else if (dlsch0_harq->mimo_mode == NR_DUALSTREAM) {
-      nr_dlsch_detection_mrc_core(pdsch_vars[gNB_id]->rxdataF_comp0,
-                                  NULL,
-                                  pdsch_vars[gNB_id]->dl_ch_rho_ext[harq_pid][round],
-                                  pdsch_vars[gNB_id]->dl_ch_rho2_ext,
-                                  pdsch_vars[gNB_id]->dl_ch_mag0,
-                                  pdsch_vars[gNB_id]->dl_ch_magb0,
-                                  NULL,
-                                  NULL,
-                                  n_tx,
-                                  n_rx,
-                                  2*len,
-                                  0);
-    }
+  if (n_rx > 1) {
+    nr_dlsch_detection_mrc(pdsch_vars[gNB_id]->rxdataF_comp0,
+                           (nl>1)? pdsch_vars[gNB_id]->rho : NULL,
+                           pdsch_vars[gNB_id]->dl_ch_mag0,
+                           pdsch_vars[gNB_id]->dl_ch_magb0,
+                           pdsch_vars[gNB_id]->dl_ch_magr0,
+                           nl,
+                           n_rx,
+                           symbol,
+                           nb_rb_pdsch,
+                           nb_re_pdsch);
+    if (nl >= 2)//Apply zero forcing for 2, 3, and 4 Tx layers
+      nr_zero_forcing_rx(pdsch_vars[gNB_id]->rxdataF_comp0,
+                                 pdsch_vars[gNB_id]->dl_ch_mag0,
+                                 pdsch_vars[gNB_id]->dl_ch_magb0,
+                                 pdsch_vars[gNB_id]->dl_ch_magr0,
+                                 pdsch_vars[gNB_id]->dl_ch_estimates_ext,
+                                 nb_rb_pdsch,
+                                 n_rx,
+                                 nl,
+                                 dlsch0_harq->Qm,
+                                 pdsch_vars[gNB_id]->log2_maxh,
+                                 symbol,
+                                 nb_re_pdsch);
   }
+  stop_meas(&ue->generic_stat_bis[proc->thread_id][slot]);
+
   //printf("start compute LLR\n");
-  if (dlsch0_harq->mimo_mode == NR_DUALSTREAM)  {
-    rxdataF_comp_ptr = pdsch_vars[gNB_id]->rxdataF_comp1[harq_pid][round];
-    dl_ch_mag_ptr = pdsch_vars[gNB_id]->dl_ch_mag1[harq_pid][round];
-  }
-  else {
-    rxdataF_comp_ptr = pdsch_vars[gNB_id_i]->rxdataF_comp0;
-    dl_ch_mag_ptr = pdsch_vars[gNB_id_i]->dl_ch_mag0;
-    //i_mod should have been passed as a parameter
-  }
+  rxdataF_comp_ptr = pdsch_vars[gNB_id_i]->rxdataF_comp0;
+  dl_ch_mag_ptr = pdsch_vars[gNB_id_i]->dl_ch_mag0;
   
-    stop_meas(&ue->generic_stat_bis[proc->thread_id][slot]);
-    if (cpumeas(CPUMEAS_GETSTATE))
-      LOG_D(PHY, "[AbsSFN %u.%d] Slot%d Symbol %d: Channel Combine  %5.2f \n",frame,nr_slot_rx,slot,symbol,ue->generic_stat_bis[proc->thread_id][slot].p_time/(cpuf*1000.0));
+  if (cpumeas(CPUMEAS_GETSTATE))
+    LOG_D(PHY, "[AbsSFN %u.%d] Slot%d Symbol %d: Channel Combine and zero forcing %5.2f \n",frame,nr_slot_rx,slot,symbol,ue->generic_stat_bis[proc->thread_id][slot].p_time/(cpuf*1000.0));
 
     start_meas(&ue->generic_stat_bis[proc->thread_id][slot]);
   /* Store the valid DL RE's */
-    pdsch_vars[gNB_id]->dl_valid_re[symbol-1] = len;
+    pdsch_vars[gNB_id]->dl_valid_re[symbol-1] = nb_re_pdsch;
 
     if(dlsch0_harq->status == ACTIVE) {
       startSymbIdx = dlsch0_harq->start_symbol;
@@ -583,7 +493,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
                                gNB_id,
                                nr_slot_rx,
                                symbol,
-                               (nb_rb*12),
+                               (nb_rb_pdsch*12),
                                dlsch[0]->rnti,rx_type);
       pdsch_vars[gNB_id]->dl_valid_re[symbol-1] -= pdsch_vars[gNB_id]->ptrs_re_per_slot[0][symbol];
     }
@@ -605,7 +515,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, round,
+                     i, nb_rb_pdsch, round,
                      codeword_TB0, codeword_TB1,
                      pdsch_vars[gNB_id]->dl_valid_re[i-1],
                      nr_slot_rx, beamforming_mode);
@@ -661,14 +571,14 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
 /*
   for (int i=0; i < 2; i++){
     snprintf(filename, 50,  "llr%d_symb_%d_nr_slot_rx_%d.m", i, symbol, nr_slot_rx);
-    write_output(filename,"llr",  &pdsch_vars[gNB_id]->llr[i][0], (NR_SYMBOLS_PER_SLOT*nb_rb*NR_NB_SC_PER_RB*dlsch1_harq->Qm) - 4*(nb_rb*4*dlsch1_harq->Qm), 1, 0);
+    write_output(filename,"llr",  &pdsch_vars[gNB_id]->llr[i][0], (NR_SYMBOLS_PER_SLOT*nb_rb_pdsch*NR_NB_SC_PER_RB*dlsch1_harq->Qm) - 4*(nb_rb_pdsch*4*dlsch1_harq->Qm), 1, 0);
   }
 */
 #endif
 
 #if T_TRACER
   T(T_UE_PHY_PDSCH_IQ, T_INT(gNB_id), T_INT(ue->Mod_id), T_INT(frame%1024),
-    T_INT(nr_slot_rx), T_INT(nb_rb),
+    T_INT(nr_slot_rx), T_INT(nb_rb_pdsch),
     T_INT(frame_parms->N_RB_UL), T_INT(frame_parms->symbols_per_slot),
     T_BUFFER(&pdsch_vars[gNB_id]->rxdataF_comp0[gNB_id][0], 2 * /* ulsch[UE_id]->harq_processes[harq_pid]->nb_rb */ frame_parms->N_RB_UL *12*frame_parms->symbols_per_slot*2));
 #endif
@@ -924,16 +834,16 @@ void nr_dlsch_channel_compensation(int **rxdataF_ext,
     //rho[aarx][nb_aatx*nb_aatx] = [cov(H_aarx_0,H_aarx_0) cov(H_aarx_0,H_aarx_1)
     //                              cov(H_aarx_1,H_aarx_0) cov(H_aarx_1,H_aarx_1)], aarx=0,...,nb_antennas_rx-1
 
-    int avg_rho_re[frame_parms->nb_antennas_rx][nb_aatx*nb_aatx];
-    int avg_rho_im[frame_parms->nb_antennas_rx][nb_aatx*nb_aatx];
+    //int avg_rho_re[frame_parms->nb_antennas_rx][nb_aatx*nb_aatx];
+    //int avg_rho_im[frame_parms->nb_antennas_rx][nb_aatx*nb_aatx];
 
     for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
 
       for (aatx=0; aatx<nb_aatx; aatx++) {
 
         for (atx=0; atx<nb_aatx; atx++) {
-          avg_rho_re[aarx][aatx*nb_aatx+atx] = 0;
-          avg_rho_im[aarx][aatx*nb_aatx+atx] = 0;
+          //avg_rho_re[aarx][aatx*nb_aatx+atx] = 0;
+          //avg_rho_im[aarx][aatx*nb_aatx+atx] = 0;
           rho128        = (__m128i *)&rho[aarx][aatx*nb_aatx+atx][symbol*nb_rb*12];
           dl_ch128      = (__m128i *)&dl_ch_estimates_ext[aatx*frame_parms->nb_antennas_rx+aarx][symbol*nb_rb*12];
           dl_ch128_2    = (__m128i *)&dl_ch_estimates_ext[atx*frame_parms->nb_antennas_rx+aarx][symbol*nb_rb*12];
@@ -962,15 +872,14 @@ void nr_dlsch_channel_compensation(int **rxdataF_ext,
             //print_shorts("ch:",dl_ch128);
             //print_shorts("pack:",rho128);
 
-            avg_rho_re[aarx][aatx*nb_aatx+atx] +=(((int16_t*)&rho128[0])[0]+
+            /*avg_rho_re[aarx][aatx*nb_aatx+atx] +=(((int16_t*)&rho128[0])[0]+
               ((int16_t*)&rho128[0])[2] +
               ((int16_t*)&rho128[0])[4] +
-              ((int16_t*)&rho128[0])[6])/16;//
-
-            avg_rho_im[aarx][aatx*nb_aatx+atx] +=(((int16_t*)&rho128[0])[1]+
+              ((int16_t*)&rho128[0])[6])/16;*/
+            /*avg_rho_im[aarx][aatx*nb_aatx+atx] +=(((int16_t*)&rho128[0])[1]+
               ((int16_t*)&rho128[0])[3] +
               ((int16_t*)&rho128[0])[5] +
-              ((int16_t*)&rho128[0])[7])/16;//
+              ((int16_t*)&rho128[0])[7])/16;*/
 
             // multiply by conjugated channel
             mmtmpD0 = _mm_madd_epi16(dl_ch128[1],dl_ch128_2[1]);
@@ -990,15 +899,14 @@ void nr_dlsch_channel_compensation(int **rxdataF_ext,
             //print_shorts("pack:",rho128+1);
 
             // multiply by conjugated channel
-            avg_rho_re[aarx][aatx*nb_aatx+atx] +=(((int16_t*)&rho128[1])[0]+
+            /*avg_rho_re[aarx][aatx*nb_aatx+atx] +=(((int16_t*)&rho128[1])[0]+
               ((int16_t*)&rho128[1])[2] +
               ((int16_t*)&rho128[1])[4] +
-              ((int16_t*)&rho128[1])[6])/16;
-
-            avg_rho_im[aarx][aatx*nb_aatx+atx] +=(((int16_t*)&rho128[1])[1]+
+              ((int16_t*)&rho128[1])[6])/16;*/
+            /*avg_rho_im[aarx][aatx*nb_aatx+atx] +=(((int16_t*)&rho128[1])[1]+
               ((int16_t*)&rho128[1])[3] +
               ((int16_t*)&rho128[1])[5] +
-              ((int16_t*)&rho128[1])[7])/16;
+              ((int16_t*)&rho128[1])[7])/16;*/
 
             mmtmpD0 = _mm_madd_epi16(dl_ch128[2],dl_ch128_2[2]);
             // mmtmpD0 contains real part of 4 consecutive outputs (32-bit)
@@ -1016,25 +924,28 @@ void nr_dlsch_channel_compensation(int **rxdataF_ext,
             //print_shorts("rx:",dl_ch128_2+2);
             //print_shorts("ch:",dl_ch128+2);
             //print_shorts("pack:",rho128+2);
-            avg_rho_re[aarx][aatx*nb_aatx+atx] +=(((int16_t*)&rho128[2])[0]+
+
+            /*avg_rho_re[aarx][aatx*nb_aatx+atx] +=(((int16_t*)&rho128[2])[0]+
               ((int16_t*)&rho128[2])[2] +
               ((int16_t*)&rho128[2])[4] +
-              ((int16_t*)&rho128[2])[6])/16;
-
-            avg_rho_im[aarx][aatx*nb_aatx+atx] +=(((int16_t*)&rho128[2])[1]+
+              ((int16_t*)&rho128[2])[6])/16;*/
+            /*avg_rho_im[aarx][aatx*nb_aatx+atx] +=(((int16_t*)&rho128[2])[1]+
               ((int16_t*)&rho128[2])[3] +
               ((int16_t*)&rho128[2])[5] +
-              ((int16_t*)&rho128[2])[7])/16;
+              ((int16_t*)&rho128[2])[7])/16;*/
 
             dl_ch128+=3;
             dl_ch128_2+=3;
             rho128+=3;
           }
           if (first_symbol_flag==1) {
-            //measurements->rx_correlation[0][0][aarx] = signal_energy(&rho[aarx][aatx*nb_aatx+atx][symbol*nb_rb*12],rb*12);
-            avg_rho_re[aarx][aatx*nb_aatx+atx] = 16*avg_rho_re[aarx][aatx*nb_aatx+atx]/(nb_rb*12);
-            avg_rho_im[aarx][aatx*nb_aatx+atx] = 16*avg_rho_im[aarx][aatx*nb_aatx+atx]/(nb_rb*12);
+            //rho_nm = H_arx_n.conj(H_arx_m)
+            //rho_rx_corr[arx][nm] = |H_arx_n|^2.|H_arx_m|^2 &rho[aarx][aatx*nb_aatx+atx][symbol*nb_rb*12]
+            measurements->rx_correlation[0][aarx][aatx*nb_aatx+atx] = signal_energy(&rho[aarx][aatx*nb_aatx+atx][symbol*nb_rb*12],length);
+            //avg_rho_re[aarx][aatx*nb_aatx+atx] = 16*avg_rho_re[aarx][aatx*nb_aatx+atx]/length;
+            //avg_rho_im[aarx][aatx*nb_aatx+atx] = 16*avg_rho_im[aarx][aatx*nb_aatx+atx]/length;
             //printf("rho[rx]%d tx%d tx%d = Re: %d Im: %d\n",aarx, aatx,atx, avg_rho_re[aarx][aatx*nb_aatx+atx], avg_rho_im[aarx][aatx*nb_aatx+atx]);
+            //printf("rho_corr[rx]%d tx%d tx%d = %d ...\n",aarx, aatx,atx, measurements->rx_correlation[0][aarx][aatx*nb_aatx+atx]);
           }
         }
       }
@@ -1687,294 +1598,6 @@ void nr_dlsch_channel_level_median(int **dl_ch_estimates_ext,
 
 }
 
-static void nr_dlsch_dual_stream_correlation_core(int **dl_ch_estimates_ext,
-                                        int **dl_ch_estimates_ext_i,
-                                        int **dl_ch_rho_ext,
-                                        unsigned char n_tx,
-                                        unsigned char n_rx,
-                                        unsigned char output_shift,
-                                        int length,
-                                        int start_point)
-{
-#if defined(__x86_64__)||defined(__i386__)
-
-  __m128i *dl_ch128,*dl_ch128i,*dl_ch_rho128,mmtmpD0,mmtmpD1,mmtmpD2,mmtmpD3;
-  unsigned char aarx;
-  int ii, length2, length_mod8;
-
-
-  for (aarx=0; aarx<n_rx; aarx++) {
-
-    dl_ch128          = (__m128i *)&dl_ch_estimates_ext[aarx][start_point];
-
-    if (dl_ch_estimates_ext_i == NULL)
-      dl_ch128i         = (__m128i *)&dl_ch_estimates_ext[aarx + n_rx][start_point];
-    else
-      dl_ch128i         = (__m128i *)&dl_ch_estimates_ext_i[aarx][start_point];
-
-    dl_ch_rho128      = (__m128i *)&dl_ch_rho_ext[aarx][start_point];
-
-    length_mod8 = length&7;
-
-    if (length_mod8 == 0){
-      length2 = length>>3;
-
-      for (ii=0; ii<length2; ++ii) {
-      // multiply by conjugated channel
-        mmtmpD0 = _mm_madd_epi16(dl_ch128[0],dl_ch128i[0]);
-        //      print_ints("re",&mmtmpD0);
-        // mmtmpD0 contains real part of 4 consecutive outputs (32-bit)
-        mmtmpD1 = _mm_shufflelo_epi16(dl_ch128[0],_MM_SHUFFLE(2,3,0,1));
-        mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1));
-        mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)&conjugate[0]);
-        mmtmpD1 = _mm_madd_epi16(mmtmpD1,dl_ch128i[0]);
-        //      print_ints("im",&mmtmpD1);
-        // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit)
-        mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift);
-        //      print_ints("re(shift)",&mmtmpD0);
-        mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift);
-        //      print_ints("im(shift)",&mmtmpD1);
-        mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1);
-        mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1);
-        //      print_ints("c0",&mmtmpD2);
-        //      print_ints("c1",&mmtmpD3);
-        dl_ch_rho128[0] = _mm_packs_epi32(mmtmpD2,mmtmpD3);
-      // print_shorts("rho 0:",dl_ch_rho128);
-        // multiply by conjugated channel
-        mmtmpD0 = _mm_madd_epi16(dl_ch128[1],dl_ch128i[1]);
-        // mmtmpD0 contains real part of 4 consecutive outputs (32-bit)
-        mmtmpD1 = _mm_shufflelo_epi16(dl_ch128[1],_MM_SHUFFLE(2,3,0,1));
-        mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1));
-        mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)conjugate);
-        mmtmpD1 = _mm_madd_epi16(mmtmpD1,dl_ch128i[1]);
-        // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit)
-        mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift);
-        mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift);
-        mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1);
-        mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1);
-        dl_ch_rho128[1] =_mm_packs_epi32(mmtmpD2,mmtmpD3);
-
-        dl_ch128+=2;
-        dl_ch128i+=2;
-        dl_ch_rho128+=2;
-      }
-
-    }else {
-        printf ("Channel Correlarion: Received number of subcarriers is not multiple of 8, \n"
-                 "need to adapt the code!\n");
-      }
-
-  }
-
-  _mm_empty();
-  _m_empty();
-
-#elif defined(__arm__)
-
-#endif
-}
-
-void nr_dlsch_detection_mrc_core(int **rxdataF_comp,
-                              int **rxdataF_comp_i,
-                              int **rho,
-                              int **rho_i,
-                              int **dl_ch_mag,
-                              int **dl_ch_magb,
-                              int **dl_ch_mag_i,
-                              int **dl_ch_magb_i,
-                              unsigned char n_tx,
-                              unsigned char n_rx,
-                              int length,
-                              int start_point)
-{
-
-#if defined(__x86_64__)||defined(__i386__)
-
-  unsigned char aatx;
-  int i;
-  __m128i *rxdataF_comp128_0, *rxdataF_comp128_1, *rxdataF_comp128_2, *rxdataF_comp128_3;
-  __m128i *dl_ch_mag128_0, *dl_ch_mag128_1, *dl_ch_mag128_2, *dl_ch_mag128_3;
-  __m128i *dl_ch_mag128_0b, *dl_ch_mag128_1b,  *dl_ch_mag128_2b,  *dl_ch_mag128_3b;
-  __m128i *rho128_0, *rho128_1, *rho128_2=NULL, *rho128_3=NULL;
-  __m128i *rho128_i0, *rho128_i1, *rho128_i2=NULL, *rho128_i3=NULL;
-  int length_mod4 = 0;
-  int length2;
-
-  if (n_rx>1) {
-
-    for (aatx=0; aatx<n_tx; aatx++) {
-
-      rxdataF_comp128_0   = (__m128i *)&rxdataF_comp[(aatx<<1)][start_point];
-      rxdataF_comp128_1   = (__m128i *)&rxdataF_comp[(aatx<<1)+1][start_point];
-      dl_ch_mag128_0      = (__m128i *)&dl_ch_mag[(aatx<<1)][start_point];
-      dl_ch_mag128_1      = (__m128i *)&dl_ch_mag[(aatx<<1)+1][start_point];
-      dl_ch_mag128_0b     = (__m128i *)&dl_ch_magb[(aatx<<1)][start_point];
-      dl_ch_mag128_1b     = (__m128i *)&dl_ch_magb[(aatx<<1)+1][start_point];
-
-      if (length_mod4 == 0){
-        length2 = length>>2;
-
-        for (i=0; i<length2; ++i) {
-          rxdataF_comp128_0[i] = _mm_adds_epi16(_mm_srai_epi16(rxdataF_comp128_0[i],1),_mm_srai_epi16(rxdataF_comp128_1[i],1));
-          dl_ch_mag128_0[i] = _mm_adds_epi16(_mm_srai_epi16(dl_ch_mag128_0[i],1),_mm_srai_epi16(dl_ch_mag128_1[i],1));
-          dl_ch_mag128_0b[i] = _mm_adds_epi16(_mm_srai_epi16(dl_ch_mag128_0b[i],1),_mm_srai_epi16(dl_ch_mag128_1b[i],1));
-        }
-      }
-    }
-
-
-    if (rho) {
-      rho128_0 = (__m128i *) &rho[0][start_point];
-      rho128_1 = (__m128i *) &rho[1][start_point];
-
-      if (n_tx == 4){
-        rho128_2 = (__m128i *) &rho[2][start_point];
-        rho128_3 = (__m128i *) &rho[3][start_point];
-      }
-        if (length_mod4 == 0){
-          length2 = length>>2;
-
-          for (i=0; i<length2; ++i) {
-            rho128_0[i] = _mm_adds_epi16(_mm_srai_epi16(rho128_0[i],1),_mm_srai_epi16(rho128_1[i],1));
-          if (n_tx == 4){
-            rho128_2[i] = _mm_adds_epi16(_mm_srai_epi16(rho128_2[i],1),_mm_srai_epi16(rho128_3[i],1));
-          }
-        }
-      }
-    }
-
-    if (rho_i){
-      rho128_i0 = (__m128i *) &rho_i[0][start_point];
-      rho128_i1 = (__m128i *) &rho_i[1][start_point];
-      if (n_tx == 4){
-        rho128_i2 = (__m128i *) &rho_i[2][start_point];
-        rho128_i3 = (__m128i *) &rho_i[3][start_point];
-      }
-      if (length_mod4 == 0){
-        length2 = length>>2;
-
-        for (i=0; i<length2; ++i){
-          rho128_i0[i] = _mm_adds_epi16(_mm_srai_epi16(rho128_i0[i],1),_mm_srai_epi16(rho128_i1[i],1));
-          if (n_tx == 4){
-            rho128_i2[i] = _mm_adds_epi16(_mm_srai_epi16(rho128_i2[i],1),_mm_srai_epi16(rho128_i3[i],1));
-          }
-        }
-      }
-    }
-
-      if (n_tx == 4){
-
-      rxdataF_comp128_0 = (__m128i *)&rxdataF_comp[0][start_point];
-      rxdataF_comp128_1 = (__m128i *)&rxdataF_comp[2][start_point];
-      rxdataF_comp128_2 = (__m128i *)&rxdataF_comp[4][start_point];
-      rxdataF_comp128_3 = (__m128i *)&rxdataF_comp[6][start_point];
-
-      dl_ch_mag128_0 = (__m128i *)&dl_ch_mag[0][start_point];
-      dl_ch_mag128_1 = (__m128i *)&dl_ch_mag[2][start_point];
-      dl_ch_mag128_2 = (__m128i *)&dl_ch_mag[4][start_point];
-      dl_ch_mag128_3 = (__m128i *)&dl_ch_mag[6][start_point];
-
-      dl_ch_mag128_0b = (__m128i *)&dl_ch_magb[0][start_point];
-      dl_ch_mag128_1b = (__m128i *)&dl_ch_magb[2][start_point];
-      dl_ch_mag128_2b = (__m128i *)&dl_ch_magb[4][start_point];
-      dl_ch_mag128_3b = (__m128i *)&dl_ch_magb[6][start_point];
-
-      rho128_0 = (__m128i *)&rho[0][start_point];
-      rho128_1 = (__m128i *)&rho[2][start_point];
-
-      rho128_i0 = (__m128i *)&rho_i[0][start_point];
-      rho128_i1 = (__m128i *)&rho_i[2][start_point];
-
-
-      if (length_mod4 == 0){
-
-        length2 = length>>2;
-
-        for (i=0; i<length2; ++i) {
-          rxdataF_comp128_0[i] = _mm_adds_epi16(_mm_srai_epi16(rxdataF_comp128_0[i],1),_mm_srai_epi16(rxdataF_comp128_1[i],1));
-          rxdataF_comp128_2[i] = _mm_adds_epi16(_mm_srai_epi16(rxdataF_comp128_2[i],1),_mm_srai_epi16(rxdataF_comp128_3[i],1));
-
-          dl_ch_mag128_0[i] = _mm_adds_epi16(_mm_srai_epi16(dl_ch_mag128_0[i],1),_mm_srai_epi16(dl_ch_mag128_1[i],1));
-          dl_ch_mag128_2[i] = _mm_adds_epi16(_mm_srai_epi16(dl_ch_mag128_2[i],1),_mm_srai_epi16(dl_ch_mag128_3[i],1));
-
-          dl_ch_mag128_0b[i] = _mm_adds_epi16(_mm_srai_epi16(dl_ch_mag128_0b[i],1),_mm_srai_epi16(dl_ch_mag128_1b[i],1));
-          dl_ch_mag128_2b[i] = _mm_adds_epi16(_mm_srai_epi16(dl_ch_mag128_2b[i],1),_mm_srai_epi16(dl_ch_mag128_3b[i],1));
-
-          rho128_0[i] = _mm_adds_epi16(_mm_srai_epi16(rho128_0[i],1),_mm_srai_epi16(rho128_1[i],1));
-
-          rho128_i0[i] = _mm_adds_epi16(_mm_srai_epi16(rho128_i0[i],1),_mm_srai_epi16(rho128_i1[i],1));
-        }
-    }
-  }
-
-  }
-
-  _mm_empty();
-  _m_empty();
-
-#elif defined(__arm__)
-
-  unsigned char aatx;
-  int i;
-  int16x8_t *rxdataF_comp128_0,*rxdataF_comp128_1,*dl_ch_mag128_0,*dl_ch_mag128_1,*dl_ch_mag128_0b,*dl_ch_mag128_1b,*rho128_0,*rho128_1,*rho128_i0,*rho128_i1;
-  int length_mod4 = 0;
-  int length2;
-  int ii=0;
-
-  if (n_rx>1) {
-
-    for (aatx=0; aatx<n_tx; aatx++) {
-
-      rxdataF_comp128_0   = (int16x8_t *)&rxdataF_comp[(aatx<<1)][start_point];
-      rxdataF_comp128_1   = (int16x8_t *)&rxdataF_comp[(aatx<<1)+1][start_point];
-      dl_ch_mag128_0      = (int16x8_t *)&dl_ch_mag[(aatx<<1)][start_point];
-      dl_ch_mag128_1      = (int16x8_t *)&dl_ch_mag[(aatx<<1)+1][start_point];
-      dl_ch_mag128_0b     = (int16x8_t *)&dl_ch_magb[(aatx<<1)][start_point];
-      dl_ch_mag128_1b     = (int16x8_t *)&dl_ch_magb[(aatx<<1)+1][start_point];
-
-      if (length_mod4 == 0){
-        length2 = length>>2;
-
-        for (i=0; i<length2; ++ii) {
-          rxdataF_comp128_0[i] = vhaddq_s16(rxdataF_comp128_0[i],rxdataF_comp128_1[i]);
-          dl_ch_mag128_0[i]    = vhaddq_s16(dl_ch_mag128_0[i],dl_ch_mag128_1[i]);
-          dl_ch_mag128_0b[i]   = vhaddq_s16(dl_ch_mag128_0b[i],dl_ch_mag128_1b[i]);
-        }
-      }
-
-    if (rho) {
-      rho128_0 = (int16x8_t *) &rho[0][start_point];
-      rho128_1 = (int16x8_t *) &rho[1][start_point];
-
-      if (length_mod4 == 0){
-        length2 = length>>2;
-
-        for (i=0; i<length2; ++i) {
-          rho128_0[i] = vhaddq_s16(rho128_0[i],rho128_1[i]);
-        }
-      }
-    }
-
-    if (rho_i){
-
-      rho128_i0 = (__m128i *) &rho_i[0][start_point];
-      rho128_i1 = (__m128i *) &rho_i[1][start_point];
-
-      if (length_mod4 == 0){
-        length2 = length>>2;
-
-        for (i=0; i<length2; ++i)
-          rho128_i0[i] = vhaddq_s16(rho128_i0[i],rho128_i1[i]);
-
-      }
-    }
-  }
-
-  }
-
-#endif
-}
-
 //==============================================================================================
 // Extraction functions
 //==============================================================================================
@@ -2076,19 +1699,19 @@ unsigned short nr_dlsch_extract_rbs_single(int **rxdataF,
   return nb_rb_pdsch;
 }
 
-unsigned short nr_dlsch_extract_rbs_multiple(int **rxdataF,
-                                             int **dl_ch_estimates,
-                                             int **rxdataF_ext,
-                                             int **dl_ch_estimates_ext,
-                                             unsigned char symbol,
-                                             uint8_t pilots,
-                                             uint8_t config_type,
-                                             unsigned short start_rb,
-                                             unsigned short nb_rb_pdsch,
-                                             uint8_t n_dmrs_cdm_groups,
-                                             uint8_t Nl,
-                                             NR_DL_FRAME_PARMS *frame_parms,
-                                             uint16_t dlDmrsSymbPos)
+void nr_dlsch_extract_rbs(int **rxdataF,
+                          int **dl_ch_estimates,
+                          int **rxdataF_ext,
+                          int **dl_ch_estimates_ext,
+                          unsigned char symbol,
+                          uint8_t pilots,
+                          uint8_t config_type,
+                          unsigned short start_rb,
+                          unsigned short nb_rb_pdsch,
+                          uint8_t n_dmrs_cdm_groups,
+                          uint8_t Nl,
+                          NR_DL_FRAME_PARMS *frame_parms,
+                          uint16_t dlDmrsSymbPos)
 {
 
   unsigned short k,rb;
@@ -2173,7 +1796,6 @@ unsigned short nr_dlsch_extract_rbs_multiple(int **rxdataF,
       }//rb
     }//aatx
   }//aarx
-  return(nb_rb_pdsch);
 }
 
 void nr_dlsch_detection_mrc(int **rxdataF_comp,
@@ -2240,108 +1862,351 @@ void nr_dlsch_detection_mrc(int **rxdataF_comp,
 #endif
 }
 
-/* Zero Forcing Rx function: nr_det_HhH()
+/* Zero Forcing Rx function: nr_a_sum_b()
+ * Compute the complex addition x=x+y
  *
+ * */
+void nr_a_sum_b(__m128i *input_x,
+                __m128i *input_y,
+                unsigned short nb_rb)
+{
+  unsigned short rb;
+
+  for (rb=0; rb<nb_rb; rb++) {
+
+    input_x[0] = _mm_adds_epi16(input_x[0],input_y[0]);
+    input_x[1] = _mm_adds_epi16(input_x[1],input_y[1]);
+    input_x[2] = _mm_adds_epi16(input_x[2],input_y[2]);
+
+    input_x+=3;
+    input_y+=3;
+  }
+  _mm_empty();
+  _m_empty();
+}
+
+/* Zero Forcing Rx function: nr_a_mult_b()
+ * Compute the complex Multiplication c=a*b
  *
  * */
-void nr_det_HhH(int32_t *after_mf_00,//a
-                int32_t *after_mf_01,//b
-                int32_t *after_mf_10,//c
-                int32_t *after_mf_11,//d
-                int32_t *det_fin,//1/ad-bc
-                unsigned short nb_rb,
-                unsigned char symbol,
-                int32_t shift)
+void nr_a_mult_b(int *a,
+                 int *b,
+                 int32_t *c,
+                 unsigned short nb_rb,
+                 unsigned char output_shift0)
 {
-  int16_t nr_conjug2[8]__attribute__((aligned(16))) = {1,-1,1,-1,1,-1,1,-1} ;
+  //This function is used to compute complex multiplications
+  short nr_conjugate[8]__attribute__((aligned(16))) = {1,-1,1,-1,1,-1,1,-1};
   unsigned short rb;
-  __m128i *after_mf_00_128,*after_mf_01_128, *after_mf_10_128, *after_mf_11_128, ad_re_128, bc_re_128; //ad_im_128, bc_im_128;
-  __m128i *det_fin_128, det_re_128; //det_im_128, tmp_det0, tmp_det1;
+  __m128i *a_128,*b_128, *c_128, mmtmpD0,mmtmpD1,mmtmpD2,mmtmpD3;
 
-  after_mf_00_128 = (__m128i *)after_mf_00;
-  after_mf_01_128 = (__m128i *)after_mf_01;
-  after_mf_10_128 = (__m128i *)after_mf_10;
-  after_mf_11_128 = (__m128i *)after_mf_11;
+  a_128 = (__m128i *)a;
+  b_128 = (__m128i *)b;
 
-  det_fin_128 = (__m128i *)det_fin;
+  c_128 = (__m128i *)c;
 
   for (rb=0; rb<3*nb_rb; rb++) {
+    // the real part
+    mmtmpD0 = _mm_sign_epi16(a_128[0],*(__m128i*)&nr_conjugate[0]);
+    mmtmpD0 = _mm_madd_epi16(mmtmpD0,b_128[0]); //Re: (a_re*b_re - a_im*b_im)
+
+    // the imag part
+    mmtmpD1 = _mm_shufflelo_epi16(a_128[0],_MM_SHUFFLE(2,3,0,1));
+    mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1));
+    mmtmpD1 = _mm_madd_epi16(mmtmpD1,b_128[0]);//Im: (x_im*y_re + x_re*y_im)
+
+    mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift0);
+    mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift0);
+    mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1);
+    mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1);
 
-    //complex multiplication (I_a+jQ_a)(I_d+jQ_d) = (I_aI_d - Q_aQ_d) + j(Q_aI_d + I_aQ_d)
-    //The imag part is often zero, we compute only the real part
-    ad_re_128 = _mm_sign_epi16(after_mf_00_128[0],*(__m128i*)&nr_conjug2[0]);
-    ad_re_128 = _mm_madd_epi16(ad_re_128,after_mf_11_128[0]); //Re: I_a0*I_d0 - Q_a1*Q_d1
-    //ad_im_128 = _mm_shufflelo_epi16(after_mf_00_128[0],_MM_SHUFFLE(2,3,0,1));//permutes IQs for the low 64 bits as [I_a0 Q_a1 I_a2 Q_a3]_64bits to [Q_a1 I_a0 Q_a3 I_a2]_64bits
-    //ad_im_128 = _mm_shufflehi_epi16(ad_im_128,_MM_SHUFFLE(2,3,0,1));//permutes IQs for the high 64 bits as [I_a0 Q_a1 I_a2 Q_a3]_64bits to [Q_a1 I_a0 Q_a3 I_a2]_64bits
-    //ad_im_128 = _mm_madd_epi16(ad_im_128,after_mf_11_128[0]);//Im: (Q_aI_d + I_aQ_d)
+    c_128[0] = _mm_packs_epi32(mmtmpD2,mmtmpD3);
+
+    /*printf("\n Computing mult \n");
+    print_shorts("a:",(int16_t*)&a_128[0]);
+    print_shorts("b:",(int16_t*)&b_128[0]);
+    print_shorts("pack:",(int16_t*)&c_128[0]);*/
+
+    a_128+=1;
+    b_128+=1;
+    c_128+=1;
+  }
+  _mm_empty();
+  _m_empty();
+}
 
-    //complex multiplication (I_b+jQ_b)(I_c+jQ_c) = (I_bI_c - Q_bQ_c) + j(Q_bI_c + I_bQ_c)
-    //The imag part is often zero, we compute only the real part
-    bc_re_128 = _mm_sign_epi16(after_mf_01_128[0],*(__m128i*)&nr_conjug2[0]);
-    bc_re_128 = _mm_madd_epi16(bc_re_128,after_mf_10_128[0]); //Re: I_b0*I_c0 - Q_b1*Q_c1
-    //bc_im_128 = _mm_shufflelo_epi16(after_mf_01_128[0],_MM_SHUFFLE(2,3,0,1));//permutes IQs for the low 64 bits as [I_b0 Q_b1 I_b2 Q_b3]_64bits to [Q_b1 I_b0 Q_b3 I_b2]_64bits
-    //bc_im_128 = _mm_shufflehi_epi16(bc_im_128,_MM_SHUFFLE(2,3,0,1));//permutes IQs for the high 64 bits as [I_b0 Q_b1 I_b2 Q_b3]_64bits to [Q_b1 I_b0 Q_b3 I_b2]_64bits
-    //bc_im_128 = _mm_madd_epi16(bc_im_128,after_mf_10_128[0]);//Im: (Q_bI_c + I_bQ_c)
+/* Zero Forcing Rx function: nr_element_sign()
+ * Compute b=sign*a
+ *
+ * */
+void nr_element_sign(int32_t *a,//a
+                     int32_t *b,//b
+                     unsigned short nb_rb,
+                     int32_t sign)
+{
+  int16_t nr_sign[8]__attribute__((aligned(16))) = {-1,-1,-1,-1,-1,-1,-1,-1} ;
+  unsigned short rb;
+  __m128i *a_128,*b_128;
 
-    det_re_128 = _mm_sub_epi32(ad_re_128, bc_re_128);
-    //det_im_128 = _mm_sub_epi32(ad_im_128, bc_im_128);
+  a_128 = (__m128i *)a;
+  b_128 = (__m128i *)b;
 
-    //det in Q30 format
-    det_fin_128[0] = _mm_abs_epi32(det_re_128);
+  for (rb=0; rb<3*nb_rb; rb++) {
 
+    if (sign < 0)
+      b_128[0] = _mm_sign_epi16(a_128[0],*(__m128i*)&nr_sign[0]);
+    else
+      b_128[0] = a_128[0];
 
 #ifdef DEBUG_DLSCH_DEMOD
-     printf("\n Computing det_HhH_inv \n");
+     printf("\n Out \n");
      //print_ints("det_re_128:",(int32_t*)&det_re_128);
      //print_ints("det_im_128:",(int32_t*)&det_im_128);
-     print_ints("det_fin_128:",(int32_t*)&det_fin_128[0]);
+     print_shorts("b:",(int32_t*)&b_128[0]);
 #endif
-    det_fin_128+=1;
-    after_mf_00_128+=1;
-    after_mf_01_128+=1;
-    after_mf_10_128+=1;
-    after_mf_11_128+=1;
+    a_128+=1;
+    b_128+=1;
   }
   _mm_empty();
   _m_empty();
 }
 
-/* Zero Forcing Rx function: nr_inv_comp_muli
- * Complex number multi: z = x*y
- *                         = (x_re*y_re - x_im*y_im) + j(x_im*y_re + x_re*y_im)
+/* Zero Forcing Rx function: nr_det_4x4()
+ * Compute the matrix determinant for 4x4 Matrix
+ *
  * */
-__m128i nr_inv_comp_muli(__m128i input_x,
-                         __m128i input_y)
-{
-  int16_t nr_conjug2[8]__attribute__((aligned(16))) = {1,-1,1,-1,1,-1,1,-1} ;
-
-  __m128i xy_re_128, xy_im_128;
-  __m128i output_z, tmp_z0, tmp_z1;
+void nr_determin(int32_t **a44,//
+                 int32_t *ad_bc,//ad-bc
+                 int32_t size,
+                 unsigned short nb_rb,
+                 int32_t sign,
+                 int32_t shift0){
+
+  int32_t outtemp[12*nb_rb] __attribute__((aligned(32)));
+  int32_t outtemp1[12*nb_rb] __attribute__((aligned(32)));
+  int32_t **sub_matrix;
+  sub_matrix = (int32_t **)malloc16_clear( (size-1)*(size-1)*sizeof(int32_t *) );
+  for (int rtx=0;rtx<(size-1);rtx++) {//row
+    for (int ctx=0;ctx<(size-1);ctx++) {//column
+      sub_matrix[ctx*(size-1)+rtx] = (int32_t *)malloc16_clear( 12*nb_rb*sizeof(int32_t) );
+    }
+  }
+  int16_t k,rr[size-1],cc[size-1];
 
-  // complex multiplication (x_re + jx_im)*(y_re + jy_im) = (x_re*y_re - x_im*y_im) + j(x_im*y_re + x_re*y_im)
+  if(size==1) {
+    nr_element_sign(a44[0],//a
+                    ad_bc,//b
+                    nb_rb,
+                    sign);
+  } else {
 
-  // the real part
-  xy_re_128 = _mm_sign_epi16(input_x,*(__m128i*)&nr_conjug2[0]);
-  xy_re_128 = _mm_madd_epi16(xy_re_128,input_y); //Re: (x_re*y_re - x_im*y_im)
+    for (int rtx=0;rtx<size;rtx++) {//row calculation for determin
+      int ctx=0;
+      //find the submatrix row and column indices
+      k=0;
+      for(int rrtx=0;rrtx<size;rrtx++)
+        if(rrtx != rtx) rr[k++] = rrtx;
+      k=0;
+      for(int cctx=0;cctx<size;cctx++)
+        if(cctx != ctx) cc[k++] = cctx;
+      //fill out the sub matrix corresponds to this element
+       for (int ridx=0;ridx<(size-1);ridx++)
+         for (int cidx=0;cidx<(size-1);cidx++)
+           sub_matrix[cidx*(size-1)+ridx]= (int32_t *)&a44[cc[cidx]*size+rr[ridx]][0];
+
+       nr_determin(sub_matrix,//a33
+                   outtemp,
+                   size-1,
+                   nb_rb,
+                   ((rtx&1)==1?-1:1)*((ctx&1)==1?-1:1)*sign,
+                   shift0);
+       nr_a_mult_b(a44[ctx*size+rtx],
+                   outtemp,
+                   rtx==0? ad_bc:outtemp1,
+                   nb_rb,
+                   shift0);
+
+       if (rtx != 0)
+         nr_a_sum_b((__m128i *)ad_bc,
+                    (__m128i *)outtemp1,
+                    nb_rb);
+    }
+  }
+  _mm_empty();
+  _m_empty();
+}
 
-  // the imag part
-  xy_im_128 = _mm_shufflelo_epi16(input_x,_MM_SHUFFLE(2,3,0,1));//permutes IQs for the low 64 bits as [I_a0 Q_a1 I_a2 Q_a3]_64bits to [Q_a1 I_a0 Q_a3 I_a2]_64bits
-  xy_im_128 = _mm_shufflehi_epi16(xy_im_128,_MM_SHUFFLE(2,3,0,1));//permutes IQs for the high 64 bits as [I_a0 Q_a1 I_a2 Q_a3]_64bits to [Q_a1 I_a0 Q_a3 I_a2]_64bits
-  xy_im_128 = _mm_madd_epi16(xy_im_128,input_y);//Im: (x_im*y_re + x_re*y_im)
+double complex nr_determin_cpx(double complex *a44_cpx,//
+                               int32_t size,//size
+                               int32_t sign){
+  double complex outtemp, outtemp1;
+  //Allocate the submatrix elements
+  double complex sub_matrix[(size-1)*(size-1)];
+  int16_t k,rr[size-1],cc[size-1];
+
+  if(size==1) {
+    return((double complex)a44_cpx[0]*sign);
+  }else {
+    outtemp1 = 0;
+    for (int rtx=0;rtx<size;rtx++) {//row calculation for determin
+      int ctx=0;
+      //find the submatrix row and column indices
+      k=0;
+      for(int rrtx=0;rrtx<size;rrtx++)
+        if(rrtx != rtx) rr[k++] = rrtx;
+      k=0;
+      for(int cctx=0;cctx<size;cctx++)
+        if(cctx != ctx) cc[k++] = cctx;
+      //fill out the sub matrix corresponds to this element
+       for (int ridx=0;ridx<(size-1);ridx++)
+         for (int cidx=0;cidx<(size-1);cidx++)
+           sub_matrix[cidx*(size-1)+ridx]= a44_cpx[cc[cidx]*size+rr[ridx]];
+
+       outtemp = nr_determin_cpx(sub_matrix,//a33
+                             size-1,
+                             ((rtx&1)==1?-1:1)*((ctx&1)==1?-1:1)*sign);
+       outtemp1 += a44_cpx[ctx*size+rtx]*outtemp;
+    }
 
-  //convert back to Q15 before packing
-  xy_re_128 = _mm_srai_epi32(xy_re_128,4);//(2^15/64*2*16)
-  xy_im_128 = _mm_srai_epi32(xy_im_128,4);
+    return((double complex)outtemp1);
+  }
+}
 
-  tmp_z0  = _mm_unpacklo_epi32(xy_re_128,xy_im_128);
-  //print_ints("unpack lo:",&tmp_z0[0]);
-  tmp_z1  = _mm_unpackhi_epi32(xy_re_128,xy_im_128);
-  //print_ints("unpack hi:",&tmp_z1[0]);
-  output_z = _mm_packs_epi32(tmp_z0,tmp_z1);
+/* Zero Forcing Rx function: nr_matrix_inverse()
+ * Compute the matrix inverse and determinant up to 4x4 Matrix
+ *
+ * */
+uint8_t nr_matrix_inverse(int32_t **a44,//Input matrix//conjH_H_elements[0]
+                          int32_t **inv_H_h_H,//Inverse
+                          int32_t *ad_bc,//determin
+                          int32_t size,
+                          unsigned short nb_rb,
+                          int32_t flag,//fixed point or floating flag
+                          int32_t shift0){
+
+  int16_t k,rr[size-1],cc[size-1];
+
+  if(flag) {//fixed point SIMD calc.
+    //Allocate the submatrix elements
+    int32_t **sub_matrix;
+    sub_matrix = (int32_t **)malloc16_clear( (size-1)*(size-1)*sizeof(int32_t *) );
+    for (int rtx=0;rtx<(size-1);rtx++) {//row
+      for (int ctx=0;ctx<(size-1);ctx++) {//column
+        sub_matrix[ctx*(size-1)+rtx] = (int32_t *)malloc16_clear( 12*nb_rb*sizeof(int32_t) );
+      }
+    }
 
-  _mm_empty();
-  _m_empty();
-  return(output_z);
+    //Compute Matrix determinant
+    nr_determin(a44,//
+                ad_bc,//determinant
+                size,//size
+                nb_rb,
+                +1,
+                shift0);
+    //print_shorts("nr_det_",(int16_t*)&ad_bc[0]);
+
+    //Compute Inversion of the H^*H matrix
+    /* For 2x2 MIMO matrix, we compute
+     * *        |(conj_H_00xH_00+conj_H_10xH_10)   (conj_H_00xH_01+conj_H_10xH_11)|
+     * * H_h_H= |                                                                 |
+     * *        |(conj_H_01xH_00+conj_H_11xH_10)   (conj_H_01xH_01+conj_H_11xH_11)|
+     * *
+     * *inv(H_h_H) =(1/det)*[d  -b
+     * *                     -c  a]
+     * **************************************************************************/
+    for (int rtx=0;rtx<size;rtx++) {//row
+      k=0;
+      for(int rrtx=0;rrtx<size;rrtx++)
+        if(rrtx != rtx) rr[k++] = rrtx;
+      for (int ctx=0;ctx<size;ctx++) {//column
+        k=0;
+        for(int cctx=0;cctx<size;cctx++)
+          if(cctx != ctx) cc[k++] = cctx;
+
+        //fill out the sub matrix corresponds to this element
+        for (int ridx=0;ridx<(size-1);ridx++)
+          for (int cidx=0;cidx<(size-1);cidx++)
+            sub_matrix[cidx*(size-1)+ridx]= (int32_t *)&a44[cc[cidx]*size+rr[ridx]][0];
+
+        nr_determin(sub_matrix,
+                    inv_H_h_H[rtx*size+ctx],//out transpose
+                    size-1,//size
+                    nb_rb,
+                    ((rtx&1)==1?-1:1)*((ctx&1)==1?-1:1),
+                    shift0);
+        //printf("H_h_H(r%d,c%d)=%d+j%d --> inv_H_h_H(%d,%d) = %d+j%d \n",rtx,ctx,((short *)a44[ctx*size+rtx])[0],((short *)a44[ctx*size+rtx])[1],ctx,rtx,((short *)inv_H_h_H[rtx*size+ctx])[0],((short *)inv_H_h_H[rtx*size+ctx])[1]);
+      }
+    }
+    _mm_empty();
+    _m_empty();
+  }
+  else {//floating point calc.
+    //Allocate the submatrix elements
+    double complex sub_matrix_cpx[(size-1)*(size-1)];
+    //Convert the IQ samples (in Q15 format) to float complex
+    double complex a44_cpx[size*size];
+    double complex inv_H_h_H_cpx[size*size];
+    double complex determin_cpx;
+    for (int i=0; i<12*nb_rb; i++) {
+
+      //Convert Q15 to floating point
+      for (int rtx=0;rtx<size;rtx++) {//row
+        for (int ctx=0;ctx<size;ctx++) {//column
+          a44_cpx[ctx*size+rtx]= ((double)((short *)a44[ctx*size+rtx])[(i<<1)])/(1<<(shift0-1)) + I*((double)((short *)a44[ctx*size+rtx])[(i<<1)+1])/(1<<(shift0-1));
+          //if (i<4) printf("a44_cpx(%d,%d)= ((FP %d))%lf+(FP %d)j%lf \n",ctx,rtx,((short *)a44[ctx*size+rtx])[(i<<1)],creal(a44_cpx[ctx*size+rtx]),((short *)a44[ctx*size+rtx])[(i<<1)+1],cimag(a44_cpx[ctx*size+rtx]));
+        }
+      }
+      //Compute Matrix determinant (copy real value only)
+      determin_cpx = nr_determin_cpx(a44_cpx,//
+                                     size,//size
+                                     +1);
+      //if (i<4) printf("order %d nr_det_cpx = %lf+j%lf \n",log2_approx(creal(determin_cpx)),creal(determin_cpx),cimag(determin_cpx));
+
+      //Round and convert to Q15 (Out in the same format as Fixed point).
+      if (creal(determin_cpx)>0) {//determin of the symmetric matrix is real part only
+        ((short*) ad_bc)[i<<1] = (short) ((creal(determin_cpx)*(1<<(shift0)))+0.5);//
+        //((short*) ad_bc)[(i<<1)+1] = (short) ((cimag(determin_cpx)*(1<<(shift0)))+0.5);//
+      } else {
+        ((short*) ad_bc)[i<<1] = (short) ((creal(determin_cpx)*(1<<(shift0)))-0.5);//
+        //((short*) ad_bc)[(i<<1)+1] = (short) ((cimag(determin_cpx)*(1<<(shift0)))-0.5);//
+      }
+      //if (i<4) printf("nr_det_FP= %d+j%d \n",((short*) ad_bc)[i<<1],((short*) ad_bc)[(i<<1)+1]);
+      //Compute Inversion of the H^*H matrix (normalized output divide by determinant)
+      for (int rtx=0;rtx<size;rtx++) {//row
+        k=0;
+        for(int rrtx=0;rrtx<size;rrtx++)
+          if(rrtx != rtx) rr[k++] = rrtx;
+        for (int ctx=0;ctx<size;ctx++) {//column
+          k=0;
+          for(int cctx=0;cctx<size;cctx++)
+            if(cctx != ctx) cc[k++] = cctx;
+
+          //fill out the sub matrix corresponds to this element
+          for (int ridx=0;ridx<(size-1);ridx++)
+            for (int cidx=0;cidx<(size-1);cidx++)
+              sub_matrix_cpx[cidx*(size-1)+ridx]= a44_cpx[cc[cidx]*size+rr[ridx]];
+
+          inv_H_h_H_cpx[rtx*size+ctx] = nr_determin_cpx(sub_matrix_cpx,//
+                                                        size-1,//size
+                                                        ((rtx&1)==1?-1:1)*((ctx&1)==1?-1:1));
+          //if (i==0) printf("H_h_H(r%d,c%d)=%lf+j%lf --> inv_H_h_H(%d,%d) = %lf+j%lf \n",rtx,ctx,creal(a44_cpx[ctx*size+rtx]),cimag(a44_cpx[ctx*size+rtx]),ctx,rtx,creal(inv_H_h_H_cpx[rtx*size+ctx]),cimag(inv_H_h_H_cpx[rtx*size+ctx]));
+
+          if (creal(inv_H_h_H_cpx[rtx*size+ctx])>0)
+            ((short *) inv_H_h_H[rtx*size+ctx])[i<<1] = (short) ((creal(inv_H_h_H_cpx[rtx*size+ctx])*(1<<(shift0-1)))+0.5);//Convert to Q 18
+          else
+            ((short *) inv_H_h_H[rtx*size+ctx])[i<<1] = (short) ((creal(inv_H_h_H_cpx[rtx*size+ctx])*(1<<(shift0-1)))-0.5);//
+
+          if (cimag(inv_H_h_H_cpx[rtx*size+ctx])>0)
+            ((short *) inv_H_h_H[rtx*size+ctx])[(i<<1)+1] = (short) ((cimag(inv_H_h_H_cpx[rtx*size+ctx])*(1<<(shift0-1)))+0.5);//
+          else
+            ((short *) inv_H_h_H[rtx*size+ctx])[(i<<1)+1] = (short) ((cimag(inv_H_h_H_cpx[rtx*size+ctx])*(1<<(shift0-1)))-0.5);//
+
+          //if (i<4) printf("inv_H_h_H_FP(%d,%d)= %d+j%d \n",ctx,rtx, ((short *) inv_H_h_H[rtx*size+ctx])[i<<1],((short *) inv_H_h_H[rtx*size+ctx])[(i<<1)+1]);
+        }
+      }
+    }
+  }
+  return(0);
 }
 
 /* Zero Forcing Rx function: nr_conjch0_mult_ch1()
@@ -2390,451 +2255,121 @@ void nr_conjch0_mult_ch1(int *ch0,
   _mm_empty();
   _m_empty();
 }
-__m128i nr_comp_muli_sum(__m128i input_x,
-                         __m128i input_y,
-                         __m128i input_w,
-                         __m128i input_z,
-                         __m128i det)
-{
-  int16_t nr_conjug2[8]__attribute__((aligned(16))) = {1,-1,1,-1,1,-1,1,-1} ;
-
-  __m128i xy_re_128, xy_im_128, wz_re_128, wz_im_128;
-  __m128i output, tmp_z0, tmp_z1;
-
-  // complex multiplication (x_re + jx_im)*(y_re + jy_im) = (x_re*y_re - x_im*y_im) + j(x_im*y_re + x_re*y_im)
-  // the real part
-  xy_re_128 = _mm_sign_epi16(input_x,*(__m128i*)&nr_conjug2[0]);
-  xy_re_128 = _mm_madd_epi16(xy_re_128,input_y); //Re: (x_re*y_re - x_im*y_im)
-
-  // the imag part
-  xy_im_128 = _mm_shufflelo_epi16(input_x,_MM_SHUFFLE(2,3,0,1));//permutes IQs for the low 64 bits as [I_a0 Q_a1 I_a2 Q_a3]_64bits to [Q_a1 I_a0 Q_a3 I_a2]_64bits
-  xy_im_128 = _mm_shufflehi_epi16(xy_im_128,_MM_SHUFFLE(2,3,0,1));//permutes IQs for the high 64 bits as [I_a0 Q_a1 I_a2 Q_a3]_64bits to [Q_a1 I_a0 Q_a3 I_a2]_64bits
-  xy_im_128 = _mm_madd_epi16(xy_im_128,input_y);//Im: (x_im*y_re + x_re*y_im)
-
-  // complex multiplication (w_re + jw_im)*(z_re + jz_im) = (w_re*z_re - w_im*z_im) + j(w_im*z_re + w_re*z_im)
-  // the real part
-  wz_re_128 = _mm_sign_epi16(input_w,*(__m128i*)&nr_conjug2[0]);
-  wz_re_128 = _mm_madd_epi16(wz_re_128,input_z); //Re: (w_re*z_re - w_im*z_im)
-
-  // the imag part
-  wz_im_128 = _mm_shufflelo_epi16(input_w,_MM_SHUFFLE(2,3,0,1));//permutes IQs for the low 64 bits as [I_a0 Q_a1 I_a2 Q_a3]_64bits to [Q_a1 I_a0 Q_a3 I_a2]_64bits
-  wz_im_128 = _mm_shufflehi_epi16(wz_im_128,_MM_SHUFFLE(2,3,0,1));//permutes IQs for the high 64 bits as [I_a0 Q_a1 I_a2 Q_a3]_64bits to [Q_a1 I_a0 Q_a3 I_a2]_64bits
-  wz_im_128 = _mm_madd_epi16(wz_im_128,input_z);//Im: (w_im*z_re + w_re*z_im)
-
-
-  xy_re_128 = _mm_sub_epi32(xy_re_128, wz_re_128);
-  xy_im_128 = _mm_sub_epi32(xy_im_128, wz_im_128);
-  //print_ints("rx_re:",(int32_t*)&xy_re_128[0]);
-  //print_ints("rx_Img:",(int32_t*)&xy_im_128[0]);
-  //divide by matrix det and convert back to Q15 before packing
-  int sum_det =0;
-  for (int k=0; k<4;k++) {
-    sum_det += ((((int *)&det[0])[k])>>2);
-    //printf("det_%d = %d log2 =%d \n",k,(((int *)&det[0])[k]),log2_approx(((int *)&det[0])[k]));
-    }
-
-  xy_re_128 = _mm_slli_epi32(xy_re_128,5);
-  xy_re_128 = _mm_srai_epi32(xy_re_128,log2_approx(sum_det));
-  xy_re_128 = _mm_slli_epi32(xy_re_128,5);
 
-  xy_im_128 = _mm_slli_epi32(xy_im_128,5);
-  xy_im_128 = _mm_srai_epi32(xy_im_128,log2_approx(sum_det));
-  xy_im_128 = _mm_slli_epi32(xy_im_128,5);
-
-  tmp_z0  = _mm_unpacklo_epi32(xy_re_128,xy_im_128);
-  //print_ints("unpack lo:",&tmp_z0[0]);
-  tmp_z1  = _mm_unpackhi_epi32(xy_re_128,xy_im_128);
-  //print_ints("unpack hi:",&tmp_z1[0]);
-  output = _mm_packs_epi32(tmp_z0,tmp_z1);
-
-  _mm_empty();
-  _m_empty();
-  return(output);
-}
-/* Zero Forcing Rx function: nr_construct_HhH_elements()
+/* Zero Forcing Rx function: up to 4 layers
  *
  *
  * */
-void nr_construct_HhH_elements(int *conjch00_ch00,
-                               int *conjch01_ch01,
-                               int *conjch11_ch11,
-                               int *conjch10_ch10,//
-                               int *conjch20_ch20,
-                               int *conjch21_ch21,
-                               int *conjch30_ch30,
-                               int *conjch31_ch31,
-                               int *conjch00_ch01,//00_01
-                               int *conjch01_ch00,//01_00
-                               int *conjch10_ch11,//10_11
-                               int *conjch11_ch10,//11_10
-                               int *conjch20_ch21,
-                               int *conjch21_ch20,
-                               int *conjch30_ch31,
-                               int *conjch31_ch30,
-                               int32_t *after_mf_00,
-                               int32_t *after_mf_01,
-                               int32_t *after_mf_10,
-                               int32_t *after_mf_11,
-                               unsigned short nb_rb,
-                               unsigned char symbol)
+uint8_t nr_zero_forcing_rx(int **rxdataF_comp,
+                           int **dl_ch_mag,
+                           int **dl_ch_magb,
+                           int **dl_ch_magr,
+                           int **dl_ch_estimates_ext,
+                           unsigned short nb_rb,
+                           unsigned char n_rx,
+                           unsigned char n_tx,//number of layer
+                           unsigned char mod_order,
+                           int shift,
+                           unsigned char symbol,
+                           int length)
 {
-  //This function is used to construct the (H_hermitian * H matrix) matrix elements
-  unsigned short rb;
-  __m128i *conjch00_ch00_128, *conjch01_ch01_128, *conjch11_ch11_128, *conjch10_ch10_128;
-  __m128i *conjch20_ch20_128, *conjch21_ch21_128, *conjch30_ch30_128, *conjch31_ch31_128;
-  __m128i *conjch00_ch01_128, *conjch01_ch00_128, *conjch10_ch11_128, *conjch11_ch10_128;
-  __m128i *conjch20_ch21_128, *conjch21_ch20_128, *conjch30_ch31_128, *conjch31_ch30_128;
-  __m128i *after_mf_00_128, *after_mf_01_128, *after_mf_10_128, *after_mf_11_128;
-
-  conjch00_ch00_128 = (__m128i *)conjch00_ch00;
-  conjch01_ch01_128 = (__m128i *)conjch01_ch01;
-  conjch11_ch11_128 = (__m128i *)conjch11_ch11;
-  conjch10_ch10_128 = (__m128i *)conjch10_ch10;
-
-  conjch20_ch20_128 = (__m128i *)conjch20_ch20;
-  conjch21_ch21_128 = (__m128i *)conjch21_ch21;
-  conjch30_ch30_128 = (__m128i *)conjch30_ch30;
-  conjch31_ch31_128 = (__m128i *)conjch31_ch31;
-
-  conjch00_ch01_128 = (__m128i *)conjch00_ch01;
-  conjch01_ch00_128 = (__m128i *)conjch01_ch00;
-  conjch10_ch11_128 = (__m128i *)conjch10_ch11;
-  conjch11_ch10_128 = (__m128i *)conjch11_ch10;
-
-  conjch20_ch21_128 = (__m128i *)conjch20_ch21;
-  conjch21_ch20_128 = (__m128i *)conjch21_ch20;
-  conjch30_ch31_128 = (__m128i *)conjch30_ch31;
-  conjch31_ch30_128 = (__m128i *)conjch31_ch30;
-
-  after_mf_00_128 = (__m128i *)after_mf_00;
-  after_mf_01_128 = (__m128i *)after_mf_01;
-  after_mf_10_128 = (__m128i *)after_mf_10;
-  after_mf_11_128 = (__m128i *)after_mf_11;
-
-  for (rb=0; rb<3*nb_rb; rb++) {
-
-    after_mf_00_128[0] =_mm_adds_epi16(conjch00_ch00_128[0],conjch10_ch10_128[0]);//00_00 + 10_10
-    if (conjch20_ch20 != NULL) after_mf_00_128[0] =_mm_adds_epi16(after_mf_00_128[0],conjch20_ch20_128[0]);
-    if (conjch30_ch30 != NULL) after_mf_00_128[0] =_mm_adds_epi16(after_mf_00_128[0],conjch30_ch30_128[0]);
-
-    after_mf_11_128[0] =_mm_adds_epi16(conjch01_ch01_128[0], conjch11_ch11_128[0]); //01_01 + 11_11
-    if (conjch21_ch21 != NULL) after_mf_11_128[0] =_mm_adds_epi16(after_mf_11_128[0],conjch21_ch21_128[0]);
-    if (conjch31_ch31 != NULL) after_mf_11_128[0] =_mm_adds_epi16(after_mf_11_128[0],conjch31_ch31_128[0]);
-
-    after_mf_01_128[0] =_mm_adds_epi16(conjch00_ch01_128[0], conjch10_ch11_128[0]);//00_01 + 10_11
-    if (conjch20_ch21 != NULL) after_mf_01_128[0] =_mm_adds_epi16(after_mf_01_128[0],conjch20_ch21_128[0]);
-    if (conjch30_ch31 != NULL) after_mf_01_128[0] =_mm_adds_epi16(after_mf_01_128[0],conjch30_ch31_128[0]);
-
-    after_mf_10_128[0] =_mm_adds_epi16(conjch01_ch00_128[0], conjch11_ch10_128[0]);//01_00 + 11_10
-    if (conjch21_ch20 != NULL) after_mf_10_128[0] =_mm_adds_epi16(after_mf_10_128[0],conjch21_ch20_128[0]);
-    if (conjch31_ch30 != NULL) after_mf_10_128[0] =_mm_adds_epi16(after_mf_10_128[0],conjch31_ch30_128[0]);
-
-#ifdef DEBUG_DLSCH_DEMOD
-    if ((rb<=30))
-    {
-      printf(" \n construct_HhH_elements \n");
-      print_shorts("after_mf_00_128:",(int16_t*)&after_mf_00_128[0]);
-      print_shorts("after_mf_01_128:",(int16_t*)&after_mf_01_128[0]);
-      print_shorts("after_mf_10_128:",(int16_t*)&after_mf_10_128[0]);
-      print_shorts("after_mf_11_128:",(int16_t*)&after_mf_11_128[0]);
+  int *ch0r, *ch0c;
+  int32_t *** conjH_H_elements;
+  uint32_t nb_rb_0 = length/12 + ((length%12)?1:0);
+  int32_t determ_fin[12*nb_rb_0] __attribute__((aligned(32)));
+
+  ///Allocate H^*H matrix elements and sub elements
+  conjH_H_elements        = (int32_t ***)malloc16_clear( n_rx*sizeof(int32_t **) );
+  for (int aarx=0;aarx<n_rx;aarx++) {
+    conjH_H_elements[aarx] = (int32_t **)malloc16_clear( n_tx*n_tx*sizeof(int32_t) );
+    for (int rtx=0;rtx<n_tx;rtx++) {//row
+      for (int ctx=0;ctx<n_tx;ctx++) {//column
+        conjH_H_elements[aarx][ctx*n_tx+rtx] = (int32_t *)malloc16_clear( 12*nb_rb_0*sizeof(int32_t *) );
+      }
     }
-#endif
-    conjch00_ch00_128+=1;
-    conjch10_ch10_128+=1;
-    conjch01_ch01_128+=1;
-    conjch11_ch11_128+=1;
-
-    if (conjch20_ch20 != NULL) conjch20_ch20_128+=1;
-    if (conjch21_ch21 != NULL) conjch21_ch21_128+=1;
-    if (conjch30_ch30 != NULL) conjch30_ch30_128+=1;
-    if (conjch31_ch31 != NULL) conjch31_ch31_128+=1;
-
-    conjch00_ch01_128+=1;
-    conjch01_ch00_128+=1;
-    conjch10_ch11_128+=1;
-    conjch11_ch10_128+=1;
-
-    if (conjch20_ch21 != NULL) conjch20_ch21_128+=1;
-    if (conjch21_ch20 != NULL) conjch21_ch20_128+=1;
-    if (conjch30_ch31 != NULL) conjch30_ch31_128+=1;
-    if (conjch31_ch30 != NULL) conjch31_ch30_128+=1;
-
-    after_mf_00_128 += 1;
-    after_mf_01_128 += 1;
-    after_mf_10_128 += 1;
-    after_mf_11_128 += 1;
   }
-  _mm_empty();
-  _m_empty();
-}
 
-/* Zero Forcing Rx function: nr_zero_forcing_rx_2layers()
- *
- *
- * */
-uint8_t nr_zero_forcing_rx_2layers(int **rxdataF_comp,
-                                   int **dl_ch_mag,
-                                   int **dl_ch_magb,
-                                   int **dl_ch_magr,
-                                   int **dl_ch_estimates_ext,
-                                   unsigned short nb_rb,
-                                   unsigned char n_rx,
-                                   unsigned char mod_order,
-                                   int shift,
-                                   unsigned char symbol,
-                                   int length)
-{
-  int *ch00, *ch01, *ch10, *ch11;
-  int *ch20, *ch30, *ch21, *ch31;
-  uint32_t nb_rb_0 = length/12 + ((length%12)?1:0);
-  /* we need at least alignment to 16 bytes, let's put 32 to be sure
-   * (maybe not necessary but doesn't hurt)
-   */
-  int32_t conjch00_ch01[12*nb_rb] __attribute__((aligned(32)));
-  int32_t conjch01_ch00[12*nb_rb] __attribute__((aligned(32)));
-  int32_t conjch10_ch11[12*nb_rb] __attribute__((aligned(32)));
-  int32_t conjch11_ch10[12*nb_rb] __attribute__((aligned(32)));
-  int32_t conjch00_ch00[12*nb_rb] __attribute__((aligned(32)));
-  int32_t conjch01_ch01[12*nb_rb] __attribute__((aligned(32)));
-  int32_t conjch10_ch10[12*nb_rb] __attribute__((aligned(32)));
-  int32_t conjch11_ch11[12*nb_rb] __attribute__((aligned(32)));
-  int32_t conjch20_ch20[12*nb_rb] __attribute__((aligned(32)));
-  int32_t conjch21_ch21[12*nb_rb] __attribute__((aligned(32)));
-  int32_t conjch30_ch30[12*nb_rb] __attribute__((aligned(32)));
-  int32_t conjch31_ch31[12*nb_rb] __attribute__((aligned(32)));
-  int32_t conjch20_ch21[12*nb_rb] __attribute__((aligned(32)));
-  int32_t conjch30_ch31[12*nb_rb] __attribute__((aligned(32)));
-  int32_t conjch21_ch20[12*nb_rb] __attribute__((aligned(32)));
-  int32_t conjch31_ch30[12*nb_rb] __attribute__((aligned(32)));
-
-  int32_t af_mf_00[12*nb_rb] __attribute__((aligned(32)));
-  int32_t af_mf_01[12*nb_rb] __attribute__((aligned(32)));
-  int32_t af_mf_10[12*nb_rb] __attribute__((aligned(32)));
-  int32_t af_mf_11[12*nb_rb] __attribute__((aligned(32)));
-  int32_t determ_fin[12*nb_rb] __attribute__((aligned(32)));
-
-  switch (n_rx) {
-    case 2://
-      ch00 = (int *)&dl_ch_estimates_ext[0][symbol*nb_rb*12];
-      ch01 = (int *)&dl_ch_estimates_ext[2][symbol*nb_rb*12];
-      ch10 = (int *)&dl_ch_estimates_ext[1][symbol*nb_rb*12];
-      ch11 = (int *)&dl_ch_estimates_ext[3][symbol*nb_rb*12];
-      ch20 = NULL;
-      ch21 = NULL;
-      ch30 = NULL;
-      ch31 = NULL;
-      break;
-
-    case 4://
-      ch00 = (int *)&dl_ch_estimates_ext[0][symbol*nb_rb*12];
-      ch01 = (int *)&dl_ch_estimates_ext[4][symbol*nb_rb*12];
-      ch10 = (int *)&dl_ch_estimates_ext[1][symbol*nb_rb*12];
-      ch11 = (int *)&dl_ch_estimates_ext[5][symbol*nb_rb*12];
-      ch20 = (int *)&dl_ch_estimates_ext[2][symbol*nb_rb*12];
-      ch21 = (int *)&dl_ch_estimates_ext[6][symbol*nb_rb*12];
-      ch30 = (int *)&dl_ch_estimates_ext[3][symbol*nb_rb*12];
-      ch31 = (int *)&dl_ch_estimates_ext[7][symbol*nb_rb*12];
-      break;
-
-    default:
-      return -1;
-      break;
+  //Compute H^*H matrix elements and sub elements:(1/2^log2_maxh)*conjH_H_elements
+  for (int rtx=0;rtx<n_tx;rtx++) {//row
+    for (int ctx=0;ctx<n_tx;ctx++) {//column
+      for (int aarx=0;aarx<n_rx;aarx++)  {
+        ch0r = (int *)&dl_ch_estimates_ext[rtx*n_rx+aarx][symbol*nb_rb*12];//[]//conjch00,01,02,03
+        ch0c = (int *)&dl_ch_estimates_ext[ctx*n_rx+aarx][symbol*nb_rb*12];//[aatx*n_rx+aarx]//ch00: 01,02,03
+        nr_conjch0_mult_ch1(ch0r,
+                            ch0c,
+                            conjH_H_elements[aarx][ctx*n_tx+rtx],
+                            nb_rb_0,
+                            shift);
+        if (aarx !=0) nr_a_sum_b((__m128i *)conjH_H_elements[0][ctx*n_tx+rtx],
+                                 (__m128i *)conjH_H_elements[aarx][ctx*n_tx+rtx],
+                                 nb_rb_0);
+      }
+    }
   }
 
-  /* 1- Compute the rx channel matrix after compensation: (1/2^log2_max)x(H_herm x H)
-   * for n_rx = 2
-   * |conj_H_00       conj_H_10|    | H_00         H_01|   |(conj_H_00xH_00+conj_H_10xH_10)   (conj_H_00xH_01+conj_H_10xH_11)|
-   * |                         |  x |                  | = |                                                                 |
-   * |conj_H_01       conj_H_11|    | H_10         H_11|   |(conj_H_01xH_00+conj_H_11xH_10)   (conj_H_01xH_01+conj_H_11xH_11)|
-   *
-   */
-
-  if (n_rx>=2){
-    // (1/2^log2_maxh)*conj_H_00xH_00: (1/(64*2))conjH_00*H_00*2^15
-    nr_conjch0_mult_ch1(ch00,
-                        ch00,
-                        conjch00_ch00,
-                        nb_rb_0,
-                        shift);
-    // (1/2^log2_maxh)*conj_H_10xH_10: (1/(64*2))conjH_10*H_10*2^15
-    nr_conjch0_mult_ch1(ch10,
-                        ch10,
-                        conjch10_ch10,
-                        nb_rb_0,
-                        shift);
-    // conj_H_00xH_01
-    nr_conjch0_mult_ch1(ch00,
-                        ch01,
-                        conjch00_ch01,
-                        nb_rb_0,
-                        shift); // this shift is equal to the channel level log2_maxh
-    // conj_H_10xH_11
-    nr_conjch0_mult_ch1(ch10,
-                        ch11,
-                        conjch10_ch11,
-                        nb_rb_0,
-                        shift);
-    // conj_H_01xH_01
-    nr_conjch0_mult_ch1(ch01,
-                        ch01,
-                        conjch01_ch01,
-                        nb_rb_0,
-                        shift);
-    // conj_H_11xH_11
-    nr_conjch0_mult_ch1(ch11,
-                        ch11,
-                        conjch11_ch11,
-                        nb_rb_0,
-                        shift);
-    // conj_H_01xH_00
-    nr_conjch0_mult_ch1(ch01,
-                        ch00,
-                        conjch01_ch00,
-                        nb_rb_0,
-                        shift);
-    // conj_H_11xH_10
-    nr_conjch0_mult_ch1(ch11,
-                        ch10,
-                        conjch11_ch10,
-                        nb_rb_0,
-                        shift);
-  }
-  if (n_rx==4){
-    // (1/2^log2_maxh)*conj_H_20xH_20: (1/(64*2*16))conjH_20*H_20*2^15
-    nr_conjch0_mult_ch1(ch20,
-                        ch20,
-                        conjch20_ch20,
-                        nb_rb_0,
-                        shift);
-
-    // (1/2^log2_maxh)*conj_H_30xH_30: (1/(64*2*4))conjH_30*H_30*2^15
-    nr_conjch0_mult_ch1(ch30,
-                        ch30,
-                        conjch30_ch30,
-                        nb_rb_0,
-                        shift);
-
-    // (1/2^log2_maxh)*conj_H_20xH_20: (1/(64*2))conjH_20*H_20*2^15
-    nr_conjch0_mult_ch1(ch20,
-                        ch21,
-                        conjch20_ch21,
-                        nb_rb_0,
-                        shift);
-
-    nr_conjch0_mult_ch1(ch30,
-                        ch31,
-                        conjch30_ch31,
-                        nb_rb_0,
-                        shift);
-
-    nr_conjch0_mult_ch1(ch21,
-                        ch21,
-                        conjch21_ch21,
-                        nb_rb_0,
-                        shift);
-
-    nr_conjch0_mult_ch1(ch31,
-                        ch31,
-                        conjch31_ch31,
-                        nb_rb_0,
-                        shift);
-
-    // (1/2^log2_maxh)*conj_H_20xH_20: (1/(64*2))conjH_20*H_20*2^15
-    nr_conjch0_mult_ch1(ch21,
-                        ch20,
-                        conjch21_ch20,
-                        nb_rb_0,
-                        shift);
-
-    nr_conjch0_mult_ch1(ch31,
-                        ch30,
-                        conjch31_ch30,
-                        nb_rb_0,
-                        shift);
-
-    nr_construct_HhH_elements(conjch00_ch00,
-                              conjch01_ch01,
-                              conjch11_ch11,
-                              conjch10_ch10,//
-                              conjch20_ch20,
-                              conjch21_ch21,
-                              conjch30_ch30,
-                              conjch31_ch31,
-                              conjch00_ch01,
-                              conjch01_ch00,
-                              conjch10_ch11,
-                              conjch11_ch10,//
-                              conjch20_ch21,
-                              conjch21_ch20,
-                              conjch30_ch31,
-                              conjch31_ch30,
-                              af_mf_00,
-                              af_mf_01,
-                              af_mf_10,
-                              af_mf_11,
-                              nb_rb_0,
-                              symbol);
-  }
-  if (n_rx==2){
-    nr_construct_HhH_elements(conjch00_ch00,
-                              conjch01_ch01,
-                              conjch11_ch11,
-                              conjch10_ch10,//
-                              NULL,
-                              NULL,
-                              NULL,
-                              NULL,
-                              conjch00_ch01,
-                              conjch01_ch00,
-                              conjch10_ch11,
-                              conjch11_ch10,//
-                              NULL,
-                              NULL,
-                              NULL,
-                              NULL,
-                              af_mf_00,
-                              af_mf_01,
-                              af_mf_10,
-                              af_mf_11,
-                              nb_rb_0,
-                              symbol);
+  //Compute the inverse and determinant of the H^*H matrix
+  //Allocate the inverse matrix
+  int32_t ** inv_H_h_H;
+  inv_H_h_H = (int32_t **)malloc16_clear( n_tx*n_tx*sizeof(int32_t *) );
+  for (int rtx=0;rtx<n_tx;rtx++) {//row
+    for (int ctx=0;ctx<n_tx;ctx++) {//column
+      inv_H_h_H[ctx*n_tx+rtx] = (int32_t *)malloc16_clear( 12*nb_rb_0*sizeof(int32_t) );
+    }
   }
-  //det_HhH = ad -bc
-  nr_det_HhH(af_mf_00,//a
-             af_mf_01,//b
-             af_mf_10,//c
-             af_mf_11,//d
-             determ_fin,
-             nb_rb_0,
-             symbol,
-             shift);
-  /* 2- Compute the channel matrix inversion **********************************
-   *
-     *    |(conj_H_00xH_00+conj_H_10xH_10)   (conj_H_00xH_01+conj_H_10xH_11)|
-     * A= |                                                                 |
-     *    |(conj_H_01xH_00+conj_H_11xH_10)   (conj_H_01xH_01+conj_H_11xH_11)|
-     *
-     *
-     *
-     *inv(A) =(1/det)*[d  -b
-     *                 -c  a]
-     *
-     *
-     **************************************************************************/
-  __m128i *rxdataF_comp128_0,*rxdataF_comp128_1,*dl_ch_mag128_0=NULL,*dl_ch_mag128b_0=NULL,*dl_ch_mag128r_0=NULL,*determ_fin_128;//*dl_ch_mag128_1,*dl_ch_mag128b_1,*dl_ch_mag128r_1
-  __m128i mmtmpD0,mmtmpD1,mmtmpD2,mmtmpD3;
-  __m128i *after_mf_a_128,*after_mf_b_128, *after_mf_c_128, *after_mf_d_128;
-  __m128i QAM_amp128={0},QAM_amp128b={0},QAM_amp128r={0};
-
-  determ_fin_128      = (__m128i *)&determ_fin[0];
+  int fp_flag = 1;//0: float point calc 1: Fixed point calc
+  nr_matrix_inverse(conjH_H_elements[0],//Input matrix
+                    inv_H_h_H,//Inverse
+                    determ_fin,//determin
+                    n_tx,//size
+                    nb_rb_0,
+                    fp_flag,//fixed point flag
+                    shift-(fp_flag==1?2:0));//the out put is Q15
+
+  // multiply Matrix inversion pf H_h_H by the rx signal vector
+  int32_t outtemp[12*nb_rb_0] __attribute__((aligned(32)));
+  int32_t **rxdataF_zforcing;
+  //Allocate rxdataF for zforcing out
+  rxdataF_zforcing        = (int32_t **)malloc16_clear( n_tx*sizeof(int32_t *) );
+   for (int rtx=0;rtx<n_tx;rtx++) {//row
+     rxdataF_zforcing[rtx] = (int32_t *)malloc16_clear( 12*nb_rb_0*sizeof(int32_t) );
+   }
+
+  for (int rtx=0;rtx<n_tx;rtx++) {//Output Layers row
+    // loop over Layers rtx=0,...,N_Layers-1
+      for (int ctx=0;ctx<n_tx;ctx++) {//column multi
+        //printf("Computing r_%d c_%d\n",rtx,ctx);
+        //print_shorts(" H_h_H=",(int16_t*)&conjH_H_elements[ctx*n_tx+rtx][0][0]);
+        //print_shorts(" Inv_H_h_H=",(int16_t*)&inv_H_h_H[ctx*n_tx+rtx][0]);
+        nr_a_mult_b(inv_H_h_H[ctx*n_tx+rtx],
+                    (int *)&rxdataF_comp[ctx*n_rx][symbol*nb_rb*12],
+                    outtemp,
+                    nb_rb_0,
+                    shift-(fp_flag==1?2:0));
+        nr_a_sum_b((__m128i *)rxdataF_zforcing[rtx],
+                   (__m128i *)outtemp,
+                   nb_rb_0);//a =a + b
+        }
+#ifdef DEBUG_DLSCH_DEMOD
+    printf("Computing layer_%d \n",rtx);;
+    print_shorts(" Rx signal:=",(int16_t*)&rxdataF_zforcing[rtx][0]);
+    print_shorts(" Rx signal:=",(int16_t*)&rxdataF_zforcing[rtx][4]);
+    print_shorts(" Rx signal:=",(int16_t*)&rxdataF_zforcing[rtx][8]);
+#endif
+    }
 
-  rxdataF_comp128_0   = (__m128i *)&rxdataF_comp[0][symbol*nb_rb*12];//aatx=0 @ aarx =0
-  rxdataF_comp128_1   = (__m128i *)&rxdataF_comp[n_rx][symbol*nb_rb*12];//aatx=1 @ aarx =0
+  //Copy zero_forcing out to output array
+  for (int rtx=0;rtx<n_tx;rtx++)
+    nr_element_sign(rxdataF_zforcing[rtx],
+                    (int *)&rxdataF_comp[rtx*n_rx][symbol*nb_rb*12],
+                    nb_rb_0,
+                    +1);
 
-  after_mf_a_128 = (__m128i *)af_mf_00;
-  after_mf_b_128 = (__m128i *)af_mf_01;
-  after_mf_c_128 = (__m128i *)af_mf_10;
-  after_mf_d_128 = (__m128i *)af_mf_11;
+  //Update LLR thresholds with the Matrix determinant
+  __m128i *dl_ch_mag128_0=NULL,*dl_ch_mag128b_0=NULL,*dl_ch_mag128r_0=NULL,*determ_fin_128;
+  __m128i mmtmpD2,mmtmpD3;
+  __m128i QAM_amp128={0},QAM_amp128b={0},QAM_amp128r={0};
+  short nr_realpart[8]__attribute__((aligned(16))) = {1,0,1,0,1,0,1,0};
+  determ_fin_128      = (__m128i *)&determ_fin[0];
 
   if (mod_order>2) {
     if (mod_order == 4) {
@@ -2849,88 +2384,41 @@ uint8_t nr_zero_forcing_rx_2layers(int **rxdataF_comp,
       QAM_amp128 = _mm_set1_epi16(QAM256_n1); //8/sqrt{170}
       QAM_amp128b = _mm_set1_epi16(QAM256_n2);//4/sqrt{170}
       QAM_amp128r = _mm_set1_epi16(QAM256_n3);//2/sqrt{170}
-      }
+    }
     dl_ch_mag128_0      = (__m128i *)&dl_ch_mag[0][symbol*nb_rb*12];
     dl_ch_mag128b_0     = (__m128i *)&dl_ch_magb[0][symbol*nb_rb*12];
     dl_ch_mag128r_0     = (__m128i *)&dl_ch_magr[0][symbol*nb_rb*12];
-  }
-
-  for (int rb=0; rb<3*nb_rb_0; rb++) {
-    if (mod_order>2) {
-      int sum_det =0;
-      for (int k=0; k<4;k++) {
-        sum_det += ((((int *)&determ_fin_128[0])[k])>>2);
-        //printf("det_%d = %d\n",k,sum_det);
-        }
-
-      mmtmpD2 = _mm_slli_epi32(determ_fin_128[0],5);
-      mmtmpD2 = _mm_srai_epi32(mmtmpD2,log2_approx(sum_det));
-      mmtmpD2 = _mm_slli_epi32(mmtmpD2,5);
-
-      mmtmpD3 = _mm_unpacklo_epi32(mmtmpD2,mmtmpD2);
 
-      mmtmpD2 = _mm_unpackhi_epi32(mmtmpD2,mmtmpD2);
+    for (int rb=0; rb<3*nb_rb_0; rb++) {
+      //for symmetric H_h_H matrix, the determinant is only real values
+        mmtmpD2 = _mm_sign_epi16(determ_fin_128[0],*(__m128i*)&nr_realpart[0]);//set imag part to 0
+        mmtmpD3 = _mm_shufflelo_epi16(mmtmpD2,_MM_SHUFFLE(2,3,0,1));
+        mmtmpD3 = _mm_shufflehi_epi16(mmtmpD3,_MM_SHUFFLE(2,3,0,1));
+        mmtmpD2 = _mm_add_epi16(mmtmpD2,mmtmpD3);
 
-      mmtmpD2 = _mm_packs_epi32(mmtmpD3,mmtmpD2);
+        dl_ch_mag128_0[0] = mmtmpD2;
+        dl_ch_mag128b_0[0] = mmtmpD2;
+        dl_ch_mag128r_0[0] = mmtmpD2;
 
-      dl_ch_mag128_0[0] = mmtmpD2;
-      dl_ch_mag128b_0[0] = mmtmpD2;
-      dl_ch_mag128r_0[0] = mmtmpD2;
+        dl_ch_mag128_0[0] = _mm_mulhi_epi16(dl_ch_mag128_0[0],QAM_amp128);
+        dl_ch_mag128_0[0] = _mm_slli_epi16(dl_ch_mag128_0[0],1);
 
-      dl_ch_mag128_0[0] = _mm_mulhi_epi16(dl_ch_mag128_0[0],QAM_amp128);
-      dl_ch_mag128_0[0] = _mm_slli_epi16(dl_ch_mag128_0[0],1);
+        dl_ch_mag128b_0[0] = _mm_mulhi_epi16(dl_ch_mag128b_0[0],QAM_amp128b);
+        dl_ch_mag128b_0[0] = _mm_slli_epi16(dl_ch_mag128b_0[0],1);
+        dl_ch_mag128r_0[0] = _mm_mulhi_epi16(dl_ch_mag128r_0[0],QAM_amp128r);
+        dl_ch_mag128r_0[0] = _mm_slli_epi16(dl_ch_mag128r_0[0],1);
 
-      dl_ch_mag128b_0[0] = _mm_mulhi_epi16(dl_ch_mag128b_0[0],QAM_amp128b);
-      dl_ch_mag128b_0[0] = _mm_slli_epi16(dl_ch_mag128b_0[0],1);
 
-      dl_ch_mag128r_0[0] = _mm_mulhi_epi16(dl_ch_mag128r_0[0],QAM_amp128r);
-      dl_ch_mag128r_0[0] = _mm_slli_epi16(dl_ch_mag128r_0[0],1);
-
-      //print_shorts("mag layer 1:",(int16_t*)&dl_ch_mag128_0[0]);
-      //print_shorts("mag layer 2:",(int16_t*)&dl_ch_mag128_1[0]);
-      //print_shorts("magb layer 1:",(int16_t*)&dl_ch_mag128b_0[0]);
-      //print_shorts("magb layer 2:",(int16_t*)&dl_ch_mag128b_1[0]);
-      //print_shorts("magr layer 1:",(int16_t*)&dl_ch_mag128r_0[0]);
-      //print_shorts("magr layer 2:",(int16_t*)&dl_ch_mag128r_1[0]);
+      determ_fin_128 += 1;
+      dl_ch_mag128_0 += 1;
+      dl_ch_mag128b_0 += 1;
+      dl_ch_mag128r_0 += 1;
     }
-    // multiply by channel Inv
-    //rxdataF_zf128_0 = rxdataF_comp128_0*d - b*rxdataF_comp128_1
-    //rxdataF_zf128_1 = rxdataF_comp128_1*a - c*rxdataF_comp128_0
-    //printf("layer_1 \n");
-    mmtmpD0 = nr_comp_muli_sum(rxdataF_comp128_0[0],
-                               after_mf_d_128[0],
-                               rxdataF_comp128_1[0],
-                               after_mf_b_128[0],
-                               determ_fin_128[0]);
-
-    //printf("layer_2 \n");
-    mmtmpD1 = nr_comp_muli_sum(rxdataF_comp128_1[0],
-                               after_mf_a_128[0],
-                               rxdataF_comp128_0[0],
-                               after_mf_c_128[0],
-                               determ_fin_128[0]);
-
-    rxdataF_comp128_0[0] = mmtmpD0;
-    rxdataF_comp128_1[0] = mmtmpD1;
-#ifdef DEBUG_DLSCH_DEMOD
-    printf("\n Rx signal after ZF l%d rb%d\n",symbol,rb);
-    print_shorts(" Rx layer 1:",(int16_t*)&rxdataF_comp128_0[0]);
-    print_shorts(" Rx layer 2:",(int16_t*)&rxdataF_comp128_1[0]);
-#endif
-    determ_fin_128 += 1;
-    dl_ch_mag128_0 += 1;
-    dl_ch_mag128b_0 += 1;
-    dl_ch_mag128r_0 += 1;
-    rxdataF_comp128_0 += 1;
-    rxdataF_comp128_1 += 1;
-    after_mf_a_128 += 1;
-    after_mf_b_128 += 1;
-    after_mf_c_128 += 1;
-    after_mf_d_128 += 1;
   }
+
   _mm_empty();
   _m_empty();
-   return(0);
+  return(0);
 }
 
 static void nr_dlsch_layer_demapping(int16_t **llr_cw,
@@ -2991,26 +2479,12 @@ static int nr_dlsch_llr(NR_UE_PDSCH **pdsch_vars,
                         uint8_t nr_slot_rx,
                         uint8_t beamforming_mode)
 {
-
-  int16_t  *pllr_symbol_cw0;
-  int16_t  *pllr_symbol_cw1;
-  int16_t  *pllr_symbol_layer0;
-  int16_t  *pllr_symbol_layer1;
   uint32_t llr_offset_symbol;
   
-  if (first_symbol_flag==1) pdsch_vars[gNB_id]->llr_offset[symbol-1] = 0;
+  if (first_symbol_flag==1)
+    pdsch_vars[gNB_id]->llr_offset[symbol-1] = 0;
   llr_offset_symbol = pdsch_vars[gNB_id]->llr_offset[symbol-1];
-  //pllr_symbol_cw0_deint  = (int8_t*)pdsch_vars[gNB_id]->llr[0];
-  //pllr_symbol_cw1_deint  = (int8_t*)pdsch_vars[gNB_id]->llr[1];
-  pllr_symbol_layer0 = pdsch_vars[gNB_id]->layer_llr[0];
-  pllr_symbol_layer1 = pdsch_vars[gNB_id]->layer_llr[1];
-  pllr_symbol_layer0 += llr_offset_symbol;
-  pllr_symbol_layer1 += llr_offset_symbol;
-  pllr_symbol_cw0 = pdsch_vars[gNB_id]->llr[0];
-  pllr_symbol_cw1 = pdsch_vars[gNB_id]->llr[1];
-  pllr_symbol_cw0 += llr_offset_symbol;
-  pllr_symbol_cw1 += llr_offset_symbol;
-    
+
   pdsch_vars[gNB_id]->llr_offset[symbol] = len*dlsch0_harq->Qm + llr_offset_symbol;
  
   /*LOG_I(PHY,"compute LLRs [symbol %d] NbRB %d Qm %d LLRs-Length %d LLR-Offset %d @LLR Buff %x @LLR Buff(symb) %x\n",
@@ -3020,14 +2494,6 @@ static int nr_dlsch_llr(NR_UE_PDSCH **pdsch_vars,
     pdsch_vars[gNB_id]->llr_offset[symbol],
     (int16_t*)pdsch_vars[gNB_id]->llr[0],
     pllr_symbol_cw0);*/
-             
-  /*printf("compute LLRs [symbol %d] NbRB %d Qm %d LLRs-Length %d LLR-Offset %d @LLR Buff %p @LLR Buff(symb) %p\n",
-    symbol,
-    nb_rb,dlsch0_harq->Qm,
-    pdsch_vars[gNB_id]->llr_length[symbol],
-    pdsch_vars[gNB_id]->llr_offset[symbol],
-    pdsch_vars[gNB_id]->llr[0],
-    pllr_symbol_cw0);*/
 
   switch (dlsch0_harq->Qm) {
   case 2 :
@@ -3043,27 +2509,14 @@ static int nr_dlsch_llr(NR_UE_PDSCH **pdsch_vars,
                             nb_rb,
                             beamforming_mode);
         break;
-      case rx_IC_single_stream ://not implemented yet
-        /*nr_dlsch_qpsk_qpsk_llr(frame_parms,
-                               pdsch_vars[gNB_id]->rxdataF_comp0,
-                               rxdataF_comp_ptr,
-                               pdsch_vars[gNB_id]->dl_ch_rho2_ext,
-                               pdsch_vars[gNB_id]->layer_llr[0],
-                               symbol,len,first_symbol_flag,nb_rb,
-                               adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,2,nr_slot_rx,symbol),
-                               pdsch_vars[gNB_id]->llr128);*/
+      case rx_IC_single_stream ://From LTE Code!!
+        //not implemented yet
         break;
-      case rx_IC_dual_stream ://not implemented yet
-        /*nr_dlsch_qpsk_qpsk_llr(frame_parms,
-                               rxdataF_comp_ptr,
-                               pdsch_vars[gNB_id]->rxdataF_comp0,
-                               pdsch_vars[gNB_id]->dl_ch_rho_ext[harq_pid][round],
-                               pdsch_vars[gNB_id]->layer_llr[1],
-                               symbol,len,first_symbol_flag,nb_rb,
-                               adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,2,nr_slot_rx,symbol),
-                               pdsch_vars[gNB_id]->llr128_2ndstream);*/
+      case rx_IC_dual_stream :
+        //not implemented yet
         break;
-      case rx_SIC_dual_stream ://not implemented yet
+      case rx_SIC_dual_stream :
+        //not implemented yet
         break;
     }
     break;
diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c b/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c
index ac918b4f3e85e0451f235ac29e729917faebd892..b806e4c381cba26624b278a3d1b45fefabae7dba 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c
@@ -146,23 +146,26 @@ 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);
+                     &result);
 
     temp_ptr=temp_ptr->next_ssb;
   }
@@ -349,15 +352,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){
@@ -548,6 +553,7 @@ int nr_initial_sync(UE_nr_rxtx_proc_t *proc,
                                       0,
                                       pdcch_vars->slot,
                                       l,
+                                      fp->Nid_cell,
                                       fp->first_carrier_offset+(pdcch_vars->pdcch_config[n_ss].BWPStart + coreset_start_rb)*12,
                                       coreset_nb_rb);
 
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 db21323cdd4aa7c49c5b2494d3dc4f50272c4ecb..6897cbd69c03ab087dfd6c2d0c57ccefe944b6a1 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h
@@ -733,7 +733,7 @@ unsigned short nr_dlsch_extract_rbs_single(int **rxdataF,
     @param n_dmrs_cdm_groups
     @param frame_parms Pointer to frame descriptor
 */
-unsigned short nr_dlsch_extract_rbs_multiple(int **rxdataF,
+void nr_dlsch_extract_rbs(int **rxdataF,
                                         int **dl_ch_estimates,
                                         int **rxdataF_ext,
                                         int **dl_ch_estimates_ext,
@@ -824,28 +824,12 @@ void nr_dlsch_channel_compensation_core(int **rxdataF_ext,
                                      int start_point);
 
 void nr_dlsch_deinterleaving(uint8_t symbol,
-							uint8_t start_symbol,
-							uint16_t L,
-							uint16_t *llr,
-							uint16_t *llr_deint,
-							uint16_t nb_rb_pdsch);
-
-void dlsch_dual_stream_correlation(NR_DL_FRAME_PARMS *frame_parms,
-                                   unsigned char symbol,
-                                   unsigned short nb_rb,
-                                   int **dl_ch_estimates_ext,
-                                   int **dl_ch_estimates_ext_i,
-                                   int **dl_ch_rho_ext,
-                                   unsigned char output_shift);
-
-void dlsch_dual_stream_correlationTM34(NR_DL_FRAME_PARMS *frame_parms,
-                                   unsigned char symbol,
-                                   unsigned short nb_rb,
-                                   int **dl_ch_estimates_ext,
-                                   int **dl_ch_estimates_ext_i,
-                                   int **dl_ch_rho_ext,
-                                   unsigned char output_shift0,
-                                   unsigned char output_shift1);
+                             uint8_t start_symbol,
+                             uint16_t L,
+                             uint16_t *llr,
+                             uint16_t *llr_deint,
+                             uint16_t nb_rb_pdsch);
+
 //This function is used to compute multiplications in Hhermitian * H matrix
 void conjch0_mult_ch1(int *ch0,
                       int *ch1,
@@ -897,19 +881,6 @@ void nr_dlsch_detection_mrc(int **rxdataF_comp,
                             unsigned short nb_rb,
                             int length);
 
-void nr_dlsch_detection_mrc_core(int **rxdataF_comp,
-                              int **rxdataF_comp_i,
-                              int **rho,
-                              int **rho_i,
-                              int **dl_ch_mag,
-                              int **dl_ch_magb,
-                              int **dl_ch_mag_i,
-                              int **dl_ch_magb_i,
-                              unsigned char n_tx,
-                              unsigned char n_rx,
-                              int length,
-                              int start_point);
-
 void det_HhH(int32_t *after_mf_00,
              int32_t *after_mf_01,
              int32_t *after_mf_10,
diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h
index f76119250f5164a8c2859ce0a7bc926fe9fc283a..7b5019edfe8518f64c26d18e5788dd88083726f0 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h
@@ -196,8 +196,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 +259,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/sss_nr.c b/openair1/PHY/NR_UE_TRANSPORT/sss_nr.c
index dc73fe0add1226bfaeff3d433ee7d613d9d601ce..88585e6094f92bb6817c80586c06f677990ac80c 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/sss_nr.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/sss_nr.c
@@ -558,6 +558,9 @@ 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;
   d = (int16_t *)&d_sss[Nid2][Nid1];
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/tools_defs.h b/openair1/PHY/TOOLS/tools_defs.h
index 966e93440e9b017752734da7f4b4cc9398dc5019..86bce9614fd442ef47ad3670901c477c17d21378 100644
--- a/openair1/PHY/TOOLS/tools_defs.h
+++ b/openair1/PHY/TOOLS/tools_defs.h
@@ -181,159 +181,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 +384,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 +441,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_gNB.h b/openair1/PHY/defs_gNB.h
index 6dcce5df0a238ca61ad7f08a565e2a2bac1e9133..7b655c023a9bbd27db6c315528f38eef6c66bf50 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)
@@ -800,6 +798,13 @@ typedef struct PHY_VARS_gNB_s {
   /// PDSCH DMRS sequence
   uint32_t ****nr_gold_pdsch_dmrs;
 
+  /// PDSCH codebook I precoding LUTs
+  /// first dimension: Rank number [0,...,noOfLayers-1[
+  /// second dimension: PMI [0,...,CodeSize-1[
+  /// third dimension: [i_rows*noOfLayers+j_col], i_rows=0,...pdsch_AntennaPorts-1 and j_col=0,...,noOfLayers-1
+  int32_t ***nr_mimo_precoding_matrix;
+  int pmiq_size[NR_MAX_NB_LAYERS];
+
   /// PUSCH DMRS
   uint32_t ****nr_gold_pusch_dmrs;
 
@@ -845,6 +850,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 04080e72150326f7046a971084135750990836c1..ddd84fbc41ce049a1dc3f2db838ba3c890ed88a6 100644
--- a/openair1/PHY/defs_nr_UE.h
+++ b/openair1/PHY/defs_nr_UE.h
@@ -183,7 +183,7 @@ typedef struct {
   //! estimated rssi (dBm)
   short          rx_rssi_dBm[NUMBER_OF_CONNECTED_gNB_MAX];
   //! estimated correlation (wideband linear) between spatial channels (computed in dlsch_demodulation)
-  int            rx_correlation[NUMBER_OF_CONNECTED_gNB_MAX][4][4];
+  int            rx_correlation[NUMBER_OF_CONNECTED_gNB_MAX][NB_ANTENNAS_RX][NR_MAX_NB_LAYERS*NR_MAX_NB_LAYERS];//
   //! estimated correlation (wideband dB) between spatial channels (computed in dlsch_demodulation)
   int            rx_correlation_dB[NUMBER_OF_CONNECTED_gNB_MAX][2];
 
@@ -271,12 +271,6 @@ typedef struct {
   /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx
   /// - second index: ? [0..168*N_RB_DL[
   int32_t **rxdataF_comp0;
-  /// \brief Received frequency-domain signal after extraction and channel compensation for the second stream. For the SIC receiver we need to store the history of this for each harq process and round
-  /// - first index: ? [0..7] (hard coded) accessed via \c harq_pid
-  /// - second index: ? [0..7] (hard coded) accessed via \c round
-  /// - third index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx
-  /// - fourth index: ? [0..168*N_RB_DL[
-  int32_t **rxdataF_comp1[8][8];
   /// \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)[
@@ -289,12 +283,6 @@ typedef struct {
   /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx
   /// - second index: ? [0..168*N_RB_DL[
   int32_t **dl_ch_ptrs_estimates_ext;
-  /// \brief Downlink cross-correlation of MIMO channel estimates (unquantized PMI) extracted in PRBS. For the SIC receiver we need to store the history of this for each harq process and round
-  /// - first index: ? [0..7] (hard coded) accessed via \c harq_pid
-  /// - second index: ? [0..7] (hard coded) accessed via \c round
-  /// - third index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx
-  /// - fourth index: ? [0..168*N_RB_DL[
-  int32_t **dl_ch_rho_ext[8][8];
   /// \brief Downlink beamforming 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)[
@@ -303,10 +291,6 @@ typedef struct {
   /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx
   /// - second index: ? [0..168*N_RB_DL[
   int32_t **dl_bf_ch_estimates_ext;
-  /// \brief Downlink cross-correlation of MIMO channel estimates (unquantized PMI) extracted in PRBS.
-  /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx
-  /// - second index: ? [0..168*N_RB_DL[
-  int32_t **dl_ch_rho2_ext;
   /// \brief Downlink PMIs extracted in PRBS and grouped in subbands.
   /// - first index: ressource block [0..N_RB_DL[
   uint8_t *pmi_ext;
@@ -314,18 +298,10 @@ typedef struct {
   /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx
   /// - second index: ? [0..168*N_RB_DL[
   int32_t **dl_ch_mag0;
-  /// \brief Magnitude of Downlink Channel second layer (16QAM level/First 64QAM level).
-  /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx
-  /// - second index: ? [0..168*N_RB_DL[
-  int32_t **dl_ch_mag1[8][8];
   /// \brief Magnitude of Downlink Channel, first layer (2nd 64QAM level).
   /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx
   /// - second index: ? [0..168*N_RB_DL[
   int32_t **dl_ch_magb0;
-  /// \brief Magnitude of Downlink Channel second layer (2nd 64QAM level).
-  /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx
-  /// - second index: ? [0..168*N_RB_DL[
-  int32_t **dl_ch_magb1[8][8];
   /// \brief Magnitude of Downlink Channel, first layer (256QAM level).
   int32_t **dl_ch_magr0;
   /// \brief Cross-correlation Matrix of the gNB Tx channel signals.
@@ -595,10 +571,6 @@ typedef struct {
   /// - 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: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx
-  /// - second index: ? [0..168*N_RB_DL[
-  int32_t **dl_ch_rho_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;
@@ -817,7 +789,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];
@@ -826,7 +801,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 0a58ff3dc18311ea05047866f5f29f5a3078d54c..7c78d20ae50bf7c73fadb3b1f9eb22efadcabad4 100644
--- a/openair1/PHY/defs_nr_common.h
+++ b/openair1/PHY/defs_nr_common.h
@@ -94,6 +94,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
@@ -322,7 +324,7 @@ struct NR_DL_FRAME_PARMS {
   uint32_t samples_per_frame_wCP;
   /// NR numerology index [0..5] as specified in 38.211 Section 4 (mu). 0=15khZ SCS, 1=30khZ, 2=60kHz, etc
   uint8_t numerology_index;
-  /// Number of Physical transmit antennas in node
+  /// Number of Physical transmit antennas in node (corresponds to nrOfAntennaPorts)
   uint8_t nb_antennas_tx;
   /// Number of Receive antennas in node
   uint8_t nb_antennas_rx;
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/fapi_nr_ue_l1.c b/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c
index 88403e30065b35b68c91d3ed7ddcd59f2a3ae9e0..8a1def31e25578b0f44849211541adc4b82e5afb 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;
 }
@@ -246,6 +318,8 @@ void configure_dlsch(NR_UE_DLSCH_t *dlsch0,
   dlsch0_harq->R = dlsch_config_pdu->targetCodeRate;
   dlsch0_harq->Qm = dlsch_config_pdu->qamModOrder;
   dlsch0_harq->TBS = dlsch_config_pdu->TBS;
+  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
diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c
index c61fb4ea519870465458528fd6bb6d1ec32b528e..35674da2e28d9e467d8c5fde4d917133c44cd1df 100644
--- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c
+++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c
@@ -580,6 +580,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,
@@ -1403,9 +1405,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,
@@ -1413,7 +1417,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);
@@ -1431,7 +1434,8 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,
         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,
@@ -1478,6 +1482,7 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,
                                     gNB_id,
                                     nr_slot_rx,
                                     l,
+                                    pdcch_vars->pdcch_config[n_ss].coreset.pdcch_dmrs_scrambling_id,
                                     fp->first_carrier_offset+(pdcch_vars->pdcch_config[n_ss].BWPStart + coreset_start_rb)*12,
                                     coreset_nb_rb);
 
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/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/dlsim.c b/openair1/SIMULATION/NR_PHY/dlsim.c
index c3ff79ab071ec316797df97d6354ab7c73185f5c..412ab1a6eaec23b245ac8de7fc6f6b23307f5523 100644
--- a/openair1/SIMULATION/NR_PHY/dlsim.c
+++ b/openair1/SIMULATION/NR_PHY/dlsim.c
@@ -207,7 +207,7 @@ int nr_derive_key(int alg_type, uint8_t alg_id,
 
 void config_common(int Mod_idP,
                    int ssb_SubcarrierOffset,
-                   int pdsch_AntennaPorts,
+                   rrc_pdsch_AntennaPorts_t pdsch_AntennaPorts,
                    int pusch_AntennaPorts,
 		   NR_ServingCellConfigCommon_t *scc
 		   );
@@ -239,6 +239,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 
@@ -272,7 +274,7 @@ void nr_dlsim_preprocessor(module_id_t module_id,
 
   /* manually set free CCE to 0 */
   const int target_ss = NR_SearchSpace__searchSpaceType_PR_ue_Specific;
-  sched_ctrl->search_space = get_searchspace(scc, sched_ctrl->active_bwp ? sched_ctrl->active_bwp->bwp_Dedicated : NULL, target_ss);
+  sched_ctrl->search_space = get_searchspace(NULL, scc, sched_ctrl->active_bwp ? sched_ctrl->active_bwp->bwp_Dedicated : NULL, target_ss);
   uint8_t nr_of_candidates;
   find_aggregation_candidates(&sched_ctrl->aggregation_level,
                               &nr_of_candidates,
@@ -282,7 +284,8 @@ void nr_dlsim_preprocessor(module_id_t module_id,
 
   NR_pdsch_semi_static_t *ps = &sched_ctrl->pdsch_semi_static;
 
-  nr_set_pdsch_semi_static(scc,
+  nr_set_pdsch_semi_static(NULL,
+                           scc,
                            UE_info->CellGroup[0],
                            sched_ctrl->active_bwp,
                            NULL,
@@ -537,8 +540,8 @@ int main(int argc, char **argv)
     case 'x':
       g_nrOfLayers=atoi(optarg);
 
-      if ((g_nrOfLayers!=1) &&
-          (g_nrOfLayers!=2)) {
+      if ((g_nrOfLayers==0) ||
+          (g_nrOfLayers>4)) {
         printf("Unsupported nr Of Layers %d\n",g_nrOfLayers);
         exit(-1);
       }
@@ -784,12 +787,27 @@ int main(int argc, char **argv)
   fix_scc(scc,ssb_bitmap);
   prepare_scd(scd);
 
+  rrc_pdsch_AntennaPorts_t pdsch_AntennaPorts;
+  pdsch_AntennaPorts.N1 = n_tx>1 ? n_tx>>1 : 1;
+  pdsch_AntennaPorts.N2 = 1;
+  pdsch_AntennaPorts.XP = n_tx>1 ? 2 : 1;
+  gNB->ap_N1 = pdsch_AntennaPorts.N1;
+  gNB->ap_N2 = pdsch_AntennaPorts.N2;
+  gNB->ap_XP = pdsch_AntennaPorts.XP;
+
   NR_UE_NR_Capability_t* UE_Capability_nr = CALLOC(1,sizeof(NR_UE_NR_Capability_t));
   prepare_sim_uecap(UE_Capability_nr,scc,mu,
                     N_RB_DL,g_mcsTableIdx);
 
   // TODO do a UECAP for phy-sim
-  fill_default_secondaryCellGroup(scc, scd, secondaryCellGroup, UE_Capability_nr, 0, 1, n_tx, 6, 0, 0, 0);
+  const gNB_RrcConfigurationReq conf = {
+    .pdsch_AntennaPorts = pdsch_AntennaPorts,
+    .minRXTXTIME = 6,
+    .do_CSIRS = 0,
+    .do_SRS = 0,
+    .force_256qam_off = false
+  };
+  fill_default_secondaryCellGroup(scc, scd, secondaryCellGroup, UE_Capability_nr, 0, 1, &conf, 0);
 
   /* RRC parameter validation for secondaryCellGroup */
   fix_scd(scd);
@@ -807,10 +825,11 @@ int main(int argc, char **argv)
 
   AssertFatal((gNB->if_inst         = NR_IF_Module_init(0))!=NULL,"Cannot register interface");
   gNB->if_inst->NR_PHY_config_req      = nr_phy_config_request;
+
   // common configuration
-  rrc_mac_config_req_gNB(0,0, n_tx, n_tx, 0, 6, scc, NULL, 0, 0, NULL);
+  rrc_mac_config_req_gNB(0,0, pdsch_AntennaPorts, n_tx, 0, 6, scc, NULL, NULL, 0, 0, NULL);
   // UE dedicated configuration
-  rrc_mac_config_req_gNB(0,0, n_tx, n_tx, 0, 6, scc, NULL, 1, secondaryCellGroup->spCellConfig->reconfigurationWithSync->newUE_Identity,secondaryCellGroup);
+  rrc_mac_config_req_gNB(0,0, pdsch_AntennaPorts, n_tx, 0, 6, scc, NULL, NULL, 1, secondaryCellGroup->spCellConfig->reconfigurationWithSync->newUE_Identity,secondaryCellGroup);
   // reset preprocessor to the one of DLSIM after it has been set during
   // rrc_mac_config_req_gNB
   gNB_mac->pre_processor_dl = nr_dlsim_preprocessor;
@@ -942,10 +961,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);
@@ -1202,10 +1221,10 @@ int main(int argc, char **argv)
                              frame_length_complex_samples,
                              0);
 
-        double H_awgn_mimo[4][4] ={{1.0, 0.5, 0.25, 0.125},//rx 0
-                                   {0.5, 1.0, 0.5, 0.25},  //rx 1
-                                   {0.25, 0.5, 1.0, 0.5},  //rx 2
-                                   {0.125, 0.25, 0.5, 1.0}};//rx 3
+        double H_awgn_mimo[4][4] ={{1.0, 0.2, 0.1, 0.05}, //rx 0
+                                   {0.2, 1.0, 0.2, 0.1}, //rx 1
+                                   {0.1, 0.2, 1.0, 0.2}, //rx 2
+                                   {0.05, 0.1, 0.2, 1.0}};//rx 3
 
         for (i=frame_parms->get_samples_slot_timestamp(slot,frame_parms,0); 
              i<frame_parms->get_samples_slot_timestamp(slot+1,frame_parms,0);
@@ -1260,7 +1279,7 @@ int main(int argc, char **argv)
       TBS                  = UE_harq_process->TBS;//rel15->TBSize[0];
       uint16_t length_dmrs = get_num_dmrs(rel15->dlDmrsSymbPos);
       uint16_t nb_rb       = rel15->rbSize;
-      uint8_t  nb_re_dmrs  = rel15->dmrsConfigType == NFAPI_NR_DMRS_TYPE1 ? 6 : 4;
+      uint8_t  nb_re_dmrs  = rel15->dmrsConfigType == NFAPI_NR_DMRS_TYPE1 ? 6*UE_harq_process->n_dmrs_cdm_groups : 4*UE_harq_process->n_dmrs_cdm_groups;
       uint8_t  mod_order   = rel15->qamModOrder[0];
       uint8_t  nb_symb_sch = rel15->NrOfSymbols;
 
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/ulsim.c b/openair1/SIMULATION/NR_PHY/ulsim.c
index 7cd745fed58f81291e8830c894dff9e91c155e77..17734d9889421327d02804e1b6a9286ccc53ac21 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);  }
@@ -731,7 +733,14 @@ int main(int argc, char **argv)
   prepare_scd(scd);
 
   // TODO do a UECAP for phy-sim
-  fill_default_secondaryCellGroup(scc, scd, secondaryCellGroup, NULL, 0, 1, n_tx, 0, 0, 0, 0);
+  const gNB_RrcConfigurationReq conf = {
+    .pdsch_AntennaPorts = { .N1 = n_tx, .N2 = 1, .XP = 1 },
+    .minRXTXTIME = 0,
+    .do_CSIRS = 0,
+    .do_SRS = 0,
+    .force_256qam_off = false
+  };
+  fill_default_secondaryCellGroup(scc, scd, secondaryCellGroup, NULL, 0, 1, &conf, 0);
 
   // xer_fprint(stdout, &asn_DEF_NR_CellGroupConfig, (const void*)secondaryCellGroup);
 
@@ -742,9 +751,9 @@ int main(int argc, char **argv)
 
   gNB->if_inst->NR_PHY_config_req      = nr_phy_config_request;
   // common configuration
-  rrc_mac_config_req_gNB(0,0, n_tx, n_rx, 0, 6, scc, &rrc.carrier.mib,0, 0, NULL);
+  rrc_mac_config_req_gNB(0,0, conf.pdsch_AntennaPorts, n_rx, 0, 6, scc, &rrc.carrier.mib, rrc.carrier.siblock1, 0, 0, NULL);
   // UE dedicated configuration
-  rrc_mac_config_req_gNB(0,0, n_tx, n_rx, 0, 6, scc, &rrc.carrier.mib,1, secondaryCellGroup->spCellConfig->reconfigurationWithSync->newUE_Identity,secondaryCellGroup);
+  rrc_mac_config_req_gNB(0,0, conf.pdsch_AntennaPorts, n_rx, 0, 6, scc, &rrc.carrier.mib, rrc.carrier.siblock1, 1, secondaryCellGroup->spCellConfig->reconfigurationWithSync->newUE_Identity,secondaryCellGroup);
   frame_parms->nb_antennas_tx = n_tx;
   frame_parms->nb_antennas_rx = n_rx;
   nfapi_nr_config_request_scf_t *cfg = &gNB->gNB_config;
@@ -773,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/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 769bc7d01d3bffd3569651dc1cb34d0bda946b8d..ac70dee0928f4d9586495938d6f50d375adf6cf5 100644
--- a/openair2/COMMON/rrc_messages_types.h
+++ b/openair2/COMMON/rrc_messages_types.h
@@ -401,6 +401,12 @@ typedef struct NbIoTRrcConfigurationReq_s {
   long                    ue_TimersAndConstants_n311_NB;
 } NbIoTRrcConfigurationReq;
 
+typedef struct {
+  int N1;
+  int N2;
+  int XP;
+} rrc_pdsch_AntennaPorts_t;
+
 // gNB: GNB_APP -> RRC messages
 typedef struct NRRrcConfigurationReq_s {
   uint64_t                cell_identity;
@@ -413,13 +419,15 @@ typedef struct NRRrcConfigurationReq_s {
   NR_ServingCellConfig_t  *scd;
   int                     ssb_SubcarrierOffset;
   int                     sib1_tda;
-  int                     pdsch_AntennaPorts;
+  rrc_pdsch_AntennaPorts_t pdsch_AntennaPorts;
   int                     pusch_AntennaPorts;
   int                     minRXTXTIME;
   int                     do_CSIRS;
   int                     do_SRS;
+  bool                    force_256qam_off;
   int                     pusch_TargetSNRx10;
   int                     pucch_TargetSNRx10;
+  bool                    enable_sdap;
 } gNB_RrcConfigurationReq;
 
 typedef struct NRDuDlReq_s {
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 f5ff7ddf9e6ebd05324cc4e27f0ff721e4532a41..434a2896de95e72071931f50d422bdedce49513b 100644
--- a/openair2/GNB_APP/gnb_config.c
+++ b/openair2/GNB_APP/gnb_config.c
@@ -621,8 +621,11 @@ void RCconfig_NR_L1(void) {
   int num_gnbs = GNBSParams[GNB_ACTIVE_GNBS_IDX].numelt;
   AssertFatal (num_gnbs > 0,"Failed to parse config file no gnbs %s \n",GNB_CONFIG_STRING_ACTIVE_GNBS);
 
-  config_getlist( &GNBParamList,GNBParams,sizeof(GNBParams)/sizeof(paramdef_t),NULL); 
-  char *ulprbbl = *GNBParamList.paramarray[0][GNB_ULPRBBLACKLIST_IDX].strptr; 
+  config_getlist( &GNBParamList,GNBParams,sizeof(GNBParams)/sizeof(paramdef_t),NULL);
+  int N1 = *GNBParamList.paramarray[0][GNB_PDSCH_ANTENNAPORTS_N1_IDX].iptr;
+  int N2 = *GNBParamList.paramarray[0][GNB_PDSCH_ANTENNAPORTS_N2_IDX].iptr;
+  int XP = *GNBParamList.paramarray[0][GNB_PDSCH_ANTENNAPORTS_XP_IDX].iptr;
+  char *ulprbbl = *GNBParamList.paramarray[0][GNB_ULPRBBLACKLIST_IDX].strptr;
   if (ulprbbl) LOG_I(NR_PHY,"PRB blacklist %s\n",ulprbbl);
   char *save = NULL;
   char *pt = strtok_r(ulprbbl, ",", &save);
@@ -669,6 +672,9 @@ void RCconfig_NR_L1(void) {
       RC.gNB[j]->prach_thres        = *(L1_ParamList.paramarray[j][L1_PRACH_DTX_THRESHOLD].uptr);
       RC.gNB[j]->pusch_thres        = *(L1_ParamList.paramarray[j][L1_PUSCH_DTX_THRESHOLD].uptr);
       RC.gNB[j]->num_ulprbbl        = num_prbbl;
+      RC.gNB[j]->ap_N1              = N1;
+      RC.gNB[j]->ap_N2              = N2;
+      RC.gNB[j]->ap_XP              = XP;
       LOG_I(NR_PHY,"Copying %d blacklisted PRB to L1 context\n",num_prbbl);
       memcpy(RC.gNB[j]->ulprbbl,prbbl,275*sizeof(int));
       if(strcmp(*(L1_ParamList.paramarray[j][L1_TRANSPORT_N_PREFERENCE_IDX].strptr), "local_mac") == 0) {
@@ -1166,8 +1172,12 @@ void RCconfig_NRRRC(MessageDef *msg_p, uint32_t i, gNB_RRC_INST *rrc) {
 	}
         LOG_I(RRC,"SSB SCO %d\n",*GNBParamList.paramarray[i][GNB_SSB_SUBCARRIEROFFSET_IDX].iptr);
         NRRRC_CONFIGURATION_REQ (msg_p).ssb_SubcarrierOffset = *GNBParamList.paramarray[i][GNB_SSB_SUBCARRIEROFFSET_IDX].iptr;
-        LOG_I(RRC,"pdsch_AntennaPorts %d\n",*GNBParamList.paramarray[i][GNB_PDSCH_ANTENNAPORTS_IDX].iptr);
-        NRRRC_CONFIGURATION_REQ (msg_p).pdsch_AntennaPorts = *GNBParamList.paramarray[i][GNB_PDSCH_ANTENNAPORTS_IDX].iptr;
+        LOG_I(RRC,"pdsch_AntennaPorts N1 %d\n",*GNBParamList.paramarray[i][GNB_PDSCH_ANTENNAPORTS_N1_IDX].iptr);
+        NRRRC_CONFIGURATION_REQ (msg_p).pdsch_AntennaPorts.N1 = *GNBParamList.paramarray[i][GNB_PDSCH_ANTENNAPORTS_N1_IDX].iptr;
+        LOG_I(RRC,"pdsch_AntennaPorts N2 %d\n",*GNBParamList.paramarray[i][GNB_PDSCH_ANTENNAPORTS_N2_IDX].iptr);
+        NRRRC_CONFIGURATION_REQ (msg_p).pdsch_AntennaPorts.N2 = *GNBParamList.paramarray[i][GNB_PDSCH_ANTENNAPORTS_N2_IDX].iptr;
+        LOG_I(RRC,"pdsch_AntennaPorts XP %d\n",*GNBParamList.paramarray[i][GNB_PDSCH_ANTENNAPORTS_XP_IDX].iptr);
+        NRRRC_CONFIGURATION_REQ (msg_p).pdsch_AntennaPorts.XP = *GNBParamList.paramarray[i][GNB_PDSCH_ANTENNAPORTS_XP_IDX].iptr;
         LOG_I(RRC,"pusch_AntennaPorts %d\n",*GNBParamList.paramarray[i][GNB_PUSCH_ANTENNAPORTS_IDX].iptr);
         NRRRC_CONFIGURATION_REQ (msg_p).pusch_AntennaPorts = *GNBParamList.paramarray[i][GNB_PUSCH_ANTENNAPORTS_IDX].iptr;
         LOG_I(RRC,"minTXRXTIME %d\n",*GNBParamList.paramarray[i][GNB_MINRXTXTIME_IDX].iptr);
@@ -1176,11 +1186,15 @@ void RCconfig_NRRRC(MessageDef *msg_p, uint32_t i, gNB_RRC_INST *rrc) {
         NRRRC_CONFIGURATION_REQ (msg_p).sib1_tda = *GNBParamList.paramarray[i][GNB_SIB1_TDA_IDX].iptr;
         LOG_I(RRC,"Do CSI-RS %d\n",*GNBParamList.paramarray[i][GNB_DO_CSIRS_IDX].iptr);
         NRRRC_CONFIGURATION_REQ (msg_p).do_CSIRS = *GNBParamList.paramarray[i][GNB_DO_CSIRS_IDX].iptr;
-        printf("Do SRS %d\n",*GNBParamList.paramarray[i][GNB_DO_SRS_IDX].iptr);
+        LOG_I(RRC, "Do SRS %d\n",*GNBParamList.paramarray[i][GNB_DO_SRS_IDX].iptr);
         NRRRC_CONFIGURATION_REQ (msg_p).do_SRS = *GNBParamList.paramarray[i][GNB_DO_SRS_IDX].iptr;
+        NRRRC_CONFIGURATION_REQ (msg_p).force_256qam_off = *GNBParamList.paramarray[i][GNB_FORCE256QAMOFF_IDX].iptr;
+        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)));
@@ -2049,6 +2063,7 @@ void configure_gnb_du_mac(int inst) {
                         rrc->configuration.minRXTXTIME,
                         rrc->configuration.scc,
                         NULL,
+                        NULL,
                         0,
                         0, // rnti
                         (NR_CellGroupConfig_t *)NULL
diff --git a/openair2/GNB_APP/gnb_paramdef.h b/openair2/GNB_APP/gnb_paramdef.h
index cde7819e2556070fd095a0195e17db6fd60a43e6..8cd831970fae7b9b6a4a84aa6b4959b0ab2893b1 100644
--- a/openair2/GNB_APP/gnb_paramdef.h
+++ b/openair2/GNB_APP/gnb_paramdef.h
@@ -114,7 +114,9 @@ typedef enum {
 #define GNB_CONFIG_STRING_LOCAL_S_PORTD                 "local_s_portd"
 #define GNB_CONFIG_STRING_REMOTE_S_PORTD                "remote_s_portd"
 #define GNB_CONFIG_STRING_SSBSUBCARRIEROFFSET           "ssb_SubcarrierOffset"
-#define GNB_CONFIG_STRING_PDSCHANTENNAPORTS             "pdsch_AntennaPorts"
+#define GNB_CONFIG_STRING_PDSCHANTENNAPORTS_N1          "pdsch_AntennaPorts_N1"
+#define GNB_CONFIG_STRING_PDSCHANTENNAPORTS_N2          "pdsch_AntennaPorts_N2"
+#define GNB_CONFIG_STRING_PDSCHANTENNAPORTS_XP          "pdsch_AntennaPorts_XP"
 #define GNB_CONFIG_STRING_PUSCHANTENNAPORTS             "pusch_AntennaPorts"
 #define GNB_CONFIG_STRING_SIB1TDA                       "sib1_tda"
 #define GNB_CONFIG_STRING_DOCSIRS                       "do_CSIRS"
@@ -122,7 +124,11 @@ typedef enum {
 #define GNB_CONFIG_STRING_NRCELLID                      "nr_cellid"
 #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"
 
 /*-----------------------------------------------------------------------------------------------------------------------------------------*/
 /*                                            cell configuration parameters                                                                */
@@ -144,14 +150,18 @@ typedef enum {
 {GNB_CONFIG_STRING_LOCAL_S_PORTD,                NULL,   0,            uptr:NULL,   defuintval:50001,            TYPE_UINT,      0},  \
 {GNB_CONFIG_STRING_REMOTE_S_PORTD,               NULL,   0,            uptr:NULL,   defuintval:50001,            TYPE_UINT,      0},  \
 {GNB_CONFIG_STRING_SSBSUBCARRIEROFFSET,          NULL,   0,            iptr:NULL,   defintval:31,                TYPE_INT,       0},  \
-{GNB_CONFIG_STRING_PDSCHANTENNAPORTS,            NULL,   0,            iptr:NULL,   defintval:1,                 TYPE_INT,       0},  \
+{GNB_CONFIG_STRING_PDSCHANTENNAPORTS_N1, "horiz. log. antenna ports", 0, iptr:NULL, defintval:1,                 TYPE_INT,       0},  \
+{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_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_ENABLE_SDAP, GNB_CONFIG_HLP_STRING_ENABLE_SDAP, PARAMFLAG_BOOL, iptr:NULL, defintval:0,       TYPE_INT,       0},  \
 }
 
 #define GNB_GNB_ID_IDX                  0
@@ -169,14 +179,18 @@ typedef enum {
 #define GNB_LOCAL_S_PORTD_IDX           12
 #define GNB_REMOTE_S_PORTD_IDX          13
 #define GNB_SSB_SUBCARRIEROFFSET_IDX    14
-#define GNB_PDSCH_ANTENNAPORTS_IDX      15
-#define GNB_PUSCH_ANTENNAPORTS_IDX      16
-#define GNB_SIB1_TDA_IDX                17
-#define GNB_DO_CSIRS_IDX                18
-#define GNB_DO_SRS_IDX                  19
-#define GNB_NRCELLID_IDX                20
-#define GNB_MINRXTXTIME_IDX             21
-#define GNB_ULPRBBLACKLIST_IDX          22
+#define GNB_PDSCH_ANTENNAPORTS_N1_IDX   15
+#define GNB_PDSCH_ANTENNAPORTS_N2_IDX   16
+#define GNB_PDSCH_ANTENNAPORTS_XP_IDX   17
+#define GNB_PUSCH_ANTENNAPORTS_IDX      18
+#define GNB_SIB1_TDA_IDX                19
+#define GNB_DO_CSIRS_IDX                20
+#define GNB_DO_SRS_IDX                  21
+#define GNB_NRCELLID_IDX                22
+#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/NR_MAC_COMMON/nr_mac.h b/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h
index ba3128923fb32e86895f99fd183a7ec179db9619..9dd03ddcf6bdbf708874298260b4c8aae8a55164 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
@@ -264,14 +265,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 bbc8e65940bbcdb8888ad257ea4525869f1ff350..ad0f9c2c38d41357f862e82f473c286dffb89911 100644
--- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c
+++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c
@@ -2593,9 +2593,10 @@ uint16_t nr_dci_size(const NR_BWP_DownlinkCommon_t *initialDownlinkBWP,
                      const NR_CellGroupConfig_t *cg,
                      dci_pdu_rel15_t *dci_pdu,
                      nr_dci_format_t format,
-		     nr_rnti_type_t rnti_type,
-		     uint16_t N_RB,
-                     int bwp_id) {
+                     nr_rnti_type_t rnti_type,
+                     uint16_t N_RB,
+                     int bwp_id,
+                     uint16_t cset0_bwp_size) {
 
   uint16_t size = 0;
   uint16_t numRBG = 0;
@@ -2625,15 +2626,17 @@ uint16_t nr_dci_size(const NR_BWP_DownlinkCommon_t *initialDownlinkBWP,
     srs_config = (ubwpd->srs_Config) ? ubwpd->srs_Config->choice.setup : NULL;
   }
   else if (cg){
-    bwpd=cg->spCellConfig->spCellConfigDedicated->initialDownlinkBWP;
-    bwpc=initialDownlinkBWP;
-    ubwpd=cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP; 
-    ubwpc=initialUplinkBWP;
-    pdsch_Config = (bwpd->pdsch_Config) ? bwpd->pdsch_Config->choice.setup : NULL;
-    pdcch_Config = (bwpd->pdcch_Config) ? bwpd->pdcch_Config->choice.setup : NULL;
-    pucch_Config = (ubwpd->pucch_Config) ? ubwpd->pucch_Config->choice.setup : NULL;
-    pusch_Config = (ubwpd->pusch_Config) ? ubwpd->pusch_Config->choice.setup :  NULL;
-    srs_config = (ubwpd->srs_Config) ? ubwpd->srs_Config->choice.setup: NULL;
+    bwpc = initialDownlinkBWP;
+    ubwpc = initialUplinkBWP;
+    bwpd = cg->spCellConfig && cg->spCellConfig->spCellConfigDedicated ?
+           cg->spCellConfig->spCellConfigDedicated->initialDownlinkBWP : NULL;
+    ubwpd = cg->spCellConfig && cg->spCellConfig->spCellConfigDedicated && cg->spCellConfig->spCellConfigDedicated->uplinkConfig ?
+            cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP : NULL;
+    pdsch_Config = (bwpd && bwpd->pdsch_Config) ? bwpd->pdsch_Config->choice.setup : NULL;
+    pdcch_Config = (bwpd && bwpd->pdcch_Config) ? bwpd->pdcch_Config->choice.setup : NULL;
+    pucch_Config = (ubwpd && ubwpd->pucch_Config) ? ubwpd->pucch_Config->choice.setup : NULL;
+    pusch_Config = (ubwpd && ubwpd->pusch_Config) ? ubwpd->pusch_Config->choice.setup :  NULL;
+    srs_config = (ubwpd && ubwpd->srs_Config) ? ubwpd->srs_Config->choice.setup: NULL;
   }
 
   int n_ul_bwp=1,n_dl_bwp=1;
@@ -2643,7 +2646,9 @@ uint16_t nr_dci_size(const NR_BWP_DownlinkCommon_t *initialDownlinkBWP,
       /// fixed: Format identifier 1, Hop flag 1, MCS 5, NDI 1, RV 2, HARQ PID 4, PUSCH TPC 2 Time Domain assgnmt 4 --20
       size += 20;
       size += (uint8_t)ceil( log2( (N_RB*(N_RB+1))>>1 ) ); // Freq domain assignment -- hopping scenario to be updated
-      size += nr_dci_size(initialDownlinkBWP,initialUplinkBWP,cg,dci_pdu,NR_DL_DCI_FORMAT_1_0, rnti_type, N_RB, bwp_id) - size; // Padding to match 1_0 size
+      int dci_10_size = nr_dci_size(initialDownlinkBWP,initialUplinkBWP,cg,dci_pdu,NR_DL_DCI_FORMAT_1_0, rnti_type, N_RB, bwp_id, cset0_bwp_size);
+      AssertFatal(dci_10_size >= size, "NR_UL_DCI_FORMAT_0_0 size is bigger than NR_DL_DCI_FORMAT_1_0! 3GPP TS 38.212 Section 7.3.1.0: DCI size alignment is not fully implemented");
+      size += dci_10_size - size; // Padding to match 1_0 size
       // UL/SUL indicator assumed to be 0
       break;
 
@@ -2861,6 +2866,14 @@ uint16_t nr_dci_size(const NR_BWP_DownlinkCommon_t *initialDownlinkBWP,
 
     case NR_DL_DCI_FORMAT_1_0:
       /// fixed: Format identifier 1, VRB2PRB 1, MCS 5, NDI 1, RV 2, HARQ PID 4, DAI 2, PUCCH TPC 2, PUCCH RInd 3, PDSCH to HARQ TInd 3 Time Domain assgnmt 4 -- 28
+
+      // 3GPP TS 38.212 Section 7.3.1.0: DCI size alignment
+      // Size of DCI format 1_0 is given by the size of CORESET 0 if CORESET 0 is configured for the cell and the size
+      // of initial DL bandwidth part if CORESET 0 is not configured for the cell
+      if(cset0_bwp_size>0) {
+        N_RB = cset0_bwp_size;
+      }
+
       size = 28;
       size += (uint8_t)ceil( log2( (N_RB*(N_RB+1))>>1 ) ); // Freq domain assignment
 
diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h
index 63277022ce8e4f3c67407c24c39c7710b52d0148..56e24792ccf5b8ed4ea59d083b7bc9a71808c3cd 100644
--- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h
+++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h
@@ -54,7 +54,8 @@ uint16_t nr_dci_size(const NR_BWP_DownlinkCommon_t *initialDLBWP,
                      nr_dci_format_t format,
                      nr_rnti_type_t rnti_type,
                      uint16_t N_RB,
-                     int bwp_id);
+                     int bwp_id,
+                     uint16_t cset0_bwp_size);
 
 void find_aggregation_candidates(uint8_t *aggregation_level,
                                  uint8_t *nr_of_candidates,
diff --git a/openair2/LAYER2/NR_MAC_UE/mac_defs.h b/openair2/LAYER2/NR_MAC_UE/mac_defs.h
index ad86b1385df114294fbe2f131a9a568c75f06a38..fc2c2d2c8b7d6e4c08da99577f8bf748c0039d0a 100644
--- a/openair2/LAYER2/NR_MAC_UE/mac_defs.h
+++ b/openair2/LAYER2/NR_MAC_UE/mac_defs.h
@@ -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/nr_ue_dci_configuration.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c
index 3453e071b10c897cfdb0e8fb8190081e4dbf62b9..0ee6f5501c136b64834224657a184e30e53c330d 100644
--- a/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c
+++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c
@@ -169,7 +169,7 @@ void config_dci_pdu(NR_UE_MAC_INST_t *mac, fapi_nr_dl_config_dci_dl_pdu_rel15_t
       rel15->SubcarrierSpacing = bwp_Common->genericParameters.subcarrierSpacing;
     }
     for (int i = 0; i < rel15->num_dci_options; i++) {
-      rel15->dci_length_options[i] = nr_dci_size(initialDownlinkBWP,initialUplinkBWP, mac->cg, &mac->def_dci_pdu_rel15[rel15->dci_format_options[i]], rel15->dci_format_options[i], NR_RNTI_C, rel15->BWPSize, bwp_id);
+      rel15->dci_length_options[i] = nr_dci_size(initialDownlinkBWP,initialUplinkBWP, mac->cg, &mac->def_dci_pdu_rel15[rel15->dci_format_options[i]], rel15->dci_format_options[i], NR_RNTI_C, rel15->BWPSize, bwp_id, mac->type0_PDCCH_CSS_config.num_rbs);
     }
     break;
     case NR_RNTI_RA:
@@ -185,7 +185,7 @@ void config_dci_pdu(NR_UE_MAC_INST_t *mac, fapi_nr_dl_config_dci_dl_pdu_rel15_t
       rel15->BWPStart = NRRIV2PRBOFFSET(bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
     }
     rel15->SubcarrierSpacing = initialDownlinkBWP->genericParameters.subcarrierSpacing;
-    rel15->dci_length_options[0] = nr_dci_size(initialDownlinkBWP,initialUplinkBWP, mac->cg, &mac->def_dci_pdu_rel15[rel15->dci_format_options[0]], rel15->dci_format_options[0], NR_RNTI_RA, rel15->BWPSize, bwp_id);
+    rel15->dci_length_options[0] = nr_dci_size(initialDownlinkBWP,initialUplinkBWP, mac->cg, &mac->def_dci_pdu_rel15[rel15->dci_format_options[0]], rel15->dci_format_options[0], NR_RNTI_RA, rel15->BWPSize, bwp_id, mac->type0_PDCCH_CSS_config.num_rbs);
     break;
     case NR_RNTI_P:
     break;
@@ -200,7 +200,7 @@ void config_dci_pdu(NR_UE_MAC_INST_t *mac, fapi_nr_dl_config_dci_dl_pdu_rel15_t
       rel15->BWPStart = mac->type0_PDCCH_CSS_config.cset_start_rb;
       rel15->SubcarrierSpacing = initialDownlinkBWP->genericParameters.subcarrierSpacing;
       for (int i = 0; i < rel15->num_dci_options; i++) {
-        rel15->dci_length_options[i] = nr_dci_size(initialDownlinkBWP,initialUplinkBWP, mac->cg, &mac->def_dci_pdu_rel15[rel15->dci_format_options[i]], rel15->dci_format_options[i], NR_RNTI_TC, rel15->BWPSize, bwp_id);
+        rel15->dci_length_options[i] = nr_dci_size(initialDownlinkBWP,initialUplinkBWP, mac->cg, &mac->def_dci_pdu_rel15[rel15->dci_format_options[i]], rel15->dci_format_options[i], NR_RNTI_TC, rel15->BWPSize, bwp_id, mac->type0_PDCCH_CSS_config.num_rbs);
       }
     break;
     case NR_RNTI_SP_CSI:
@@ -223,7 +223,7 @@ void config_dci_pdu(NR_UE_MAC_INST_t *mac, fapi_nr_dl_config_dci_dl_pdu_rel15_t
         rel15->SubcarrierSpacing = mac->mib->subCarrierSpacingCommon + 2;
 
       for (int i = 0; i < rel15->num_dci_options; i++) {
-        rel15->dci_length_options[i] = nr_dci_size(initialDownlinkBWP,initialUplinkBWP, mac->cg, &mac->def_dci_pdu_rel15[rel15->dci_format_options[i]], rel15->dci_format_options[i], NR_RNTI_SI, rel15->BWPSize, 0);
+        rel15->dci_length_options[i] = nr_dci_size(initialDownlinkBWP,initialUplinkBWP, mac->cg, &mac->def_dci_pdu_rel15[rel15->dci_format_options[i]], rel15->dci_format_options[i], NR_RNTI_SI, rel15->BWPSize, 0, mac->type0_PDCCH_CSS_config.num_rbs);
       }
     break;
     case NR_RNTI_SFI:
diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c
index effd8568e3ed470bbf4698434ea87a9a6f217e38..eac1cca54b4e351be2d5075ecc4587d08834e154 100644
--- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c
+++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c
@@ -281,7 +281,6 @@ 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;
-
 }
 
 
@@ -874,14 +873,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)
@@ -1092,7 +1103,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 */
@@ -1153,17 +1187,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];
@@ -1404,10 +1432,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);
 }
 
 
@@ -1889,7 +1925,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;
@@ -2090,11 +2127,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);
diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c
index 2aa8fa2597640a22b62ca218e10c9ca9a84ade75..c62b2d34a6983288a57863d1e081f15af64ffc10 100644
--- a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c
+++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c
@@ -734,6 +734,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 +764,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 --------------------------------------------------------------------------------------------------------*/
 
@@ -1079,6 +1092,10 @@ NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_in
         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) {
 
@@ -2251,26 +2268,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,35 +2318,39 @@ 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);
     if(mac->if_module != NULL && mac->if_module->scheduled_response != NULL)
diff --git a/openair2/LAYER2/NR_MAC_gNB/config.c b/openair2/LAYER2/NR_MAC_gNB/config.c
index 3bc45b42ca87e86620145d1cfc93531eb144815b..6ba8629718a2ba134c5ff8805307f8c1b5766a26 100644
--- a/openair2/LAYER2/NR_MAC_gNB/config.c
+++ b/openair2/LAYER2/NR_MAC_gNB/config.c
@@ -160,11 +160,11 @@ void process_CellGroup(NR_CellGroupConfig_t *CellGroup, NR_UE_sched_ctrl_t *sche
 
 }
 
-void config_common(int Mod_idP, int ssb_SubcarrierOffset, int pdsch_AntennaPorts, int pusch_AntennaPorts, NR_ServingCellConfigCommon_t *scc) {
+void config_common(int Mod_idP, int ssb_SubcarrierOffset, rrc_pdsch_AntennaPorts_t dl_antenna_ports_struct, int pusch_AntennaPorts, NR_ServingCellConfigCommon_t *scc) {
 
   nfapi_nr_config_request_scf_t *cfg = &RC.nrmac[Mod_idP]->config[0];
   RC.nrmac[Mod_idP]->common_channels[0].ServingCellConfigCommon = scc;
-  int i;
+  int pdsch_AntennaPorts = dl_antenna_ports_struct.N1 * dl_antenna_ports_struct.N2 * dl_antenna_ports_struct.XP;
 
   // Carrier configuration
 
@@ -181,7 +181,7 @@ void config_common(int Mod_idP, int ssb_SubcarrierOffset, int pdsch_AntennaPorts
   cfg->carrier_config.dl_frequency.tl.tag = NFAPI_NR_CONFIG_DL_FREQUENCY_TAG;
   cfg->num_tlv++;
 
-  for (i=0; i<5; i++) {
+  for (int i=0; i<5; i++) {
     if (i==scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing) {
       cfg->carrier_config.dl_grid_size[i].value = scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth;
       cfg->carrier_config.dl_k0[i].value = scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->offsetToCarrier;
@@ -215,7 +215,7 @@ void config_common(int Mod_idP, int ssb_SubcarrierOffset, int pdsch_AntennaPorts
   cfg->carrier_config.uplink_frequency.tl.tag = NFAPI_NR_CONFIG_UPLINK_FREQUENCY_TAG;
   cfg->num_tlv++;
 
-  for (i=0; i<5; i++) {
+  for (int i=0; i<5; i++) {
     if (i==scc->uplinkConfigCommon->frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing) {
       cfg->carrier_config.ul_grid_size[i].value = scc->uplinkConfigCommon->frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth;
       cfg->carrier_config.ul_k0[i].value = scc->uplinkConfigCommon->frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->offsetToCarrier;
@@ -306,7 +306,7 @@ void config_common(int Mod_idP, int ssb_SubcarrierOffset, int pdsch_AntennaPorts
   cfg->num_tlv++;
 
   cfg->prach_config.num_prach_fd_occasions_list = (nfapi_nr_num_prach_fd_occasions_t *) malloc(cfg->prach_config.num_prach_fd_occasions.value*sizeof(nfapi_nr_num_prach_fd_occasions_t));
-  for (i=0; i<cfg->prach_config.num_prach_fd_occasions.value; i++) {
+  for (int i=0; i<cfg->prach_config.num_prach_fd_occasions.value; i++) {
 //    cfg->prach_config.num_prach_fd_occasions_list[i].num_prach_fd_occasions = i;
     if (cfg->prach_config.prach_sequence_length.value)
       cfg->prach_config.num_prach_fd_occasions_list[i].prach_root_sequence_index.value = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->prach_RootSequenceIndex.choice.l139; 
@@ -375,7 +375,7 @@ void config_common(int Mod_idP, int ssb_SubcarrierOffset, int pdsch_AntennaPorts
     case 3 :
       cfg->ssb_table.ssb_mask_list[0].ssb_mask.value = 0;
       cfg->ssb_table.ssb_mask_list[1].ssb_mask.value = 0;
-      for (i=0; i<4; i++) {
+      for (int i=0; i<4; i++) {
         cfg->ssb_table.ssb_mask_list[0].ssb_mask.value += (scc->ssb_PositionsInBurst->choice.longBitmap.buf[3-i]<<i*8);
         cfg->ssb_table.ssb_mask_list[1].ssb_mask.value += (scc->ssb_PositionsInBurst->choice.longBitmap.buf[7-i]<<i*8);
       }
@@ -414,7 +414,8 @@ void config_common(int Mod_idP, int ssb_SubcarrierOffset, int pdsch_AntennaPorts
   cfg->carrier_config.num_rx_ant.value = pusch_AntennaPorts;
   AssertFatal(pusch_AntennaPorts > 0 && pusch_AntennaPorts < 13, "pusch_AntennaPorts in 1...12\n");
   cfg->carrier_config.num_rx_ant.tl.tag = NFAPI_NR_CONFIG_NUM_RX_ANT_TAG;
-  LOG_I(NR_MAC,"Set TX/RX antenna number to %d (num ssb %d: %x,%x)\n",cfg->carrier_config.num_tx_ant.value,num_ssb,cfg->ssb_table.ssb_mask_list[0].ssb_mask.value,cfg->ssb_table.ssb_mask_list[1].ssb_mask.value);
+  LOG_I(NR_MAC,"Set TX/RX antenna number to %d (num ssb %d: %x,%x)\n",
+        cfg->carrier_config.num_tx_ant.value,num_ssb,cfg->ssb_table.ssb_mask_list[0].ssb_mask.value,cfg->ssb_table.ssb_mask_list[1].ssb_mask.value);
   AssertFatal(cfg->carrier_config.num_tx_ant.value > 0,"carrier_config.num_tx_ant.value %d !\n",cfg->carrier_config.num_tx_ant.value );
   cfg->num_tlv++;
   cfg->num_tlv++;
@@ -451,15 +452,16 @@ void config_common(int Mod_idP, int ssb_SubcarrierOffset, int pdsch_AntennaPorts
 
 int rrc_mac_config_req_gNB(module_id_t Mod_idP,
                            int ssb_SubcarrierOffset,
-                           int pdsch_AntennaPorts,
+                           rrc_pdsch_AntennaPorts_t pdsch_AntennaPorts,
                            int pusch_AntennaPorts,
                            int sib1_tda,
                            int minRXTXTIMEpdsch,
                            NR_ServingCellConfigCommon_t *scc,
                            NR_BCCH_BCH_Message_t *mib,
-	                   int add_ue,
+                           NR_BCCH_DL_SCH_Message_t *sib1,
+                           int add_ue,
                            uint32_t rnti,
-	                   NR_CellGroupConfig_t *CellGroup) {
+                           NR_CellGroupConfig_t *CellGroup) {
 
   if (scc != NULL ) {
     AssertFatal((scc->ssb_PositionsInBurst->present > 0) && (scc->ssb_PositionsInBurst->present < 4), "SSB Bitmap type %d is not valid\n",scc->ssb_PositionsInBurst->present);
@@ -567,28 +569,34 @@ int rrc_mac_config_req_gNB(module_id_t Mod_idP,
     }
   }
  
-  if (mib) RC.nrmac[Mod_idP]->common_channels[0].mib = mib; 
- 
+  if (mib) RC.nrmac[Mod_idP]->common_channels[0].mib = mib;
+  if (sib1) RC.nrmac[Mod_idP]->common_channels[0].sib1 = sib1;
+
   if (CellGroup) {
 
-    const NR_ServingCellConfig_t *servingCellConfig = CellGroup->spCellConfig->spCellConfigDedicated;
-    const struct NR_ServingCellConfig__downlinkBWP_ToAddModList *bwpList = servingCellConfig->downlinkBWP_ToAddModList;
-    if(bwpList) {
-      AssertFatal(bwpList->list.count > 0, "downlinkBWP_ToAddModList has no BWPs!\n");
-      for (int i = 0; i < bwpList->list.count; ++i) {
-        const NR_BWP_Downlink_t *bwp = bwpList->list.array[i];
-        calculate_preferred_dl_tda(Mod_idP, bwp);
-      }
-    } else {
+    if (get_softmodem_params()->sa) {
       calculate_preferred_dl_tda(Mod_idP, NULL);
     }
 
-    const struct NR_UplinkConfig__uplinkBWP_ToAddModList *ubwpList = servingCellConfig->uplinkConfig->uplinkBWP_ToAddModList;
-    if(ubwpList) {
-      AssertFatal(ubwpList->list.count > 0, "uplinkBWP_ToAddModList no BWPs!\n");
-      for (int i = 0; i < ubwpList->list.count; ++i) {
-        const NR_BWP_Uplink_t *ubwp = ubwpList->list.array[i];
-        calculate_preferred_ul_tda(Mod_idP, ubwp);
+    const NR_ServingCellConfig_t *servingCellConfig = NULL;
+    if(CellGroup->spCellConfig && CellGroup->spCellConfig->spCellConfigDedicated) {
+      servingCellConfig = CellGroup->spCellConfig->spCellConfigDedicated;
+      const struct NR_ServingCellConfig__downlinkBWP_ToAddModList *bwpList = servingCellConfig->downlinkBWP_ToAddModList;
+      if(bwpList) {
+        AssertFatal(bwpList->list.count > 0, "downlinkBWP_ToAddModList has no BWPs!\n");
+        for (int i = 0; i < bwpList->list.count; ++i) {
+          const NR_BWP_Downlink_t *bwp = bwpList->list.array[i];
+          calculate_preferred_dl_tda(Mod_idP, bwp);
+        }
+      }
+
+      const struct NR_UplinkConfig__uplinkBWP_ToAddModList *ubwpList = servingCellConfig->uplinkConfig->uplinkBWP_ToAddModList;
+      if(ubwpList) {
+        AssertFatal(ubwpList->list.count > 0, "uplinkBWP_ToAddModList no BWPs!\n");
+        for (int i = 0; i < ubwpList->list.count; ++i) {
+          const NR_BWP_Uplink_t *ubwp = ubwpList->list.array[i];
+          calculate_preferred_ul_tda(Mod_idP, ubwp);
+        }
       }
     }
 
@@ -648,7 +656,6 @@ int rrc_mac_config_req_gNB(module_id_t Mod_idP,
       UE_info->CellGroup[UE_id] = CellGroup;
       LOG_I(NR_MAC,"Modified UE_id %d/%x with CellGroup\n",UE_id,rnti);
       process_CellGroup(CellGroup,&UE_info->UE_sched_ctrl[UE_id]);
-      const NR_ServingCellConfig_t *servingCellConfig = CellGroup ? CellGroup->spCellConfig->spCellConfigDedicated : NULL;
       NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
       sched_ctrl->update_pdsch_ps = true;
       sched_ctrl->update_pusch_ps = true;
@@ -673,16 +680,14 @@ int rrc_mac_config_req_gNB(module_id_t Mod_idP,
         bwpd = (void*)CellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP;
         genericParameters = &scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters;
       }
-      else
-        AssertFatal(1==0,"Either initial BWP or active BWP should always be present\n");
-      sched_ctrl->search_space = get_searchspace(scc, bwpd, target_ss);
+      sched_ctrl->search_space = get_searchspace(sib1 ? sib1->message.choice.c1->choice.systemInformationBlockType1 : NULL, scc, bwpd, target_ss);
       sched_ctrl->coreset = get_coreset(Mod_idP, scc, bwpd, sched_ctrl->search_space, target_ss);
       sched_ctrl->sched_pdcch = set_pdcch_structure(RC.nrmac[Mod_idP],
                                                     sched_ctrl->search_space,
                                                     sched_ctrl->coreset,
                                                     scc,
                                                     genericParameters,
-                                                    NULL);
+                                                    RC.nrmac[Mod_idP]->type0_PDCCH_CSS_config);
       sched_ctrl->maxL = 2;
     }
   }
diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c
index 5a3656417bbc5611d546be00c694972f754c5d1d..59f0367090342b1f523da96c619f3c07e9a7a747 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);
@@ -635,7 +637,7 @@ void nr_initiate_ra_proc(module_id_t module_idP,
                                             ra->coreset,
                                             scc,
                                             genericParameters,
-                                            NULL);
+                                            &nr_mac->type0_PDCCH_CSS_config[ra->beam_id]);
 
       // retrieving ra pdcch monitoring period and offset
       find_monitoring_periodicity_offset_common(ra->ra_ss, &monitoring_slot_period, &monitoring_offset);
@@ -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;
@@ -871,7 +876,9 @@ void nr_generate_Msg3_retransmission(module_id_t module_idP, int CC_id, frame_t
     dci_pdu_rel15_t uldci_payload;
     memset(&uldci_payload, 0, sizeof(uldci_payload));
 
-    config_uldci(ubwp,
+    const NR_SIB1_t *sib1 = cc->sib1 ? cc->sib1->message.choice.c1->choice.systemInformationBlockType1 : NULL;
+    config_uldci(sib1,
+                 ubwp,
                  ubwpd,
                  scc,
                  pusch_pdu,
@@ -889,7 +896,8 @@ void nr_generate_Msg3_retransmission(module_id_t module_idP, int CC_id, frame_t
                        NR_UL_DCI_FORMAT_0_0,
                        NR_RNTI_TC,
                        pusch_pdu->bwp_size,
-                       ra->bwp_id);
+                       ra->bwp_id,
+                       nr_mac->cset0_bwp_size);
 
     // Mark the corresponding RBs as used
 
@@ -1461,7 +1469,8 @@ void nr_generate_Msg2(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra
                        NR_DL_DCI_FORMAT_1_0,
                        NR_RNTI_RA,
                        BWPSize,
-                       bwpid);
+                       bwpid,
+                       nr_mac->cset0_bwp_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];
@@ -1603,17 +1612,11 @@ void nr_generate_Msg4(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra
       return;
     }
 
-    int n_rb=0;
-    for (int i=0;i<6;i++)
-      for (int j=0;j<8;j++) {
-        n_rb+=((coreset->frequencyDomainResources.buf[i]>>j)&1);
-      }
-    n_rb*=6;
-    const uint16_t N_cce = n_rb * coreset->duration / NR_NB_REG_PER_CCE;
     const int delta_PRI=0;
-    int r_pucch = ((CCEIndex<<1)/N_cce)+(delta_PRI<<1);
+    int r_pucch = nr_get_pucch_resource(coreset, sched_ctrl->active_ubwp, NULL, CCEIndex);
+
+    LOG_D(NR_MAC,"[RAPROC] Msg4 r_pucch %d (CCEIndex %d, nb_of_candidates %d, delta_PRI %d)\n", r_pucch, CCEIndex, nr_of_candidates, delta_PRI);
 
-    LOG_D(NR_MAC,"[RAPROC] Msg4 r_pucch %d (CCEIndex %d, N_cce %d, nb_of_candidates %d,delta_PRI %d)\n",r_pucch,CCEIndex,N_cce,nr_of_candidates,delta_PRI);
     int alloc = nr_acknack_scheduling(module_idP, UE_id, frameP, slotP, r_pucch, 1);
     AssertFatal(alloc>=0,"Couldn't find a pucch allocation for ack nack (msg4)\n");
     NR_sched_pucch_t *pucch = &sched_ctrl->sched_pucch[alloc];
@@ -1855,7 +1858,8 @@ void nr_generate_Msg4(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra
                        NR_DL_DCI_FORMAT_1_0,
                        NR_RNTI_TC,
                        pdsch_pdu_rel15->BWPSize,
-                       bwpid);
+                       bwpid,
+                       nr_mac->cset0_bwp_size);
 
     // Add padding header and zero rest out if there is space left
     if (ra->mac_pdu_length < harq->tb_size) {
diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c
index cddeb364d519e666cd9e9bbd3c72de38d224e2ef..4b654e2ad18fe9285a924237e2d985b06feca362 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c
@@ -545,7 +545,8 @@ void nr_fill_nfapi_dl_sib1_pdu(int Mod_idP,
                      dci_format,
                      rnti_type,
                      pdsch_pdu_rel15->BWPSize,
-                     0);
+                     0,
+                     gNB_mac->cset0_bwp_size);
 
   LOG_D(MAC,"BWPSize: %i\n", pdcch_pdu_rel15->BWPSize);
   LOG_D(MAC,"BWPStart: %i\n", pdcch_pdu_rel15->BWPStart);
@@ -620,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 f030c40a01d1fc5ae22cdf827ddedebd19e98bb0..00dec1bd4d1be0ef8935d60434e6aa370d1f4f9a 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c
@@ -86,16 +86,22 @@ void calculate_preferred_dl_tda(module_id_t module_id, const NR_BWP_Downlink_t *
   else {
     target_ss = NR_SearchSpace__searchSpaceType_PR_common;
   }
-  NR_SearchSpace_t *search_space = get_searchspace(scc, bwp ? bwp->bwp_Dedicated : NULL, target_ss);
+  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,
+                                                   bwp ? bwp->bwp_Dedicated : NULL,
+                                                   target_ss);
+
   NR_ControlResourceSet_t *coreset = get_coreset(module_id, scc, bwp ? bwp->bwp_Dedicated : NULL, search_space, target_ss);
   // get coreset symbol "map"
   const uint16_t symb_coreset = (1 << coreset->duration) - 1;
 
-  /* check that TDA index 0 fits into DL and does not overlap CORESET */
-  const struct NR_PDSCH_TimeDomainResourceAllocationList *tdaList = bwp ?
-      bwp->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList :
-      scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList;
+  NR_PDSCH_TimeDomainResourceAllocationList_t *tdaList = get_pdsch_TimeDomainAllocationList(bwp,
+                                                                                            scc,
+                                                                                            sib1);
   AssertFatal(tdaList->list.count >= 1, "need to have at least one TDA for DL slots\n");
+
+  /* check that TDA index 0 fits into DL and does not overlap CORESET */
   const NR_PDSCH_TimeDomainResourceAllocation_t *tdaP_DL = tdaList->list.array[0];
   AssertFatal(!tdaP_DL->k0 || *tdaP_DL->k0 == 0,
               "TimeDomainAllocation at index 1: non-null k0 (%ld) is not supported by the scheduler\n",
@@ -525,19 +531,33 @@ bool allocate_dl_retransmission(module_id_t module_id,
                                 int UE_id,
                                 int current_harq_pid) {
 
-  const NR_ServingCellConfigCommon_t *scc = RC.nrmac[module_id]->common_channels->ServingCellConfigCommon;
-  NR_UE_info_t *UE_info = &RC.nrmac[module_id]->UE_info;
+  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;
   NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
   NR_sched_pdsch_t *retInfo = &sched_ctrl->harq_processes[current_harq_pid].sched_pdsch;
   NR_CellGroupConfig_t *cg = UE_info->CellGroup[UE_id];
-  NR_BWP_DownlinkDedicated_t *bwpd= cg ? cg->spCellConfig->spCellConfigDedicated->initialDownlinkBWP:NULL;
 
-
-  NR_BWP_t *genericParameters = sched_ctrl->active_bwp ?
-                                &sched_ctrl->active_bwp->bwp_Common->genericParameters :
-                                &RC.nrmac[module_id]->common_channels[0].ServingCellConfigCommon->downlinkConfigCommon->initialDownlinkBWP->genericParameters;
-
-  const uint16_t bwpSize = NRRIV2BW(genericParameters->locationAndBandwidth, MAX_BWP_SIZE);
+  NR_BWP_DownlinkDedicated_t *bwpd =
+      cg &&
+      cg->spCellConfig &&
+      cg->spCellConfig->spCellConfigDedicated ?
+      cg->spCellConfig->spCellConfigDedicated->initialDownlinkBWP : NULL;
+
+  NR_BWP_UplinkDedicated_t *ubwpd =
+      cg &&
+      cg->spCellConfig &&
+      cg->spCellConfig->spCellConfigDedicated &&
+      cg->spCellConfig->spCellConfigDedicated->uplinkConfig ?
+      cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP : NULL;
+
+  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,
+                                                             sib1);
+
+  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
 
   NR_pdsch_semi_static_t *ps = &sched_ctrl->pdsch_semi_static;
@@ -565,7 +585,15 @@ bool allocate_dl_retransmission(module_id_t module_id,
     /* 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) {
-      nr_set_pdsch_semi_static(scc, cg, sched_ctrl->active_bwp, bwpd, tda, ps->nrOfLayers, sched_ctrl, ps);
+      nr_set_pdsch_semi_static(sib1,
+                               scc,
+                               cg,
+                               sched_ctrl->active_bwp,
+                               bwpd,
+                               tda,
+                               ps->nrOfLayers,
+                               sched_ctrl,
+                               ps);
       sched_ctrl->update_pdsch_ps = false;
     }
   } else {
@@ -573,7 +601,15 @@ bool allocate_dl_retransmission(module_id_t module_id,
      * that we have enough resources */
 
     NR_pdsch_semi_static_t temp_ps = *ps;
-    nr_set_pdsch_semi_static(scc, UE_info->CellGroup[UE_id], sched_ctrl->active_bwp, bwpd, tda, ps->nrOfLayers, sched_ctrl, &temp_ps);
+    nr_set_pdsch_semi_static(sib1,
+                             scc,
+                             UE_info->CellGroup[UE_id],
+                             sched_ctrl->active_bwp,
+                             bwpd,
+                             tda,
+                             ps->nrOfLayers,
+                             sched_ctrl,
+                             &temp_ps);
     while (rbStart < bwpSize &&
            !(rballoc_mask[rbStart]&SL_to_bitmap(temp_ps.startSymbolIndex, temp_ps.nrOfSymbols)))
       rbStart++;
@@ -634,7 +670,8 @@ 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) */
-  const int alloc = nr_acknack_scheduling(module_id, UE_id, frame, slot, -1, 0);
+  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",
@@ -765,15 +802,30 @@ void pf_dl(module_id_t module_id,
     *max = UE_sched.next[*max];
     *p = -1;
     NR_CellGroupConfig_t *cg = UE_info->CellGroup[UE_id];
-    NR_BWP_DownlinkDedicated_t *bwpd= cg ? cg->spCellConfig->spCellConfigDedicated->initialDownlinkBWP:NULL;
+
+    NR_BWP_DownlinkDedicated_t *bwpd =
+        cg &&
+        cg->spCellConfig &&
+        cg->spCellConfig->spCellConfigDedicated ?
+        cg->spCellConfig->spCellConfigDedicated->initialDownlinkBWP : NULL;
+
+    NR_BWP_UplinkDedicated_t *ubwpd =
+        cg &&
+        cg->spCellConfig &&
+        cg->spCellConfig->spCellConfigDedicated &&
+        cg->spCellConfig->spCellConfigDedicated->uplinkConfig ?
+        cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP : NULL;
 
     NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
     const uint16_t rnti = UE_info->rnti[UE_id];
-    NR_BWP_t *genericParameters = sched_ctrl->active_bwp ?
-      &sched_ctrl->active_bwp->bwp_Common->genericParameters:
-      &scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters;
+    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,
+                                                               sib1);
 
-    const uint16_t bwpSize = NRRIV2BW(genericParameters->locationAndBandwidth,MAX_BWP_SIZE);
+    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
 
     if (sched_ctrl->available_dl_harq.head < 0) {
@@ -809,7 +861,8 @@ 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) */
-    const int alloc = nr_acknack_scheduling(module_id, UE_id, frame, slot, -1, 0);
+    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",
@@ -846,10 +899,16 @@ void pf_dl(module_id_t module_id,
     NR_sched_pdsch_t *sched_pdsch = &sched_ctrl->sched_pdsch;
     NR_pdsch_semi_static_t *ps = &sched_ctrl->pdsch_semi_static;
 
-    if (ps->nrOfLayers != layers[UE_id] ||
-        ps->time_domain_allocation != tda ||
-        sched_ctrl->update_pdsch_ps) {
-      nr_set_pdsch_semi_static(scc, UE_info->CellGroup[UE_id], sched_ctrl->active_bwp, bwpd, tda, layers[UE_id], sched_ctrl, ps);
+    if (ps->nrOfLayers != layers[UE_id] || ps->time_domain_allocation != tda || sched_ctrl->update_pdsch_ps) {
+      nr_set_pdsch_semi_static(sib1,
+                               scc,
+                               UE_info->CellGroup[UE_id],
+                               sched_ctrl->active_bwp,
+                               bwpd,
+                               tda,
+                               layers[UE_id],
+                               sched_ctrl,
+                               ps);
       sched_ctrl->update_pdsch_ps = false;
     }
 
@@ -921,14 +980,21 @@ void nr_fr1_dlsch_preprocessor(module_id_t module_id, frame_t frame, sub_frame_t
   const int startSymbolAndLength = tdaList->list.array[tda]->startSymbolAndLength;
   SLIV2SL(startSymbolAndLength, &startSymbolIndex, &nrOfSymbols);
 
-  const uint16_t bwpSize = NRRIV2BW(sched_ctrl->active_bwp ?
-				    sched_ctrl->active_bwp->bwp_Common->genericParameters.locationAndBandwidth:
-				    scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.locationAndBandwidth,
-				    MAX_BWP_SIZE);
-  const uint16_t BWPStart = NRRIV2PRBOFFSET(sched_ctrl->active_bwp ?
-				            sched_ctrl->active_bwp->bwp_Common->genericParameters.locationAndBandwidth:
-				            scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.locationAndBandwidth,
-				            MAX_BWP_SIZE);
+  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,
+                                                             sib1);
+
+  NR_BWP_DownlinkDedicated_t *bwpd =
+      UE_info->CellGroup[UE_id] &&
+      UE_info->CellGroup[UE_id]->spCellConfig &&
+      UE_info->CellGroup[UE_id]->spCellConfig->spCellConfigDedicated ?
+      UE_info->CellGroup[UE_id]->spCellConfig->spCellConfigDedicated->initialDownlinkBWP : NULL;
+
+  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);
+  const uint16_t BWPStart = coresetid == 0 ? RC.nrmac[module_id]->cset0_bwp_start : NRRIV2PRBOFFSET(genericParameters->locationAndBandwidth,MAX_BWP_SIZE);
 
   const uint16_t slbitmap = SL_to_bitmap(startSymbolIndex, nrOfSymbols);
   uint16_t *vrb_map = RC.nrmac[module_id]->common_channels[CC_id].vrb_map;
@@ -1008,7 +1074,12 @@ void nr_schedule_ue_spec(module_id_t module_id,
     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];
-    NR_BWP_DownlinkDedicated_t *bwpd= cg ? cg->spCellConfig->spCellConfigDedicated->initialDownlinkBWP:NULL;
+
+    NR_BWP_DownlinkDedicated_t *bwpd =
+        cg &&
+        cg->spCellConfig &&
+        cg->spCellConfig->spCellConfigDedicated ?
+        cg->spCellConfig->spCellConfigDedicated->initialDownlinkBWP : NULL;
 
     /* update TA and set ta_apply every 10 frames.
      * Possible improvement: take the periodicity from input file.
@@ -1087,15 +1158,17 @@ void nr_schedule_ue_spec(module_id_t module_id,
           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,
+                                                               sib1);
 
-    /* look up the PDCCH PDU for this CC, BWP, and CORESET. If it does not
-     * exist, create it */
-
-    // BWP
-    NR_BWP_t *genericParameters = bwp ? &bwp->bwp_Common->genericParameters : &scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters;
+    NR_SearchSpace_t *ss = (bwp||bwpd) ? sched_ctrl->search_space : gNB_mac->sched_ctrlCommon->search_space;
 
     const int bwpid = bwp ? bwp->bwp_Id : 0;
     const int coresetid = (bwp||bwpd) ? sched_ctrl->coreset->controlResourceSetId : gNB_mac->sched_ctrlCommon->coreset->controlResourceSetId;
+
+    /* 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");
@@ -1126,8 +1199,14 @@ void nr_schedule_ue_spec(module_id_t module_id,
     const int pduindex = gNB_mac->pdu_index[CC_id]++;
     pdsch_pdu->pduIndex = pduindex;
 
-    pdsch_pdu->BWPSize  = NRRIV2BW(genericParameters->locationAndBandwidth, MAX_BWP_SIZE);
-    pdsch_pdu->BWPStart = NRRIV2PRBOFFSET(genericParameters->locationAndBandwidth,MAX_BWP_SIZE);
+    if (coresetid == 0) {
+      pdsch_pdu->BWPSize  = gNB_mac->cset0_bwp_size;
+      pdsch_pdu->BWPStart = gNB_mac->cset0_bwp_start;
+    } else {
+      pdsch_pdu->BWPSize  = NRRIV2BW(genericParameters->locationAndBandwidth, MAX_BWP_SIZE);
+      pdsch_pdu->BWPStart = NRRIV2PRBOFFSET(genericParameters->locationAndBandwidth,MAX_BWP_SIZE);
+    }
+
     pdsch_pdu->SubcarrierSpacing = genericParameters->subcarrierSpacing;
 
     pdsch_pdu->CyclicPrefix = genericParameters->cyclicPrefix ? *genericParameters->cyclicPrefix : 0;
@@ -1258,14 +1337,9 @@ void nr_schedule_ue_spec(module_id_t module_id,
           dci_payload.tpc,
           pucch->timing_indicator);
 
-    const long f = sched_ctrl->search_space->searchSpaceType->choice.ue_Specific->dci_Formats;
-    int dci_format;
-    if (sched_ctrl->search_space) {
-       dci_format = f ? NR_DL_DCI_FORMAT_1_1 : NR_DL_DCI_FORMAT_1_0;
-    }
-    else {
-       dci_format = NR_DL_DCI_FORMAT_1_0;
-    }
+    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,
@@ -1275,7 +1349,8 @@ void nr_schedule_ue_spec(module_id_t module_id,
                        dci_format,
                        rnti_type,
                        pdsch_pdu->BWPSize,
-                       bwp? bwp->bwp_Id : 0);
+                       bwp? bwp->bwp_Id : 0,
+                       gNB_mac->cset0_bwp_size);
 
     LOG_D(NR_MAC,
           "coreset params: FreqDomainResource %llx, start_symbol %d  n_symb %d\n",
diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c
index 7891c5bcd330849b8dc02f9ae65ee6c8ff445b4d..338fc7dcd52627a4b843235605dfdc656db7648f 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c
@@ -280,7 +280,7 @@ void nr_preprocessor_phytest(module_id_t module_id,
   ps->nrOfLayers = target_dl_Nl;
 
   if (ps->time_domain_allocation != tda || ps->nrOfLayers != target_dl_Nl)
-    nr_set_pdsch_semi_static(scc, UE_info->CellGroup[UE_id], sched_ctrl->active_bwp, NULL, tda, target_dl_Nl, sched_ctrl, ps);
+    nr_set_pdsch_semi_static(NULL, scc, UE_info->CellGroup[UE_id], sched_ctrl->active_bwp, NULL, tda, target_dl_Nl, sched_ctrl, ps);
 
   /* find largest unallocated chunk */
   const int bwpSize = NRRIV2BW(sched_ctrl->active_bwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
@@ -357,7 +357,8 @@ void nr_preprocessor_phytest(module_id_t module_id,
               __func__,
               UE_id);
 
-  const int alloc = nr_acknack_scheduling(module_id, UE_id, frame, slot, -1, 0);
+  int r_pucch = nr_get_pucch_resource(sched_ctrl->coreset, sched_ctrl->active_ubwp, NULL, 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",
@@ -442,7 +443,7 @@ bool nr_ul_preprocessor_phytest(module_id_t module_id, frame_t frame, sub_frame_
               "time domain assignment %d >= %d\n",
               tda,
               tdaList->list.count);
-  int K2 = get_K2(scc,sched_ctrl->active_ubwp, tda, mu);
+  int K2 = get_K2(scc,NULL,sched_ctrl->active_ubwp, tda, mu);
   const int sched_frame = frame + (slot + K2 >= nr_slots_per_frame[mu]);
   const int sched_slot = (slot + K2) % nr_slots_per_frame[mu];
   /* check if slot is UL, and that slot is 8 (assuming K2=6 because of UE
@@ -451,7 +452,9 @@ bool nr_ul_preprocessor_phytest(module_id_t module_id, frame_t frame, sub_frame_
   if (!is_xlsch_in_slot(ulsch_slot_bitmap, sched_slot))
     return false;
 
-  const long f = sched_ctrl->search_space->searchSpaceType->choice.ue_Specific->dci_Formats;
+  const long f = (sched_ctrl->active_bwp && sched_ctrl->search_space &&
+                  sched_ctrl->search_space->searchSpaceType->present == NR_SearchSpace__searchSpaceType_PR_ue_Specific) ?
+                    sched_ctrl->search_space->searchSpaceType->choice.ue_Specific->dci_Formats : 0;
   const int dci_format = f ? NR_UL_DCI_FORMAT_0_1 : NR_UL_DCI_FORMAT_0_0;
   const uint8_t num_dmrs_cdm_grps_no_data = 1;
   /* we want to avoid a lengthy deduction of DMRS and other parameters in
@@ -461,7 +464,7 @@ bool nr_ul_preprocessor_phytest(module_id_t module_id, frame_t frame, sub_frame_
   if (ps->time_domain_allocation != tda
       || ps->dci_format != dci_format
       || ps->num_dmrs_cdm_grps_no_data != num_dmrs_cdm_grps_no_data)
-    nr_set_pusch_semi_static(scc, sched_ctrl->active_ubwp, NULL,dci_format, tda, num_dmrs_cdm_grps_no_data, ps);
+    nr_set_pusch_semi_static(NULL, scc, sched_ctrl->active_ubwp, NULL,dci_format, tda, num_dmrs_cdm_grps_no_data, ps);
 
   uint16_t rbStart = 0;
   uint16_t rbSize;
diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c
index 38f34f710b7e39db220fdee74eb1e8df6698667e..67c97a683592d5d7264be9e74a7c2becde84ded1 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c
@@ -226,6 +226,49 @@ void set_dl_dmrs_ports(NR_pdsch_semi_static_t *ps) {
   }
 }
 
+NR_BWP_t *get_dl_bwp_genericParameters(NR_BWP_Downlink_t *active_bwp,
+                                       NR_ServingCellConfigCommon_t *ServingCellConfigCommon,
+                                       const NR_SIB1_t *sib1) {
+  NR_BWP_t *genericParameters = NULL;
+  if (active_bwp) {
+    genericParameters = &active_bwp->bwp_Common->genericParameters;
+  } else if (ServingCellConfigCommon) {
+    genericParameters = &ServingCellConfigCommon->downlinkConfigCommon->initialDownlinkBWP->genericParameters;
+  } else {
+    genericParameters = &sib1->servingCellConfigCommon->downlinkConfigCommon.initialDownlinkBWP.genericParameters;
+  }
+  return genericParameters;
+}
+
+NR_BWP_t *get_ul_bwp_genericParameters(NR_BWP_Uplink_t *active_ubwp,
+                                       NR_ServingCellConfigCommon_t *ServingCellConfigCommon,
+                                       const NR_SIB1_t *sib1) {
+  NR_BWP_t *genericParameters = NULL;
+  if (active_ubwp) {
+    genericParameters = &active_ubwp->bwp_Common->genericParameters;
+  } else if (ServingCellConfigCommon) {
+    genericParameters = &ServingCellConfigCommon->uplinkConfigCommon->initialUplinkBWP->genericParameters;
+  } else {
+    genericParameters = &sib1->servingCellConfigCommon->uplinkConfigCommon->initialUplinkBWP.genericParameters;
+  }
+  return genericParameters;
+}
+
+NR_PDSCH_TimeDomainResourceAllocationList_t *get_pdsch_TimeDomainAllocationList(const NR_BWP_Downlink_t *active_bwp,
+                                                                                const NR_ServingCellConfigCommon_t *ServingCellConfigCommon,
+                                                                                const NR_SIB1_t *sib1) {
+  NR_PDSCH_TimeDomainResourceAllocationList_t *tdaList = NULL;
+  if (active_bwp) {
+    tdaList = active_bwp->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList;
+  } else if (ServingCellConfigCommon) {
+    tdaList = ServingCellConfigCommon->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList;
+  } else {
+    tdaList = sib1->servingCellConfigCommon->downlinkConfigCommon.initialDownlinkBWP.pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList;
+  }
+  return tdaList;
+}
+
+
 NR_ControlResourceSet_t *get_coreset(module_id_t module_idP,
                                      NR_ServingCellConfigCommon_t *scc,
                                      void *bwp,
@@ -262,17 +305,29 @@ NR_ControlResourceSet_t *get_coreset(module_id_t module_idP,
   }
 }
 
-NR_SearchSpace_t *get_searchspace(NR_ServingCellConfigCommon_t *scc,
-				  NR_BWP_DownlinkDedicated_t *bwp_Dedicated,
-				  NR_SearchSpace__searchSpaceType_PR target_ss) {
+NR_SearchSpace_t *get_searchspace(const NR_SIB1_t *sib1,
+                                  NR_ServingCellConfigCommon_t *scc,
+                                  NR_BWP_DownlinkDedicated_t *bwp_Dedicated,
+                                  NR_SearchSpace__searchSpaceType_PR target_ss) {
+
+  int n = 0;
+  if(bwp_Dedicated) {
+    n = bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list.count;
+  } else if(scc) {
+    n = scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->commonSearchSpaceList->list.count;
+  } else {
+    n = sib1->servingCellConfigCommon->downlinkConfigCommon.initialDownlinkBWP.pdcch_ConfigCommon->choice.setup->commonSearchSpaceList->list.count;
+  }
 
-  const int n = bwp_Dedicated ?
-    bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list.count:
-    scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->commonSearchSpaceList->list.count;
   for (int i=0;i<n;i++) {
-    NR_SearchSpace_t *ss = bwp_Dedicated ?
-      bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list.array[i]:
-      scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->commonSearchSpaceList->list.array[i];
+    NR_SearchSpace_t *ss = NULL;
+    if(bwp_Dedicated) {
+      ss = bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list.array[i];
+    } else if(scc) {
+      ss = scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->commonSearchSpaceList->list.array[i];
+    } else {
+      ss = sib1->servingCellConfigCommon->downlinkConfigCommon.initialDownlinkBWP.pdcch_ConfigCommon->choice.setup->commonSearchSpaceList->list.array[i];
+    }
     AssertFatal(ss->controlResourceSetId != NULL, "ss->controlResourceSetId is null\n");
     AssertFatal(ss->searchSpaceType != NULL, "ss->searchSpaceType is null\n");
     if (ss->searchSpaceType->present == target_ss) {
@@ -504,7 +559,8 @@ bool nr_find_nb_rb(uint16_t Qm,
   return *tbs >= bytes && *nb_rb <= nb_rb_max;
 }
 
-void nr_set_pdsch_semi_static(const NR_ServingCellConfigCommon_t *scc,
+void nr_set_pdsch_semi_static(const NR_SIB1_t *sib1,
+                              const NR_ServingCellConfigCommon_t *scc,
                               const NR_CellGroupConfig_t *secondaryCellGroup,
                               const NR_BWP_Downlink_t *bwp,
                               const NR_BWP_DownlinkDedicated_t *bwpd0,
@@ -523,7 +579,8 @@ void nr_set_pdsch_semi_static(const NR_ServingCellConfigCommon_t *scc,
     bwpd = (NR_BWP_DownlinkDedicated_t*)bwpd0;
   }
 
-  if (bwpd->pdsch_Config &&
+  if (bwpd &&
+      bwpd->pdsch_Config &&
       bwpd->pdsch_Config->choice.setup &&
       bwpd->pdsch_Config->choice.setup->mcs_Table) {
     if (*bwpd->pdsch_Config->choice.setup->mcs_Table == 0)
@@ -546,9 +603,7 @@ void nr_set_pdsch_semi_static(const NR_ServingCellConfigCommon_t *scc,
   if (ps->time_domain_allocation != tda) {
     reset_dmrs = true;
     ps->time_domain_allocation = tda;
-    const struct NR_PDSCH_TimeDomainResourceAllocationList *tdaList = bwp ?
-      bwp->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList :
-      scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList;
+    NR_PDSCH_TimeDomainResourceAllocationList_t *tdaList = get_pdsch_TimeDomainAllocationList(bwp, scc, sib1);
     AssertFatal(tda < tdaList->list.count, "time_domain_allocation %d>=%d\n", tda, tdaList->list.count);
     ps->mapping_type = tdaList->list.array[tda]->mappingType;
     if (pdsch_Config) {
@@ -563,7 +618,11 @@ void nr_set_pdsch_semi_static(const NR_ServingCellConfigCommon_t *scc,
     SLIV2SL(startSymbolAndLength, &ps->startSymbolIndex, &ps->nrOfSymbols);
   }
 
-  const long f = sched_ctrl->search_space->searchSpaceType->choice.ue_Specific->dci_Formats;
+  const long f = ((bwp || bwpd) &&
+                  sched_ctrl->search_space &&
+                  sched_ctrl->search_space->searchSpaceType->present == NR_SearchSpace__searchSpaceType_PR_ue_Specific) ?
+                 sched_ctrl->search_space->searchSpaceType->choice.ue_Specific->dci_Formats : 0;
+
   int dci_format;
   if (sched_ctrl->search_space) {
     dci_format = f ? NR_DL_DCI_FORMAT_1_1 : NR_DL_DCI_FORMAT_1_0;
@@ -592,33 +651,39 @@ void nr_set_pdsch_semi_static(const NR_ServingCellConfigCommon_t *scc,
   ps->N_PRB_DMRS = ps->numDmrsCdmGrpsNoData * (ps->dmrsConfigType == NFAPI_NR_DMRS_TYPE1 ? 6 : 4);
 
   if (reset_dmrs) {
-    ps->dl_dmrs_symb_pos = fill_dmrs_mask(bwpd ? bwpd->pdsch_Config->choice.setup : NULL, scc->dmrs_TypeA_Position, ps->nrOfSymbols, ps->startSymbolIndex, ps->mapping_type, ps->frontloaded_symb);
+    ps->dl_dmrs_symb_pos = fill_dmrs_mask(bwpd ? bwpd->pdsch_Config->choice.setup : NULL, scc ? scc->dmrs_TypeA_Position : 0, ps->nrOfSymbols, ps->startSymbolIndex, ps->mapping_type, ps->frontloaded_symb);
     ps->N_DMRS_SLOT = get_num_dmrs(ps->dl_dmrs_symb_pos);
   }
   LOG_D(NR_MAC,"bwpd0 %p, bwpd %p : Filling dmrs info, ps->N_PRB_DMRS %d, ps->dl_dmrs_symb_pos %x, ps->N_DMRS_SLOT %d\n",bwpd0,bwpd,ps->N_PRB_DMRS,ps->dl_dmrs_symb_pos,ps->N_DMRS_SLOT);
 }
 
-void nr_set_pusch_semi_static(const NR_ServingCellConfigCommon_t *scc,
+void nr_set_pusch_semi_static(const NR_SIB1_t *sib1,
+                              const NR_ServingCellConfigCommon_t *scc,
                               const NR_BWP_Uplink_t *ubwp,
                               const NR_BWP_UplinkDedicated_t *ubwpd,
                               long dci_format,
                               int tda,
                               uint8_t num_dmrs_cdm_grps_no_data,
-                              NR_pusch_semi_static_t *ps)
-{
+                              NR_pusch_semi_static_t *ps) {
   ps->dci_format = dci_format;
   ps->time_domain_allocation = tda;
 
-  const struct NR_PUSCH_TimeDomainResourceAllocationList *tdaList =
-    ubwp?
-    ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList:
-    scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList ;
+  NR_PUSCH_TimeDomainResourceAllocationList_t *tdaList = NULL;
+  if(ubwp) {
+    tdaList = ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList;
+  } else if(scc) {
+    tdaList = scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList;
+  } else {
+    tdaList = sib1->servingCellConfigCommon->uplinkConfigCommon->initialUplinkBWP.pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList;
+  }
+
   const int startSymbolAndLength = tdaList->list.array[tda]->startSymbolAndLength;
   SLIV2SL(startSymbolAndLength,
           &ps->startSymbolIndex,
           &ps->nrOfSymbols);
 
-  ps->pusch_Config = ubwp?ubwp->bwp_Dedicated->pusch_Config->choice.setup:(ubwpd ? ubwpd->pusch_Config->choice.setup : NULL);
+  ps->pusch_Config = ubwp && ubwp->bwp_Dedicated && ubwp->bwp_Dedicated->pusch_Config ?
+                    ubwp->bwp_Dedicated->pusch_Config->choice.setup : (ubwpd ? ubwpd->pusch_Config->choice.setup : NULL);
   if (ps->pusch_Config == NULL || !ps->pusch_Config->transformPrecoder)
     ps->transform_precoding = !scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg3_transformPrecoder;
   else
@@ -892,7 +957,8 @@ void nr_configure_css_dci_initial(nfapi_nr_dl_tti_pdcch_pdu_rel15_t* pdcch_pdu,
 
 }
 
-void config_uldci(const NR_BWP_Uplink_t *ubwp,
+void config_uldci(const NR_SIB1_t *sib1,
+                  const NR_BWP_Uplink_t *ubwp,
 		              const NR_BWP_UplinkDedicated_t *ubwpd,
                   const NR_ServingCellConfigCommon_t *scc,
                   const nfapi_nr_pusch_pdu_t *pusch_pdu,
@@ -903,9 +969,11 @@ void config_uldci(const NR_BWP_Uplink_t *ubwp,
                   int n_ubwp,
                   int bwp_id) {
 
-  const int bw = NRRIV2BW(ubwp ?
-			  ubwp->bwp_Common->genericParameters.locationAndBandwidth :
-			  scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
+  NR_BWP_t *genericParameters = get_ul_bwp_genericParameters((NR_BWP_Uplink_t *)ubwp,
+                                                             (NR_ServingCellConfigCommon_t *)scc,
+                                                             (NR_SIB1_t *)sib1);
+
+  const int bw = NRRIV2BW(genericParameters->locationAndBandwidth, MAX_BWP_SIZE);
 
   dci_pdu_rel15->frequency_domain_assignment.val =
       PRBalloc_to_locationandbandwidth0(pusch_pdu->rb_size, pusch_pdu->rb_start, bw);
@@ -1012,9 +1080,24 @@ void nr_configure_pdcch(nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu,
   pdcch_pdu->precoderGranularity = coreset->precoderGranularity;
 }
 
+int nr_get_pucch_resource(NR_ControlResourceSet_t *coreset,
+                          NR_BWP_Uplink_t *bwp,
+                          NR_BWP_UplinkDedicated_t *bwpd,
+                          int CCEIndex) {
+  int r_pucch = -1;
+  if(bwp == NULL && bwpd == NULL) {
+    int n_rb,rb_offset;
+    get_coreset_rballoc(coreset->frequencyDomainResources.buf,&n_rb,&rb_offset);
+    const uint16_t N_cce = n_rb * coreset->duration / NR_NB_REG_PER_CCE;
+    const int delta_PRI=0;
+    r_pucch = ((CCEIndex<<1)/N_cce)+(delta_PRI<<1);
+  }
+  return r_pucch;
+}
 
 // This function configures pucch pdu fapi structure
-void nr_configure_pucch(nfapi_nr_pucch_pdu_t* pucch_pdu,
+void nr_configure_pucch(const NR_SIB1_t *sib1,
+                        nfapi_nr_pucch_pdu_t* pucch_pdu,
                         NR_ServingCellConfigCommon_t *scc,
                         NR_CellGroupConfig_t *CellGroup,
                         NR_BWP_Uplink_t *bwp,
@@ -1042,7 +1125,13 @@ void nr_configure_pucch(nfapi_nr_pucch_pdu_t* pucch_pdu,
 
   uint16_t O_uci = O_csi + O_ack;
 
-  NR_PUSCH_Config_t *pusch_Config = bwp ? bwp->bwp_Dedicated->pusch_Config->choice.setup : bwpd->pusch_Config->choice.setup;
+  NR_PUSCH_Config_t *pusch_Config = NULL;
+  if(bwp && bwp->bwp_Dedicated && bwp->bwp_Dedicated->pusch_Config) {
+    pusch_Config = bwp->bwp_Dedicated->pusch_Config->choice.setup;
+  } else if(bwpd && bwpd->pusch_Config) {
+    pusch_Config = bwpd->pusch_Config->choice.setup;
+  }
+
   long *pusch_id = pusch_Config ? pusch_Config->dataScramblingIdentityPUSCH : NULL;
 
   if (pusch_Config && pusch_Config->dmrs_UplinkForPUSCH_MappingTypeA != NULL)
@@ -1051,9 +1140,15 @@ void nr_configure_pucch(nfapi_nr_pucch_pdu_t* pucch_pdu,
     id0 = pusch_Config->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup->transformPrecodingDisabled->scramblingID0;
   else id0 = scc->physCellId;
 
-  NR_PUCCH_ConfigCommon_t *pucch_ConfigCommon = bwp ?
-    bwp->bwp_Common->pucch_ConfigCommon->choice.setup :
-    scc->uplinkConfigCommon->initialUplinkBWP->pucch_ConfigCommon->choice.setup;
+  NR_PUCCH_ConfigCommon_t *pucch_ConfigCommon = NULL;
+  if(bwp) {
+    pucch_ConfigCommon = bwp->bwp_Common->pucch_ConfigCommon->choice.setup;
+  } else if(scc) {
+    pucch_ConfigCommon = scc->uplinkConfigCommon->initialUplinkBWP->pucch_ConfigCommon->choice.setup;
+  } else {
+    pucch_ConfigCommon =  sib1->servingCellConfigCommon->uplinkConfigCommon->initialUplinkBWP.pucch_ConfigCommon->choice.setup;
+  }
+
   // hop flags and hopping id are valid for any BWP
   switch (pucch_ConfigCommon->pucch_GroupHopping){
   case 0 :
@@ -1079,9 +1174,9 @@ void nr_configure_pucch(nfapi_nr_pucch_pdu_t* pucch_pdu,
     pucch_pdu->hopping_id = *pucch_ConfigCommon->hoppingId;
   else
     pucch_pdu->hopping_id = *scc->physCellId;
-  NR_BWP_t *genericParameters = bwp ?
-    &bwp->bwp_Common->genericParameters:
-    &scc->uplinkConfigCommon->initialUplinkBWP->genericParameters;
+
+  NR_BWP_t *genericParameters = get_ul_bwp_genericParameters(bwp,scc, sib1);
+
   pucch_pdu->bwp_size  = NRRIV2BW(genericParameters->locationAndBandwidth, MAX_BWP_SIZE);
   pucch_pdu->bwp_start = NRRIV2PRBOFFSET(genericParameters->locationAndBandwidth,MAX_BWP_SIZE);
   pucch_pdu->subcarrier_spacing = genericParameters->subcarrierSpacing;
@@ -1090,9 +1185,8 @@ void nr_configure_pucch(nfapi_nr_pucch_pdu_t* pucch_pdu,
       LOG_D(NR_MAC,"pucch_acknak: Filling dedicated configuration for PUCCH\n");
    // we have either a dedicated BWP or Dedicated PUCCH configuration on InitialBWP
       AssertFatal(bwp!=NULL || bwpd!=NULL,"We need one dedicated configuration for a BWP (neither additional or initial BWP has a dedicated configuration)\n");
-      pucch_Config = bwp ?
-	  bwp->bwp_Dedicated->pucch_Config->choice.setup:
-	  bwpd->pucch_Config->choice.setup;
+    pucch_Config = bwp && bwp->bwp_Dedicated && bwp->bwp_Dedicated->pucch_Config ?
+                   bwp->bwp_Dedicated->pucch_Config->choice.setup : bwpd->pucch_Config->choice.setup;
 
       AssertFatal(pucch_Config->resourceSetToAddModList!=NULL,
 		    "PUCCH resourceSetToAddModList is null\n");
@@ -1387,12 +1481,13 @@ void fill_dci_pdu_rel15(const NR_ServingCellConfigCommon_t *scc,
                         int dci_format,
                         int rnti_type,
                         int N_RB,
-                        int bwp_id) {
+                        int bwp_id,
+                        uint16_t cset0_bwp_size) {
   uint8_t fsize = 0, pos = 0;
 
   uint64_t *dci_pdu = (uint64_t *)pdcch_dci_pdu->Payload;
   *dci_pdu=0;
-  int dci_size = nr_dci_size(scc->downlinkConfigCommon->initialDownlinkBWP,scc->uplinkConfigCommon->initialUplinkBWP, CellGroup, dci_pdu_rel15, dci_format, rnti_type, N_RB, bwp_id);
+  int dci_size = nr_dci_size(scc->downlinkConfigCommon->initialDownlinkBWP,scc->uplinkConfigCommon->initialUplinkBWP, CellGroup, dci_pdu_rel15, dci_format, rnti_type, N_RB, bwp_id, cset0_bwp_size);
   pdcch_dci_pdu->PayloadSizeBits = dci_size;
   AssertFatal(dci_size <= 64, "DCI sizes above 64 bits not yet supported");
   if (dci_format == NR_DL_DCI_FORMAT_1_1 || dci_format == NR_UL_DCI_FORMAT_0_1)
@@ -1736,7 +1831,7 @@ void fill_dci_pdu_rel15(const NR_ServingCellConfigCommon_t *scc,
       pos+=4;
       *dci_pdu |= ((uint64_t)dci_pdu_rel15->harq_pid & 0xf) << (dci_size - pos);
       // Padding bits
-      for (int a = pos; a < 32; a++)
+      for (int a = pos; a < dci_size; a++)
         *dci_pdu |= ((uint64_t)dci_pdu_rel15->padding & 1) << (dci_size - pos++);
       // UL/SUL indicator – 1 bit
       /* commented for now (RK): need to get this from BWP descriptor
@@ -2182,8 +2277,9 @@ int get_ul_bwp_id(const NR_ServingCellConfig_t *servingCellConfig)
 //------------------------------------------------------------------------------
 int add_new_nr_ue(module_id_t mod_idP, rnti_t rntiP, NR_CellGroupConfig_t *CellGroup)
 {
-  NR_ServingCellConfigCommon_t *scc = RC.nrmac[mod_idP]->common_channels[0].ServingCellConfigCommon;
-  NR_UE_info_t *UE_info = &RC.nrmac[mod_idP]->UE_info;
+  gNB_MAC_INST *nr_mac = RC.nrmac[mod_idP];
+  NR_ServingCellConfigCommon_t *scc = nr_mac->common_channels[0].ServingCellConfigCommon;
+  NR_UE_info_t *UE_info = &nr_mac->UE_info;
   LOG_I(NR_MAC, "[gNB %d] Adding UE with rnti 0x%04x (num_UEs %d)\n",
         mod_idP,
         rntiP,
@@ -2208,7 +2304,7 @@ int add_new_nr_ue(module_id_t mod_idP, rnti_t rntiP, NR_CellGroupConfig_t *CellG
       compute_csi_bitlen (CellGroup->spCellConfig->spCellConfigDedicated->csi_MeasConfig->choice.setup, UE_info, UE_id, mod_idP);
     NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
     memset(sched_ctrl, 0, sizeof(*sched_ctrl));
-    sched_ctrl->set_mcs = TRUE;
+    sched_ctrl->set_mcs = true;
     sched_ctrl->ta_frame = 0;
     sched_ctrl->ta_update = 31;
     sched_ctrl->ta_apply = false;
@@ -2224,7 +2320,7 @@ int add_new_nr_ue(module_id_t mod_idP, rnti_t rntiP, NR_CellGroupConfig_t *CellG
     /* set illegal time domain allocation to force recomputation of all fields */
     sched_ctrl->pdsch_semi_static.time_domain_allocation = -1;
     sched_ctrl->pusch_semi_static.time_domain_allocation = -1;
-    const NR_ServingCellConfig_t *servingCellConfig = CellGroup ? CellGroup->spCellConfig->spCellConfigDedicated : NULL;
+    const NR_ServingCellConfig_t *servingCellConfig = CellGroup && CellGroup->spCellConfig ? CellGroup->spCellConfig->spCellConfigDedicated : NULL;
 
     /* Set default BWPs */
     const struct NR_ServingCellConfig__downlinkBWP_ToAddModList *bwpList = servingCellConfig ? servingCellConfig->downlinkBWP_ToAddModList : NULL;
@@ -2238,7 +2334,9 @@ int add_new_nr_ue(module_id_t mod_idP, rnti_t rntiP, NR_CellGroupConfig_t *CellG
       &sched_ctrl->active_bwp->bwp_Common->genericParameters:
       &scc->uplinkConfigCommon->initialUplinkBWP->genericParameters;
     const int target_ss = sched_ctrl->active_bwp ? NR_SearchSpace__searchSpaceType_PR_ue_Specific : NR_SearchSpace__searchSpaceType_PR_common;
-    sched_ctrl->search_space = get_searchspace(scc,
+    const NR_SIB1_t *sib1 = nr_mac->common_channels[0].sib1 ? nr_mac->common_channels[0].sib1->message.choice.c1->choice.systemInformationBlockType1 : NULL;
+    sched_ctrl->search_space = get_searchspace(sib1,
+                                               scc,
                                                sched_ctrl->active_bwp ? sched_ctrl->active_bwp->bwp_Dedicated : NULL,
                                                target_ss);
     sched_ctrl->coreset = get_coreset(mod_idP, scc,
@@ -2433,7 +2531,7 @@ void get_pdsch_to_harq_feedback(int Mod_idP,
     bwpd = CellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[bwp_id-1]->bwp_Dedicated;
     ubwpd = CellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList->list.array[bwp_id-1]->bwp_Dedicated;
   }
-  else if (CellGroup) { // this is an initialBWP
+  else if (CellGroup && CellGroup->spCellConfig && CellGroup->spCellConfig->spCellConfigDedicated) { // this is an initialBWP
     AssertFatal((bwpd=CellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP)!=NULL,
                 "CellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP is null\n");
     AssertFatal((ubwpd=CellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP)!=NULL,
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 cedc78097e0622a560931af53bd10e6c4d4a4389..e21d1e50f7ccd15823068bf15470ca9cbe781ad8 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c
@@ -44,7 +44,8 @@ void nr_fill_nfapi_pucch(module_id_t mod_id,
                          const NR_sched_pucch_t *pucch,
                          int UE_id)
 {
-  NR_UE_info_t *UE_info = &RC.nrmac[mod_id]->UE_info;
+  gNB_MAC_INST *nr_mac = RC.nrmac[mod_id];
+  NR_UE_info_t *UE_info = &nr_mac->UE_info;
 
   nfapi_nr_ul_tti_request_t *future_ul_tti_req =
       &RC.nrmac[mod_id]->UL_tti_req_ahead[0][pucch->ul_slot];
@@ -55,6 +56,9 @@ void nr_fill_nfapi_pucch(module_id_t mod_id,
               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;
@@ -76,13 +80,16 @@ void nr_fill_nfapi_pucch(module_id_t mod_id,
   NR_ServingCellConfigCommon_t *scc = RC.nrmac[mod_id]->common_channels->ServingCellConfigCommon;
   NR_CellGroupConfig_t *cg=UE_info->CellGroup[UE_id];
 
-  NR_BWP_UplinkDedicated_t *ubwpd;
-  ubwpd = cg ? cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP:NULL;
+  NR_BWP_UplinkDedicated_t *ubwpd = cg && cg->spCellConfig && cg->spCellConfig->spCellConfigDedicated &&
+                                    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",
         frame,slot,ubwpd,pucch->r_pucch,pucch->frame,pucch->ul_slot);
 
-  nr_configure_pucch(pucch_pdu,
+  const NR_SIB1_t *sib1 = nr_mac->common_channels[0].sib1 ? nr_mac->common_channels[0].sib1->message.choice.c1->choice.systemInformationBlockType1 : NULL;
+  nr_configure_pucch(sib1,
+                     pucch_pdu,
                      scc,
                      UE_info->CellGroup[UE_id],
                      UE_info->UE_sched_ctrl[UE_id].active_ubwp,
@@ -742,9 +749,11 @@ void nr_csi_meas_reporting(int Mod_idP,
       curr_pucch->csi_bits +=
           nr_get_csi_bitlen(Mod_idP,UE_id,csi_report_id);
 
-      NR_BWP_t *genericParameters = sched_ctrl->active_ubwp ?
-        &sched_ctrl->active_ubwp->bwp_Common->genericParameters:
-        &scc->uplinkConfigCommon->initialUplinkBWP->genericParameters;
+      const NR_SIB1_t *sib1 = RC.nrmac[Mod_idP]->common_channels[0].sib1 ? RC.nrmac[Mod_idP]->common_channels[0].sib1->message.choice.c1->choice.systemInformationBlockType1 : NULL;
+      NR_BWP_t *genericParameters = get_ul_bwp_genericParameters(sched_ctrl->active_ubwp,
+                                                                 scc,
+                                                                 sib1);
+
       int bwp_start = NRRIV2PRBOFFSET(genericParameters->locationAndBandwidth,MAX_BWP_SIZE);
 
       // going through the list of PUCCH resources to find the one indexed by resource_id
diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c
index c4582918dc4a3bb98967d39ecd5eebe8cfd2b422..5d1ddcb8ef3b894486bad3d9898d15a1f166101f 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c
@@ -39,16 +39,11 @@
 
 int get_dci_format(NR_UE_sched_ctrl_t *sched_ctrl) {
 
-    const long f = sched_ctrl->search_space->searchSpaceType->choice.ue_Specific->dci_Formats;
-    int dci_format;
-    if (sched_ctrl->search_space) {
-       dci_format = f ? NR_UL_DCI_FORMAT_0_1 : NR_UL_DCI_FORMAT_0_0;
-    }
-    else {
-       dci_format = NR_UL_DCI_FORMAT_0_0;
-    }
+  int dci_format = sched_ctrl->search_space && sched_ctrl->search_space->searchSpaceType &&
+                   sched_ctrl->search_space->searchSpaceType->present == NR_SearchSpace__searchSpaceType_PR_ue_Specific ?
+                   NR_UL_DCI_FORMAT_0_1 : NR_UL_DCI_FORMAT_0_0;
 
-    return(dci_format);
+  return(dci_format);
 }
 
 void calculate_preferred_ul_tda(module_id_t module_id, const NR_BWP_Uplink_t *ubwp)
@@ -62,9 +57,22 @@ void calculate_preferred_ul_tda(module_id_t module_id, const NR_BWP_Uplink_t *ub
   NR_ServingCellConfigCommon_t *scc = nrmac->common_channels->ServingCellConfigCommon;
   lte_frame_type_t frame_type = nrmac->common_channels->frame_type;
   const int n = nr_slots_per_frame[*scc->ssbSubcarrierSpacing];
-  const int mu = scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.subcarrierSpacing;
-  const NR_TDD_UL_DL_Pattern_t *tdd =
-      scc->tdd_UL_DL_ConfigurationCommon ? &scc->tdd_UL_DL_ConfigurationCommon->pattern1 : NULL;
+
+  NR_ServingCellConfigCommonSIB_t *scc_sib1 = get_softmodem_params()->sa ?
+      RC.nrmac[module_id]->common_channels[0].sib1->message.choice.c1->choice.systemInformationBlockType1->servingCellConfigCommon : NULL;
+
+  AssertFatal(scc!=NULL || scc_sib1!=NULL,"We need one serving cell config common\n");
+
+  const int mu = scc ? scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.subcarrierSpacing :
+                 scc_sib1->uplinkConfigCommon->initialUplinkBWP.genericParameters.subcarrierSpacing;
+
+  NR_TDD_UL_DL_Pattern_t *tdd = NULL;
+  if (scc && scc->tdd_UL_DL_ConfigurationCommon) {
+    tdd = &scc->tdd_UL_DL_ConfigurationCommon->pattern1;
+  } else if (scc_sib1 && scc_sib1->tdd_UL_DL_ConfigurationCommon) {
+    tdd = &scc_sib1->tdd_UL_DL_ConfigurationCommon->pattern1;
+  }
+
   /* Uplink symbols are at the end of the slot */
   int symb_ulMixed = 0;
   int nr_mix_slots = 0;
@@ -118,7 +126,7 @@ void calculate_preferred_ul_tda(module_id_t module_id, const NR_BWP_Uplink_t *ub
   /* check that TDA index 1 fits into UL slot and does not overlap with PUCCH */
   const struct NR_PUSCH_TimeDomainResourceAllocationList *tdaList = ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList;
   const NR_PUSCH_TimeDomainResourceAllocation_t *tdaP_UL = tdaList->list.array[0];
-  const int k2 = get_K2(scc, (NR_BWP_Uplink_t*)ubwp,0, mu);
+  const int k2 = get_K2(scc, scc_sib1, (NR_BWP_Uplink_t*)ubwp,0, mu);
   int start, len;
   SLIV2SL(tdaP_UL->startSymbolAndLength, &start, &len);
   const uint16_t symb_tda = ((1 << len) - 1) << start;
@@ -131,10 +139,10 @@ void calculate_preferred_ul_tda(module_id_t module_id, const NR_BWP_Uplink_t *ub
   int tdaMi = -1;
   if (nr_mix_slots>0) {
     const NR_PUSCH_TimeDomainResourceAllocation_t *tdaP_Mi = tdaList->list.array[1];
-    AssertFatal(k2 == get_K2(scc, (NR_BWP_Uplink_t*)ubwp, 1, mu),
+    AssertFatal(k2 == get_K2(scc, scc_sib1, (NR_BWP_Uplink_t*)ubwp, 1, mu),
                 "scheduler cannot handle different k2 for UL slot (%d) and UL Mixed slot (%ld)\n",
                 k2,
-                get_K2(scc, (NR_BWP_Uplink_t*)ubwp, 1, mu));
+                get_K2(scc, scc_sib1, (NR_BWP_Uplink_t*)ubwp, 1, mu));
     SLIV2SL(tdaP_Mi->startSymbolAndLength, &start, &len);
     const uint16_t symb_tda_mi = ((1 << len) - 1) << start;
     // check whether PUCCH and TDA overlap: then, we cannot use it. Also, check
@@ -271,9 +279,18 @@ 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
+                /* 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 (pdu_len < sizeof(NR_MAC_SUBHEADER_SHORT))
+                        return 0;
         	mac_ce_len |= (uint16_t)((NR_MAC_SUBHEADER_SHORT *)pduP)->L;
         	mac_subheader_len = 2;
         	if(((NR_MAC_SUBHEADER_SHORT *)pduP)->F){
+                        if (pdu_len < sizeof(NR_MAC_SUBHEADER_LONG))
+                                return 0;
         		mac_ce_len |= (uint16_t)(((NR_MAC_SUBHEADER_LONG *)pduP)->L2)<<8;
         		mac_subheader_len = 3;
         	}
@@ -350,9 +367,13 @@ 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
+                if (pdu_len < sizeof(NR_MAC_SUBHEADER_SHORT))
+                        return 0;
         	mac_ce_len |= (uint16_t)((NR_MAC_SUBHEADER_SHORT *)pduP)->L;
         	mac_subheader_len = 2;
         	if(((NR_MAC_SUBHEADER_SHORT *)pduP)->F){
+                        if (pdu_len < sizeof(NR_MAC_SUBHEADER_LONG))
+                                return 0;
         		mac_ce_len |= (uint16_t)(((NR_MAC_SUBHEADER_LONG *)pduP)->L2)<<8;
         		mac_subheader_len = 3;
         	}
@@ -362,9 +383,13 @@ int nr_process_mac_pdu(module_id_t module_idP,
         case UL_SCH_LCID_MULTI_ENTRY_PHR_4_OCT:
         	//38.321 section 6.1.3.9
         	//  varialbe length
+                if (pdu_len < sizeof(NR_MAC_SUBHEADER_SHORT))
+                        return 0;
         	mac_ce_len |= (uint16_t)((NR_MAC_SUBHEADER_SHORT *)pduP)->L;
         	mac_subheader_len = 2;
         	if(((NR_MAC_SUBHEADER_SHORT *)pduP)->F){
+                        if (pdu_len < sizeof(NR_MAC_SUBHEADER_LONG))
+                                return 0;
         		mac_ce_len |= (uint16_t)(((NR_MAC_SUBHEADER_LONG *)pduP)->L2)<<8;
         		mac_subheader_len = 3;
         	}
@@ -378,8 +403,12 @@ int nr_process_mac_pdu(module_id_t module_idP,
 
         case UL_SCH_LCID_SRB1:
         case UL_SCH_LCID_SRB2:
+          if (pdu_len < sizeof(NR_MAC_SUBHEADER_SHORT))
+                return 0;
           if(((NR_MAC_SUBHEADER_SHORT *)pduP)->F){
             //mac_sdu_len |= (uint16_t)(((NR_MAC_SUBHEADER_LONG *)pduP)->L2)<<8;
+            if (pdu_len < sizeof(NR_MAC_SUBHEADER_LONG))
+                  return 0;
             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);
@@ -463,8 +492,12 @@ int nr_process_mac_pdu(module_id_t module_idP,
 
         case UL_SCH_LCID_DTCH:
           //  check if LCID is valid at current time.
+          if (pdu_len < sizeof(NR_MAC_SUBHEADER_SHORT))
+                return 0;
           if (((NR_MAC_SUBHEADER_SHORT *)pduP)->F) {
             // mac_sdu_len |= (uint16_t)(((NR_MAC_SUBHEADER_LONG *)pduP)->L2)<<8;
+            if (pdu_len < sizeof(NR_MAC_SUBHEADER_LONG))
+                  return 0;
             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);
@@ -897,11 +930,21 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP,
   }
 }
 
-long get_K2(NR_ServingCellConfigCommon_t *scc,NR_BWP_Uplink_t *ubwp, int time_domain_assignment, int mu) {
-  DevAssert(scc);
-  const NR_PUSCH_TimeDomainResourceAllocation_t *tda_list = ubwp ?
-    ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[time_domain_assignment]:
-    scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[time_domain_assignment];
+long get_K2(NR_ServingCellConfigCommon_t *scc,
+            NR_ServingCellConfigCommonSIB_t *scc_sib1,
+            NR_BWP_Uplink_t *ubwp,
+            int time_domain_assignment,
+            int mu) {
+
+  NR_PUSCH_TimeDomainResourceAllocation_t *tda_list = NULL;
+  if(ubwp) {
+    tda_list = ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[time_domain_assignment];
+  } else if(scc) {
+    tda_list = scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[time_domain_assignment];
+  } else if(scc_sib1) {
+    tda_list = scc_sib1->uplinkConfigCommon->initialUplinkBWP.pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[time_domain_assignment];
+  }
+
   if (tda_list->k2)
     return *tda_list->k2;
   else if (mu < 2)
@@ -964,13 +1007,22 @@ bool allocate_ul_retransmission(module_id_t module_id,
                                 int harq_pid)
 {
   const int CC_id = 0;
-  const NR_ServingCellConfigCommon_t *scc = RC.nrmac[module_id]->common_channels[CC_id].ServingCellConfigCommon;
-  NR_UE_info_t *UE_info = &RC.nrmac[module_id]->UE_info;
+  gNB_MAC_INST *nr_mac = RC.nrmac[module_id];
+  const NR_ServingCellConfigCommon_t *scc = nr_mac->common_channels[CC_id].ServingCellConfigCommon;
+  NR_UE_info_t *UE_info = &nr_mac->UE_info;
   NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
   NR_sched_pusch_t *retInfo = &sched_ctrl->ul_harq_processes[harq_pid].sched_pusch;
   NR_CellGroupConfig_t *cg = UE_info->CellGroup[UE_id];
-  NR_BWP_UplinkDedicated_t *ubwpd= cg ? cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP:NULL;
-  NR_BWP_t *genericParameters = sched_ctrl->active_ubwp ? &sched_ctrl->active_ubwp->bwp_Common->genericParameters : &scc->uplinkConfigCommon->initialUplinkBWP->genericParameters;
+
+  NR_BWP_UplinkDedicated_t *ubwpd = cg && cg->spCellConfig && cg->spCellConfig->spCellConfigDedicated &&
+                                    cg->spCellConfig->spCellConfigDedicated->uplinkConfig ?
+                                    cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP : NULL;
+
+  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_ul_bwp_genericParameters(sched_ctrl->active_ubwp,
+                                                             (NR_ServingCellConfigCommon_t *)scc,
+                                                             sib1);
+
   int rbStart = 0; // wrt BWP start
   const uint16_t bwpSize = NRRIV2BW(genericParameters->locationAndBandwidth, MAX_BWP_SIZE);
 
@@ -989,7 +1041,14 @@ bool allocate_ul_retransmission(module_id_t module_id,
         || ps->dci_format != dci_format
         || ps->num_dmrs_cdm_grps_no_data != num_dmrs_cdm_grps_no_data
         || sched_ctrl->update_pusch_ps) {
-      nr_set_pusch_semi_static(scc, sched_ctrl->active_ubwp, ubwpd, dci_format, tda, num_dmrs_cdm_grps_no_data, ps);
+      nr_set_pusch_semi_static(sib1,
+                               scc,
+                               sched_ctrl->active_ubwp,
+                               ubwpd,
+                               dci_format,
+                               tda,
+                               num_dmrs_cdm_grps_no_data,
+                               ps);
       sched_ctrl->update_pusch_ps = false;
     }
 
@@ -1005,7 +1064,14 @@ bool allocate_ul_retransmission(module_id_t module_id,
   } else {
     NR_pusch_semi_static_t temp_ps;
     int dci_format = get_dci_format(sched_ctrl);
-    nr_set_pusch_semi_static(scc, sched_ctrl->active_ubwp,ubwpd, dci_format, tda, num_dmrs_cdm_grps_no_data, &temp_ps);
+    nr_set_pusch_semi_static(sib1,
+                             scc,
+                             sched_ctrl->active_ubwp,
+                             ubwpd,
+                             dci_format,
+                             tda,
+                             num_dmrs_cdm_grps_no_data,
+                             &temp_ps);
     /* the retransmission will use a different time domain allocation, check
      * that we have enough resources */
     while (rbStart < bwpSize &&
@@ -1127,6 +1193,7 @@ void pf_ul(module_id_t module_id,
   gNB_MAC_INST *nrmac = RC.nrmac[module_id];
   NR_ServingCellConfigCommon_t *scc = nrmac->common_channels[CC_id].ServingCellConfigCommon;
   NR_UE_info_t *UE_info = &nrmac->UE_info;
+  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;
   const int min_rb = 5;
   float coeff_ue[MAX_MOBILES_PER_GNB];
   // UEs that could be scheduled
@@ -1140,10 +1207,16 @@ void pf_ul(module_id_t module_id,
 
     LOG_D(NR_MAC,"pf_ul: preparing UL scheduling for UE %d\n",UE_id);
     NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
-    NR_BWP_t *genericParameters = sched_ctrl->active_ubwp ? &sched_ctrl->active_ubwp->bwp_Common->genericParameters : &scc->uplinkConfigCommon->initialUplinkBWP->genericParameters;
+
+    NR_BWP_t *genericParameters = get_ul_bwp_genericParameters(sched_ctrl->active_ubwp,
+                                                               scc,
+                                                               sib1);
+
     int rbStart = 0; // wrt BWP start
     NR_CellGroupConfig_t *cg = UE_info->CellGroup[UE_id];
-    NR_BWP_UplinkDedicated_t *ubwpd= cg ? cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP : NULL;
+    NR_BWP_UplinkDedicated_t *ubwpd = cg && cg->spCellConfig && cg->spCellConfig->spCellConfigDedicated &&
+                                      cg->spCellConfig->spCellConfigDedicated->uplinkConfig ?
+                                      cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP : NULL;
 
     const uint16_t bwpSize = NRRIV2BW(genericParameters->locationAndBandwidth, MAX_BWP_SIZE);
     NR_sched_pusch_t *sched_pusch = &sched_ctrl->sched_pusch;
@@ -1226,7 +1299,14 @@ void pf_ul(module_id_t module_id,
           || ps->dci_format != dci_format
           || ps->num_dmrs_cdm_grps_no_data != num_dmrs_cdm_grps_no_data
           || sched_ctrl->update_pusch_ps) {
-        nr_set_pusch_semi_static(scc, sched_ctrl->active_ubwp, ubwpd, dci_format, tda, num_dmrs_cdm_grps_no_data, ps);
+        nr_set_pusch_semi_static(sib1,
+                                 scc,
+                                 sched_ctrl->active_ubwp,
+                                 ubwpd,
+                                 dci_format,
+                                 tda,
+                                 num_dmrs_cdm_grps_no_data,
+                                 ps);
         sched_ctrl->update_pusch_ps = false;
       }
 
@@ -1333,8 +1413,14 @@ void pf_ul(module_id_t module_id,
     AssertFatal(max_num_ue >= 0, "Illegal max_num_ue %d\n", max_num_ue);
 
     NR_CellGroupConfig_t *cg = UE_info->CellGroup[UE_id];
-    NR_BWP_UplinkDedicated_t *ubwpd= cg ? cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP:NULL;
-    NR_BWP_t *genericParameters = sched_ctrl->active_ubwp ? &sched_ctrl->active_ubwp->bwp_Common->genericParameters : &scc->uplinkConfigCommon->initialUplinkBWP->genericParameters;
+    NR_BWP_UplinkDedicated_t *ubwpd = cg && cg->spCellConfig && cg->spCellConfig->spCellConfigDedicated
+                                      && cg->spCellConfig->spCellConfigDedicated->uplinkConfig ?
+                                      cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP : NULL;
+
+    NR_BWP_t *genericParameters = get_ul_bwp_genericParameters(sched_ctrl->active_ubwp,
+                                                               scc,
+                                                               sib1);
+
     int rbStart = sched_ctrl->active_ubwp ? NRRIV2PRBOFFSET(genericParameters->locationAndBandwidth, MAX_BWP_SIZE) : 0;
     const uint16_t bwpSize = NRRIV2BW(genericParameters->locationAndBandwidth, MAX_BWP_SIZE);
     NR_sched_pusch_t *sched_pusch = &sched_ctrl->sched_pusch;
@@ -1351,7 +1437,14 @@ void pf_ul(module_id_t module_id,
         || ps->dci_format != dci_format
         || ps->num_dmrs_cdm_grps_no_data != num_dmrs_cdm_grps_no_data
         || sched_ctrl->update_pusch_ps) {
-      nr_set_pusch_semi_static(scc, sched_ctrl->active_ubwp, ubwpd, dci_format, tda, num_dmrs_cdm_grps_no_data, ps);
+      nr_set_pusch_semi_static(sib1,
+                               scc,
+                               sched_ctrl->active_ubwp,
+                               ubwpd,
+                               dci_format,
+                               tda,
+                               num_dmrs_cdm_grps_no_data,
+                               ps);
       sched_ctrl->update_pusch_ps = false;
     }
     update_ul_ue_R_Qm(sched_pusch, ps);
@@ -1412,7 +1505,14 @@ bool nr_fr1_ulsch_preprocessor(module_id_t module_id, frame_t frame, sub_frame_t
   gNB_MAC_INST *nr_mac = RC.nrmac[module_id];
   NR_COMMON_channels_t *cc = nr_mac->common_channels;
   NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon;
-  const int mu = scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.subcarrierSpacing;
+  const NR_SIB1_t *sib1 = nr_mac->common_channels[0].sib1 ? nr_mac->common_channels[0].sib1->message.choice.c1->choice.systemInformationBlockType1 : NULL;
+  NR_ServingCellConfigCommonSIB_t *scc_sib1 = sib1 ? sib1->servingCellConfigCommon : NULL;
+
+  AssertFatal(scc!=NULL || scc_sib1!=NULL,"We need one serving cell config common\n");
+
+  const int mu = scc ? scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.subcarrierSpacing :
+                 scc_sib1->uplinkConfigCommon->initialUplinkBWP.genericParameters.subcarrierSpacing;
+
   NR_UE_info_t *UE_info = &nr_mac->UE_info;
 
   if (UE_info->num_UEs == 0)
@@ -1429,7 +1529,7 @@ bool nr_fr1_ulsch_preprocessor(module_id_t module_id, frame_t frame, sub_frame_t
   const int tda = sched_ctrl->active_ubwp ? nr_mac->preferred_ul_tda[sched_ctrl->active_ubwp->bwp_Id][slot] : 0;
   if (tda < 0)
     return false;
-  int K2 = get_K2(scc, sched_ctrl->active_ubwp, tda, mu);
+  int K2 = get_K2(scc, scc_sib1, sched_ctrl->active_ubwp, tda, mu);
   const int sched_frame = frame + (slot + K2 >= nr_slots_per_frame[mu]);
   const int sched_slot = (slot + K2) % nr_slots_per_frame[mu];
 
@@ -1461,8 +1561,8 @@ bool nr_fr1_ulsch_preprocessor(module_id_t module_id, frame_t frame, sub_frame_t
   sched_ctrl->sched_pusch.frame = sched_frame;
   for (UE_id = UE_info->list.next[UE_id]; 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];
-    AssertFatal(K2 == get_K2(scc,sched_ctrl->active_ubwp, tda, mu),
-                "Different K2, %d(UE%d) != %ld(UE%d)\n", K2, 0, get_K2(scc,sched_ctrl->active_ubwp, tda, mu), UE_id);
+    AssertFatal(K2 == get_K2(scc,scc_sib1,sched_ctrl->active_ubwp, tda, mu),
+                "Different K2, %d(UE%d) != %ld(UE%d)\n", K2, 0, get_K2(scc,scc_sib1,sched_ctrl->active_ubwp, tda, mu), UE_id);
     sched_ctrl->sched_pusch.slot = sched_slot;
     sched_ctrl->sched_pusch.frame = sched_frame;
   }
@@ -1472,17 +1572,24 @@ bool nr_fr1_ulsch_preprocessor(module_id_t module_id, frame_t frame, sub_frame_t
    * Calculate largest contiguous RBs */
   uint16_t *vrb_map_UL =
       &RC.nrmac[module_id]->common_channels[CC_id].vrb_map_UL[sched_slot * MAX_BWP_SIZE];
-  const uint16_t bwpSize = NRRIV2BW(sched_ctrl->active_ubwp ?
-                                    sched_ctrl->active_ubwp->bwp_Common->genericParameters.locationAndBandwidth:
-                                    scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.locationAndBandwidth,
-                                    MAX_BWP_SIZE);
-  const uint16_t bwpStart = NRRIV2PRBOFFSET(sched_ctrl->active_ubwp ?
-                                            sched_ctrl->active_ubwp->bwp_Common->genericParameters.locationAndBandwidth:
-                                            scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.locationAndBandwidth,
-                                            MAX_BWP_SIZE);
-  const struct NR_PUSCH_TimeDomainResourceAllocationList *tdaList = sched_ctrl->active_ubwp ?
-    sched_ctrl->active_ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList:
-    scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList;
+
+  NR_BWP_t *genericParameters = get_ul_bwp_genericParameters(sched_ctrl->active_ubwp,
+                                                             scc,
+                                                             sib1);
+
+  const uint16_t bwpSize = NRRIV2BW(genericParameters->locationAndBandwidth,MAX_BWP_SIZE);
+  const uint16_t bwpStart = NRRIV2PRBOFFSET(genericParameters->locationAndBandwidth,MAX_BWP_SIZE);
+
+  NR_PUSCH_TimeDomainResourceAllocationList_t *tdaList = NULL;
+  if (sched_ctrl->active_ubwp) {
+    tdaList = sched_ctrl->active_ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList;
+  } else if (scc) {
+    tdaList = scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList;
+  } else {
+    NR_SIB1_t *sib1 = RC.nrmac[module_id]->common_channels[0].sib1->message.choice.c1->choice.systemInformationBlockType1;
+    tdaList = sib1->servingCellConfigCommon->uplinkConfigCommon->initialUplinkBWP.pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList;
+  }
+
   const int startSymbolAndLength = tdaList->list.array[tda]->startSymbolAndLength;
   int startSymbolIndex, nrOfSymbols;
   SLIV2SL(startSymbolAndLength, &startSymbolIndex, &nrOfSymbols);
@@ -1577,13 +1684,18 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot)
 
   NR_ServingCellConfigCommon_t *scc = RC.nrmac[module_id]->common_channels[0].ServingCellConfigCommon;
   NR_UE_info_t *UE_info = &RC.nrmac[module_id]->UE_info;
+  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;
   const 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_CellGroupConfig_t *cg = UE_info->CellGroup[UE_id];
-    NR_BWP_UplinkDedicated_t *ubwpd= cg ? cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP:NULL;
+
+    NR_BWP_UplinkDedicated_t *ubwpd = cg && cg->spCellConfig && cg->spCellConfig->spCellConfigDedicated &&
+                                      cg->spCellConfig->spCellConfigDedicated->uplinkConfig ?
+                                      cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP : NULL;
+
     UE_info->mac_stats[UE_id].ulsch_current_bytes = 0;
 
     /* dynamic PUSCH values (RB alloc, MCS, hence R, Qm, TBS) that change in
@@ -1690,6 +1802,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;
@@ -1704,7 +1819,10 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot)
     pusch_pdu->handle = 0; //not yet used
 
     /* FAPI: BWP */
-    NR_BWP_t *genericParameters = sched_ctrl->active_ubwp ? &sched_ctrl->active_ubwp->bwp_Common->genericParameters:&scc->uplinkConfigCommon->initialUplinkBWP->genericParameters;
+    NR_BWP_t *genericParameters = get_ul_bwp_genericParameters(sched_ctrl->active_ubwp,
+                                                               scc,
+                                                               sib1);
+
     pusch_pdu->bwp_size  = NRRIV2BW(genericParameters->locationAndBandwidth, MAX_BWP_SIZE);
     pusch_pdu->bwp_start = NRRIV2PRBOFFSET(genericParameters->locationAndBandwidth, MAX_BWP_SIZE);
     pusch_pdu->subcarrier_spacing = genericParameters->subcarrierSpacing;
@@ -1846,10 +1964,16 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot)
     dci_pdu_rel15_t uldci_payload;
     memset(&uldci_payload, 0, sizeof(uldci_payload));
     int n_ubwp=1;
-    if (cg->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList)
-        n_ubwp = cg->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList->list.count;
+    if (cg &&
+        cg->spCellConfig &&
+        cg->spCellConfig->spCellConfigDedicated &&
+        cg->spCellConfig->spCellConfigDedicated->uplinkConfig &&
+        cg->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList) {
+      n_ubwp = cg->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList->list.count;
+    }
 
-    config_uldci(sched_ctrl->active_ubwp,
+    config_uldci(sib1,
+                 sched_ctrl->active_ubwp,
                  ubwpd,
                  scc,
                  pusch_pdu,
@@ -1866,7 +1990,8 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot)
                        ps->dci_format,
                        rnti_types[0],
                        pusch_pdu->bwp_size,
-                       bwpid);
+                       bwpid,
+                       nr_mac->cset0_bwp_size);
 
     memset(sched_pusch, 0, sizeof(*sched_pusch));
   }
diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h
index 2aacacb74f9525486480c77e88b4984ebdbd86c2..a0254c823381ff2039c805d7147090a926fa1a7b 100644
--- a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h
+++ b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h
@@ -38,21 +38,23 @@ void set_cset_offset(uint16_t);
 
 void mac_top_init_gNB(void);
 
+void process_CellGroup(NR_CellGroupConfig_t *CellGroup, NR_UE_sched_ctrl_t *sched_ctrl);
+
 void config_common(int Mod_idP,
                    int ssb_SubcarrierOffset,
-                   int pdsch_AntennaPorts,
+                   rrc_pdsch_AntennaPorts_t pdsch_AntennaPorts,
                    int pusch_AntennaPorts,
-		   NR_ServingCellConfigCommon_t *scc
-		   );
+                   NR_ServingCellConfigCommon_t *scc);
 
 int rrc_mac_config_req_gNB(module_id_t Mod_idP,
                            int ssb_SubcarrierOffset,
-                           int pdsch_AntennaPorts,
+                           rrc_pdsch_AntennaPorts_t pdsch_AntennaPorts,
                            int pusch_AntennaPorts,
                            int sib1_tda,
                            int minRXTXTIMEpdsch,
                            NR_ServingCellConfigCommon_t *scc,
                            NR_BCCH_BCH_Message_t *mib,
+                           NR_BCCH_DL_SCH_Message_t *sib1,
                            int add_ue,
                            uint32_t rnti,
                            NR_CellGroupConfig_t *CellGroup);
@@ -176,7 +178,8 @@ void handle_nr_uci_pucch_2_3_4(module_id_t mod_id,
                                const nfapi_nr_uci_pucch_pdu_format_2_3_4_t *uci_234);
 
 
-void config_uldci(const NR_BWP_Uplink_t *ubwp,
+void config_uldci(const NR_SIB1_t *sib1,
+                  const NR_BWP_Uplink_t *ubwp,
                   const NR_BWP_UplinkDedicated_t *ubwpd,
                   const NR_ServingCellConfigCommon_t *scc,
                   const nfapi_nr_pusch_pdu_t *pusch_pdu,
@@ -235,7 +238,13 @@ int nr_is_dci_opportunity(nfapi_nr_search_space_t search_space,
                           nfapi_nr_config_request_scf_t cfg);
 */
 
-void nr_configure_pucch(nfapi_nr_pucch_pdu_t* pucch_pdu,
+int nr_get_pucch_resource(NR_ControlResourceSet_t *coreset,
+                          NR_BWP_Uplink_t *bwp,
+                          NR_BWP_UplinkDedicated_t *bwpd,
+                          int CCEIndex);
+
+void nr_configure_pucch(const NR_SIB1_t *sib1,
+                        nfapi_nr_pucch_pdu_t* pucch_pdu,
                         NR_ServingCellConfigCommon_t *scc,
                         NR_CellGroupConfig_t *CellGroup,
                         NR_BWP_Uplink_t *bwp,
@@ -284,7 +293,8 @@ void fill_dci_pdu_rel15(const NR_ServingCellConfigCommon_t *scc,
                         int dci_formats,
                         int rnti_types,
                         int N_RB,
-                        int bwp_id);
+                        int bwp_id,
+                        uint16_t cset0_bwp_size);
 
 void prepare_dci(const NR_CellGroupConfig_t *CellGroup,
                  dci_pdu_rel15_t *dci_pdu_rel15,
@@ -299,6 +309,18 @@ void set_r_pucch_parms(int rsetindex,
                        int *nr_of_symbols,
                        int *start_symbol_index);
 
+NR_BWP_t *get_dl_bwp_genericParameters(NR_BWP_Downlink_t *active_bwp,
+                                       NR_ServingCellConfigCommon_t *ServingCellConfigCommon,
+                                       const NR_SIB1_t *sib1);
+
+NR_BWP_t *get_ul_bwp_genericParameters(NR_BWP_Uplink_t *active_ubwp,
+                                       NR_ServingCellConfigCommon_t *ServingCellConfigCommon,
+                                       const NR_SIB1_t *sib1);
+
+NR_PDSCH_TimeDomainResourceAllocationList_t *get_pdsch_TimeDomainAllocationList(const NR_BWP_Downlink_t *active_bwp,
+                                                                                const NR_ServingCellConfigCommon_t *ServingCellConfigCommon,
+                                                                                const NR_SIB1_t *sib1);
+
 /* find coreset within the search space */
 NR_ControlResourceSet_t *get_coreset(module_id_t module_idP,
                                      NR_ServingCellConfigCommon_t *scc,
@@ -307,13 +329,19 @@ NR_ControlResourceSet_t *get_coreset(module_id_t module_idP,
                                      NR_SearchSpace__searchSpaceType_PR ss_type);
 
 /* find a search space within a BWP */
-NR_SearchSpace_t *get_searchspace(NR_ServingCellConfigCommon_t *scc,
+NR_SearchSpace_t *get_searchspace(const NR_SIB1_t *sib1,
+                                  NR_ServingCellConfigCommon_t *scc,
                                   NR_BWP_DownlinkDedicated_t *bwp_Dedicated,
                                   NR_SearchSpace__searchSpaceType_PR target_ss);
 
-long get_K2(NR_ServingCellConfigCommon_t *scc, NR_BWP_Uplink_t *ubwp, int time_domain_assignment, int mu);
+long get_K2(NR_ServingCellConfigCommon_t *scc,
+            NR_ServingCellConfigCommonSIB_t *scc_sib1,
+            NR_BWP_Uplink_t *ubwp,
+            int time_domain_assignment,
+            int mu);
 
-void nr_set_pdsch_semi_static(const NR_ServingCellConfigCommon_t *scc,
+void nr_set_pdsch_semi_static(const NR_SIB1_t *sib1,
+                              const NR_ServingCellConfigCommon_t *scc,
                               const NR_CellGroupConfig_t *secondaryCellGroup,
                               const NR_BWP_Downlink_t *bwp,
                               const NR_BWP_DownlinkDedicated_t *bwpd0,
@@ -322,9 +350,10 @@ void nr_set_pdsch_semi_static(const NR_ServingCellConfigCommon_t *scc,
                               NR_UE_sched_ctrl_t *sched_ctrl,
                               NR_pdsch_semi_static_t *ps);
 
-void nr_set_pusch_semi_static(const NR_ServingCellConfigCommon_t *scc,
+void nr_set_pusch_semi_static(const NR_SIB1_t *sib1,
+                              const NR_ServingCellConfigCommon_t *scc,
                               const NR_BWP_Uplink_t *ubwp,
-			                        const NR_BWP_UplinkDedicated_t *ubwpd,
+                              const NR_BWP_UplinkDedicated_t *ubwpd,
                               long dci_format,
                               int tda,
                               uint8_t num_dmrs_cdm_grps_no_data,
@@ -483,4 +512,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 4141976b5dd3ff6af6d4b6f729e9e214560eaf4d..0f538131dddb0b4c6071ef46d17c28cfd9a72a15 100644
--- a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h
+++ b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h
@@ -205,6 +205,7 @@ typedef struct {
   lte_frame_type_t frame_type;
   uint64_t dl_CarrierFreq;
   NR_BCCH_BCH_Message_t *mib;
+  NR_BCCH_DL_SCH_Message_t *sib1;
   NR_ServingCellConfigCommon_t *ServingCellConfigCommon;
   NR_ARFCN_ValueEUTRA_t ul_CarrierFreq;
   long ul_Bandwidth;
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/NR_UE_PHY_INTERFACE/NR_IF_Module.c b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c
index f7323010cb05fcdbe3c9cdbac2ee97ba03aa2333..26c60fbb9bba5eaf90e25c0b72193272efab38c3 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)
 {
@@ -98,7 +109,7 @@ void nrue_init_standalone_socket(int tx_port, int rx_port)
     }
     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__);
   }
 
   {
@@ -124,9 +135,9 @@ void nrue_init_standalone_socket(int tx_port, int rx_port)
     }
     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,59 @@ 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 +656,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 +676,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 +705,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 +758,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 +779,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 +796,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 +826,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 +838,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 +862,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 +882,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 +902,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 +938,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 +1007,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 +1021,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))
       {
@@ -1037,7 +1096,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,7 +1120,7 @@ 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
@@ -1066,7 +1128,6 @@ void update_harq_status(module_id_t module_id, uint8_t harq_pid, uint8_t ack_nac
   }
 }
 
-
 int nr_ue_ul_indication(nr_uplink_indication_t *ul_info){
 
   NR_UE_L2_STATE_t ret;
@@ -1081,7 +1142,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 +1182,9 @@ 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,
@@ -1136,12 +1197,12 @@ 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");
+          LOG_T(NR_MAC, "We are filtering a UL_DCI to prevent it from being treated like a DL_DCI\n");
           break;
         }
         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) {
@@ -1160,7 +1221,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_T(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);
@@ -1244,7 +1305,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 +1340,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..034c1c6b48b2ec4dac7046c9c4a03c486ac67380 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,
@@ -240,6 +269,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);
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/PHY_INTERFACE/queue_t.h b/openair2/PHY_INTERFACE/queue_t.h
index 4678e310301ac4934ca1f7e2c241e18f481a01c4..5c644a320cf6ace6da00c7a4aa596c400d310ea6 100644
--- a/openair2/PHY_INTERFACE/queue_t.h
+++ b/openair2/PHY_INTERFACE/queue_t.h
@@ -24,7 +24,8 @@
     }
 */
 
-#pragma once
+#ifndef __OPENAIR2_PHY_INTERFACE_QUEUE_T__H__
+#define __OPENAIR2_PHY_INTERFACE_QUEUE_T__H__
 
 #include <stdbool.h>
 #include <stdint.h>
@@ -62,3 +63,5 @@ typedef bool queue_matcher_t(void *wanted, void *candidate);
    Look only at the last `max_depth` items on the queue, at most.
    Returns the candidate item, or NULL if none matches */
 void *unqueue_matching(queue_t *q, size_t max_depth, queue_matcher_t *matcher, void *wanted);
+
+#endif  /* __OPENAIR2_PHY_INTERFACE_QUEUE_T__H__ */
diff --git a/openair2/RRC/LTE/MESSAGES/asn1_msg.h b/openair2/RRC/LTE/MESSAGES/asn1_msg.h
index d1d1d3febe15254bac219f28f439bd1578b8a749..8373bb53f330b0c7bae733322ea0ace7089fd318 100644
--- a/openair2/RRC/LTE/MESSAGES/asn1_msg.h
+++ b/openair2/RRC/LTE/MESSAGES/asn1_msg.h
@@ -28,6 +28,9 @@
 * \email: raymond.knopp@eurecom.fr and  navid.nikaein@eurecom.fr
 */
 
+#ifndef __RRC_LTE_MESSAGES_ASN1_MSG__H__
+#define __RRC_LTE_MESSAGES_ASN1_MSG__H__
+
 #include <stdio.h>
 #include <sys/types.h>
 #include <stdlib.h> /* for atoi(3) */
@@ -405,3 +408,5 @@ uint8_t do_SecurityModeCommand(
   const uint8_t Transaction_id,
   const uint8_t cipheringAlgorithm,
   const uint8_t integrityProtAlgorithm);
+
+#endif  /* __RRC_LTE_MESSAGES_ASN1_MSG__H__ */
diff --git a/openair2/RRC/NR/L2_nr_interface.c b/openair2/RRC/NR/L2_nr_interface.c
index 1cf690ac0c064ac68e1d8b35f64ff77507a3ed97..e30b55cc94dfe346f132f8cd095ec2c841848cd0 100644
--- a/openair2/RRC/NR/L2_nr_interface.c
+++ b/openair2/RRC/NR/L2_nr_interface.c
@@ -321,7 +321,7 @@ int8_t nr_mac_rrc_data_ind(const module_id_t     module_idP,
     ue_context_p->ue_context.Srb0.Active        = 1;
     RB_INSERT(rrc_nr_ue_tree_s, &RC.nrrrc[module_idP]->rrc_ue_head, ue_context_p);
 
-    fill_initial_cellGroupConfig(ue_context_p->local_uid,&cellGroupConfig,scc,&RC.nrrrc[module_idP]->carrier);
+    fill_initial_cellGroupConfig(ue_context_p->local_uid,&cellGroupConfig,scc, &RC.nrrrc[module_idP]->configuration);
 
     MessageDef* tmp=itti_alloc_new_message_sized(TASK_RRC_GNB, 0, F1AP_INITIAL_UL_RRC_MESSAGE, sizeof(f1ap_initial_ul_rrc_message_t) + sdu_lenP);
     f1ap_initial_ul_rrc_message_t *msg = &F1AP_INITIAL_UL_RRC_MESSAGE(tmp);
diff --git a/openair2/RRC/NR/MESSAGES/asn1_msg.c b/openair2/RRC/NR/MESSAGES/asn1_msg.c
index d04ed78270f0efd56ef135bd6b3cd2760128b4ff..9252a23596156771840f8f939f39ee3d52c4abcb 100755
--- a/openair2/RRC/NR/MESSAGES/asn1_msg.c
+++ b/openair2/RRC/NR/MESSAGES/asn1_msg.c
@@ -197,6 +197,7 @@ uint8_t do_MIB_NR(gNB_RRC_INST *rrc,uint32_t frame) {
 
   asn_enc_rval_t enc_rval;
   rrc_gNB_carrier_data_t *carrier = &rrc->carrier;  
+  const gNB_RrcConfigurationReq *configuration = &rrc->configuration;
 
   NR_BCCH_BCH_Message_t *mib = &carrier->mib;
   NR_ServingCellConfigCommon_t *scc = carrier->servingcellconfigcommon;
@@ -220,7 +221,7 @@ uint8_t do_MIB_NR(gNB_RRC_INST *rrc,uint32_t frame) {
   mib->message.choice.mib->spare.size = 1;
   mib->message.choice.mib->spare.bits_unused = 7;  // This makes a spare of 1 bits
 
-  mib->message.choice.mib->ssb_SubcarrierOffset = (carrier->ssb_SubcarrierOffset)&15;
+  mib->message.choice.mib->ssb_SubcarrierOffset = (configuration->ssb_SubcarrierOffset)&15;
 
   /*
   * The SIB1 will be sent in this allocation (Type0-PDCCH) : 38.213, 13-4 Table and 38.213 13-11 to 13-14 tables
@@ -1007,8 +1008,8 @@ long rrc_get_max_nr_csrs(uint8_t max_rbs, long b_SRS) {
 void fill_initial_SpCellConfig(int uid,
                                NR_SpCellConfig_t *SpCellConfig,
                                NR_ServingCellConfigCommon_t *scc,
-                               rrc_gNB_carrier_data_t *carrier) {
-
+                               const gNB_RrcConfigurationReq *configuration)
+{
   // This assert will never happen in the current implementation because NUMBER_OF_UE_MAX = 4.
   // However, if in the future NUMBER_OF_UE_MAX is increased, it will be necessary to improve the allocation of SRS resources,
   // where the startPosition = 2 or 3 and sl160 = 17, 17, 27 ... 157 only give us 30 different allocations.
@@ -1139,7 +1140,7 @@ void fill_initial_SpCellConfig(int uid,
   ASN_SEQUENCE_ADD(&srs_resset0->srs_ResourceIdList->list,srs_resset0_id);
   srs_Config->srs_ResourceToReleaseList=NULL;
 
-  if(carrier->do_SRS) {
+  if (configuration->do_SRS) {
     srs_resset0->resourceType.present =  NR_SRS_ResourceSet__resourceType_PR_periodic;
     srs_resset0->resourceType.choice.periodic = calloc(1,sizeof(*srs_resset0->resourceType.choice.periodic));
     srs_resset0->resourceType.choice.periodic->associatedCSI_RS = NULL;
@@ -1183,7 +1184,7 @@ void fill_initial_SpCellConfig(int uid,
       srs_res0->freqHopping.b_SRS);
   srs_res0->groupOrSequenceHopping=NR_SRS_Resource__groupOrSequenceHopping_neither;
 
-  if(carrier->do_SRS) {
+  if (configuration->do_SRS) {
     srs_res0->resourceType.present= NR_SRS_Resource__resourceType_PR_periodic;
     srs_res0->resourceType.choice.periodic=calloc(1,sizeof(*srs_res0->resourceType.choice.periodic));
     srs_res0->resourceType.choice.periodic->periodicityAndOffset_p.present = NR_SRS_PeriodicityAndOffset_PR_sl160;
@@ -1229,9 +1230,9 @@ void fill_initial_SpCellConfig(int uid,
  long *delay[8];
  for (int i=0;i<8;i++) {
    delay[i] = calloc(1,sizeof(*delay[i]));
-   AssertFatal(carrier->minRXTXTIME >=2 && carrier->minRXTXTIME <7,
-               "check minRXTXTIME %d\n",carrier->minRXTXTIME);
-   *delay[i] = (i+carrier->minRXTXTIME);
+   AssertFatal(configuration->minRXTXTIME >= 2 && configuration->minRXTXTIME < 7,
+               "minRXTXTIME is %d but should be within [2,7)\n", configuration->minRXTXTIME);
+   *delay[i] = i + configuration->minRXTXTIME;
    ASN_SEQUENCE_ADD(&pucch_Config->dl_DataToUL_ACK->list,delay[i]);
  }
 
@@ -1451,25 +1452,26 @@ 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) {
+                            NR_UE_NR_Capability_t *uecap,
+                            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,
-                   uecap, bwp_Dedicated, scc);
+                   configuration->force_256qam_off ? NULL : uecap, bwp_Dedicated, scc);
 
   struct NR_ServingCellConfig__downlinkBWP_ToAddModList *DL_BWP_list = SpCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList;
   if (DL_BWP_list) {
     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, uecap, bwp->bwp_Dedicated, carrier->servingcellconfigcommon);
+      set_dl_mcs_table(scs, configuration->force_256qam_off ? NULL : uecap, bwp->bwp_Dedicated, scc);
     }
   }
 }
@@ -1478,8 +1480,8 @@ void update_cellGroupConfig(NR_CellGroupConfig_t *cellGroupConfig,
 void fill_initial_cellGroupConfig(int uid,
                                   NR_CellGroupConfig_t *cellGroupConfig,
                                   NR_ServingCellConfigCommon_t *scc,
-                                  rrc_gNB_carrier_data_t *carrier) {
-
+                                  const gNB_RrcConfigurationReq *configuration)
+{
   NR_RLC_BearerConfig_t                            *rlc_BearerConfig     = NULL;
   NR_RLC_Config_t                                  *rlc_Config           = NULL;
   NR_LogicalChannelConfig_t                        *logicalChannelConfig = NULL;
@@ -1569,7 +1571,7 @@ void fill_initial_cellGroupConfig(int uid,
   
   cellGroupConfig->spCellConfig                                             = calloc(1,sizeof(*cellGroupConfig->spCellConfig));
   
-  fill_initial_SpCellConfig(uid,cellGroupConfig->spCellConfig,scc,carrier);
+  fill_initial_SpCellConfig(uid,cellGroupConfig->spCellConfig,scc,configuration);
   
   cellGroupConfig->sCellToAddModList                                        = NULL;
   cellGroupConfig->sCellToReleaseList                                       = NULL;
@@ -1581,7 +1583,7 @@ uint8_t do_RRCSetup(rrc_gNB_ue_context_t         *const ue_context_pP,
                     const uint8_t                transaction_id,
                     OCTET_STRING_t               *masterCellGroup_from_DU,
                     NR_ServingCellConfigCommon_t *scc,
-                    rrc_gNB_carrier_data_t *carrier)
+                    const gNB_RrcConfigurationReq *configuration)
 //------------------------------------------------------------------------------
 {
     asn_enc_rval_t                                   enc_rval;
@@ -1648,7 +1650,7 @@ uint8_t do_RRCSetup(rrc_gNB_ue_context_t         *const ue_context_pP,
     }
     else {
       cellGroupConfig = calloc(1, sizeof(NR_CellGroupConfig_t));
-      fill_initial_cellGroupConfig(ue_context_pP->local_uid,cellGroupConfig,scc,carrier);
+      fill_initial_cellGroupConfig(ue_context_pP->local_uid, cellGroupConfig, scc, configuration);
 
       enc_rval = uper_encode_to_buffer(&asn_DEF_NR_CellGroupConfig,
 				       NULL,
@@ -1896,6 +1898,7 @@ int16_t do_RRCReconfiguration(
     struct NR_RRCReconfiguration_v1530_IEs__dedicatedNAS_MessageList *dedicatedNAS_MessageList,
     rrc_gNB_ue_context_t         *const ue_context_pP,
     rrc_gNB_carrier_data_t       *carrier,
+    const gNB_RrcConfigurationReq *configuration,
     NR_MAC_CellGroupConfig_t     *mac_CellGroupConfig,
     NR_CellGroupConfig_t         *cellGroupConfig)
 //------------------------------------------------------------------------------
@@ -1948,8 +1951,9 @@ int16_t do_RRCReconfiguration(
 
     if(cellGroupConfig!=NULL){
       update_cellGroupConfig(cellGroupConfig,
-                             carrier,
-                             ue_context_pP->ue_context.UE_Capability_nr);
+                             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 7fe08704c2bdb64d0f90ea71e48a851ed34553ec..aeef5f93a7ef1eac76400206cd0bbf44c9fe595e 100644
--- a/openair2/RRC/NR/MESSAGES/asn1_msg.h
+++ b/openair2/RRC/NR/MESSAGES/asn1_msg.h
@@ -28,7 +28,8 @@
 * \email: raymond.knopp@eurecom.fr and  navid.nikaein@eurecom.fr, kroempa@gmail.com
 */
 
-#pragma once
+#ifndef __RRC_NR_MESSAGES_ASN1_MSG__H__
+#define __RRC_NR_MESSAGES_ASN1_MSG__H__
 
 #include <stdio.h>
 #include <sys/types.h>
@@ -101,18 +102,18 @@ uint8_t do_RRCReject(uint8_t Mod_id,
                      uint8_t *const buffer);
 
 void fill_initial_SpCellConfig(int uid,
-			       NR_SpCellConfig_t *SpCellConfig,
-			       NR_ServingCellConfigCommon_t *scc,
-                               rrc_gNB_carrier_data_t *carrier);
+                               NR_SpCellConfig_t *SpCellConfig,
+                               NR_ServingCellConfigCommon_t *scc,
+                               const gNB_RrcConfigurationReq *configuration);
 
 void fill_initial_cellGroupConfig(int uid,
-				  NR_CellGroupConfig_t *cellGroupConfig,
-				  NR_ServingCellConfigCommon_t *scc,
-                                  rrc_gNB_carrier_data_t *carrier);
+                                  NR_CellGroupConfig_t *cellGroupConfig,
+                                  NR_ServingCellConfigCommon_t *scc,
+                                  const gNB_RrcConfigurationReq *configuration);
 
 void update_cellGroupConfig(NR_CellGroupConfig_t *cellGroupConfig,
-                            rrc_gNB_carrier_data_t *carrier,
-                            NR_UE_NR_Capability_t *uecap);
+                            NR_UE_NR_Capability_t *uecap,
+                            const gNB_RrcConfigurationReq *configuration);
 
 void fill_mastercellGroupConfig(NR_CellGroupConfig_t *cellGroupConfig, NR_CellGroupConfig_t *ue_context_mastercellGroup);
 
@@ -121,7 +122,7 @@ uint8_t do_RRCSetup(rrc_gNB_ue_context_t         *const ue_context_pP,
                     const uint8_t                transaction_id,
                     OCTET_STRING_t               *masterCellGroup_from_DU,
                     NR_ServingCellConfigCommon_t *scc,
-                    rrc_gNB_carrier_data_t *carrier);
+                    const gNB_RrcConfigurationReq *configuration);
 
 uint8_t do_NR_SecurityModeCommand(
                     const protocol_ctxt_t *const ctxt_pP,
@@ -151,6 +152,7 @@ int16_t do_RRCReconfiguration(
     struct NR_RRCReconfiguration_v1530_IEs__dedicatedNAS_MessageList *dedicatedNAS_MessageList,
     rrc_gNB_ue_context_t         *const ue_context_pP,
     rrc_gNB_carrier_data_t       *carrier,
+    const gNB_RrcConfigurationReq *configuration,
     NR_MAC_CellGroupConfig_t     *mac_CellGroupConfig,
     NR_CellGroupConfig_t         *cellGroupConfig);
 
@@ -205,3 +207,4 @@ do_RRCReestablishmentComplete(
     uint8_t *buffer, size_t buffer_size,
     int64_t rrc_TransactionIdentifier);
 
+#endif  /* __RRC_NR_MESSAGES_ASN1_MSG__H__ */
diff --git a/openair2/RRC/NR/nr_rrc_config.c b/openair2/RRC/NR/nr_rrc_config.c
index f8f05f2fe59abd98efc07f35637685d81910dd7c..bb2a180146c12bc92e65ba768e57289dada83075 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,
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_defs.h b/openair2/RRC/NR/nr_rrc_defs.h
index 1b2c38c8356e90cc5a4daff789b2d86f9e2797ae..b26f8243a073195e47f4e02eece9ce61f5a89709 100644
--- a/openair2/RRC/NR/nr_rrc_defs.h
+++ b/openair2/RRC/NR/nr_rrc_defs.h
@@ -424,7 +424,6 @@ typedef struct rrc_gNB_ue_context_s {
   struct gNB_RRC_UE_s   ue_context;
 } rrc_gNB_ue_context_t;
 
-
 typedef struct {
 
   // buffer that contains the encoded messages
@@ -449,13 +448,6 @@ typedef struct {
   NR_SIB2_t                                *sib2;
   NR_SIB3_t                                *sib3;
   NR_BCCH_DL_SCH_Message_t                  systemInformation; // SIB23
-  int ssb_SubcarrierOffset;
-  int sib1_tda;
-  int pdsch_AntennaPorts;
-  int pusch_AntennaPorts;
-  int minRXTXTIME;
-  int do_CSIRS;
-  int do_SRS;
   NR_BCCH_DL_SCH_Message_t                  *siblock1;
   NR_ServingCellConfigCommon_t              *servingcellconfigcommon;
   NR_PDCCH_ConfigSIB1_t                     *pdcch_ConfigSIB1;
diff --git a/openair2/RRC/NR/nr_rrc_proto.h b/openair2/RRC/NR/nr_rrc_proto.h
index 7dceb55a4bb98444e7534708665e3419dcaa880b..006040bbb9417f842d6e028acd39bee8f9c958a6 100644
--- a/openair2/RRC/NR/nr_rrc_proto.h
+++ b/openair2/RRC/NR/nr_rrc_proto.h
@@ -79,27 +79,15 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco
                                      NR_UE_NR_Capability_t *uecap,
                                      int scg_id,
                                      int servCellIndex,
-                                     int dl_antenna_ports,
-                                     int minRXTXTIMEpdsch,
-                                     int do_csirs,
-                                     int do_srs,
+                                     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,
                            NR_CellGroupConfig_t *secondaryCellGroup,
                            NR_UE_NR_Capability_t *uecap,
-                           int dl_antenna_ports,
-                           int minRXTXTIMEpdsch,
-                           int do_csirs,
-                           int do_srs,
+                           const gNB_RrcConfigurationReq *configuration,
                            int uid);
 
 void fill_default_rbconfig(NR_RadioBearerConfig_t *rbconfig,
diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c
index d6c658f01d1f3fa61780b30a5a155ff0e7ddac57..1715677c6df6fed74a2d1301af30157962984aaa 100755
--- a/openair2/RRC/NR/rrc_gNB.c
+++ b/openair2/RRC/NR/rrc_gNB.c
@@ -166,17 +166,17 @@ static void init_NR_SI(gNB_RRC_INST *rrc, gNB_RrcConfigurationReq *configuration
 
   if (NODE_IS_MONOLITHIC(rrc->node_type)){
     rrc_mac_config_req_gNB(rrc->module_id,
-			   rrc->carrier.ssb_SubcarrierOffset,
-			   rrc->carrier.pdsch_AntennaPorts,
-			   rrc->carrier.pusch_AntennaPorts,
-                           rrc->carrier.sib1_tda,
-                           rrc->carrier.minRXTXTIME,
-			   (NR_ServingCellConfigCommon_t *)rrc->carrier.servingcellconfigcommon,
-			   &rrc->carrier.mib,
-			   0,
-			   0, // WIP hardcoded rnti
-			   (NR_CellGroupConfig_t *)NULL
-			   );
+                           rrc->configuration.ssb_SubcarrierOffset,
+                           rrc->configuration.pdsch_AntennaPorts,
+                           rrc->configuration.pusch_AntennaPorts,
+                           rrc->configuration.sib1_tda,
+                           rrc->configuration.minRXTXTIME,
+                           rrc->carrier.servingcellconfigcommon,
+                           &rrc->carrier.mib,
+                           rrc->carrier.siblock1,
+                           0,
+                           0, // WIP hardcoded rnti
+                           NULL);
   }
 
   /* set flag to indicate that cell information is configured. This is required
@@ -216,14 +216,8 @@ char openair_rrc_gNB_configuration(const module_id_t gnb_mod_idP, gNB_RrcConfigu
   rrc->s1ap_id2_s1ap_ids    = hashtable_create (NUMBER_OF_UE_MAX * 2, NULL, NULL);
   rrc->initial_id2_ngap_ids = hashtable_create (NUMBER_OF_UE_MAX * 2, NULL, NULL);
   rrc->ngap_id2_ngap_ids    = hashtable_create (NUMBER_OF_UE_MAX * 2, NULL, NULL);
+  rrc->configuration = *configuration;
   rrc->carrier.servingcellconfigcommon = configuration->scc;
-  rrc->carrier.ssb_SubcarrierOffset = configuration->ssb_SubcarrierOffset;
-  rrc->carrier.pdsch_AntennaPorts = configuration->pdsch_AntennaPorts;
-  rrc->carrier.pusch_AntennaPorts = configuration->pusch_AntennaPorts;
-  rrc->carrier.minRXTXTIME = configuration->minRXTXTIME;
-  rrc->carrier.sib1_tda = configuration->sib1_tda;
-  rrc->carrier.do_CSIRS = configuration->do_CSIRS;
-  rrc->carrier.do_SRS = configuration->do_SRS;
   nr_rrc_config_ul_tda(configuration->scc,configuration->minRXTXTIME);
    /// System Information INIT
   pthread_mutex_init(&rrc->cell_info_mutex,NULL);
@@ -279,24 +273,26 @@ void apply_macrlc_config(gNB_RRC_INST *rrc,
                          rrc_gNB_ue_context_t         *const ue_context_pP,
                          const protocol_ctxt_t        *const ctxt_pP ) {
 
-      rrc_mac_config_req_gNB(rrc->module_id,
-			     rrc->carrier.ssb_SubcarrierOffset,
-			     rrc->carrier.pdsch_AntennaPorts,
-			     rrc->carrier.pusch_AntennaPorts,
-			     rrc->carrier.sib1_tda,
-                             rrc->carrier.minRXTXTIME,
-			     NULL,
-                             NULL,
-			     0,
-			     ue_context_pP->ue_context.rnti,
-			     get_softmodem_params()->sa ? ue_context_pP->ue_context.masterCellGroup : (NR_CellGroupConfig_t *)NULL);
+  NR_CellGroupConfig_t *cgc = get_softmodem_params()->sa ? ue_context_pP->ue_context.masterCellGroup : NULL;
+  rrc_mac_config_req_gNB(rrc->module_id,
+                         rrc->configuration.ssb_SubcarrierOffset,
+                         rrc->configuration.pdsch_AntennaPorts,
+                         rrc->configuration.pusch_AntennaPorts,
+                         rrc->configuration.sib1_tda,
+                         rrc->configuration.minRXTXTIME,
+                         NULL,
+                         NULL,
+                         NULL,
+                         0,
+                         ue_context_pP->ue_context.rnti,
+                         cgc);
 
-      nr_rrc_rlc_config_asn1_req(ctxt_pP,
-                                 ue_context_pP->ue_context.SRB_configList,
-                                 ue_context_pP->ue_context.DRB_configList,
-                                 NULL,
-                                 NULL,
-                                 get_softmodem_params()->sa ? ue_context_pP->ue_context.masterCellGroup->rlc_BearerToAddModList : NULL);
+  nr_rrc_rlc_config_asn1_req(ctxt_pP,
+                             ue_context_pP->ue_context.SRB_configList,
+                             ue_context_pP->ue_context.DRB_configList,
+                             NULL,
+                             NULL,
+                             get_softmodem_params()->sa ? cgc->rlc_BearerToAddModList : NULL);
 
 }
 
@@ -340,10 +336,11 @@ rrc_gNB_generate_RRCSetup(
   gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context;
   gNB_RRC_INST *rrc = RC.nrrrc[ctxt_pP->module_id];
   ue_p->Srb0.Tx_buffer.payload_size = do_RRCSetup(ue_context_pP,
-						  (uint8_t *) ue_p->Srb0.Tx_buffer.Payload,
-						  rrc_gNB_get_next_transaction_identifier(ctxt_pP->module_id),
-						  masterCellGroup_from_DU,
-						  scc,&rrc->carrier);
+                                                  (uint8_t *) ue_p->Srb0.Tx_buffer.Payload,
+                                                  rrc_gNB_get_next_transaction_identifier(ctxt_pP->module_id),
+                                                  masterCellGroup_from_DU,
+                                                  scc,
+                                                  &rrc->configuration);
 
   LOG_DUMPMSG(NR_RRC, DEBUG_RRC,
               (char *)(ue_p->Srb0.Tx_buffer.Payload),
@@ -450,10 +447,11 @@ rrc_gNB_generate_RRCSetup_for_RRCReestablishmentRequest(
 
   gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context;
   ue_p->Srb0.Tx_buffer.payload_size = do_RRCSetup(ue_context_pP,
-						  (uint8_t *) ue_p->Srb0.Tx_buffer.Payload,
-						  rrc_gNB_get_next_transaction_identifier(ctxt_pP->module_id),
-						  NULL,
-						  scc,&rrc_instance_p->carrier);
+                                                  (uint8_t *) ue_p->Srb0.Tx_buffer.Payload,
+                                                  rrc_gNB_get_next_transaction_identifier(ctxt_pP->module_id),
+                                                  NULL,
+                                                  scc,
+                                                  &rrc_instance_p->configuration);
 
   LOG_DUMPMSG(NR_RRC, DEBUG_RRC,
               (char *)(ue_p->Srb0.Tx_buffer.Payload),
@@ -465,17 +463,17 @@ rrc_gNB_generate_RRCSetup_for_RRCReestablishmentRequest(
           PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP));
 
   rrc_mac_config_req_gNB(rrc_instance_p->module_id,
-                         rrc_instance_p->carrier.ssb_SubcarrierOffset,
-                         rrc_instance_p->carrier.pdsch_AntennaPorts,
-                         rrc_instance_p->carrier.pusch_AntennaPorts,
-                         rrc_instance_p->carrier.sib1_tda,
-                         rrc_instance_p->carrier.minRXTXTIME,
-                         (NR_ServingCellConfigCommon_t *)rrc_instance_p->carrier.servingcellconfigcommon,
+                         rrc_instance_p->configuration.ssb_SubcarrierOffset,
+                         rrc_instance_p->configuration.pdsch_AntennaPorts,
+                         rrc_instance_p->configuration.pusch_AntennaPorts,
+                         rrc_instance_p->configuration.sib1_tda,
+                         rrc_instance_p->configuration.minRXTXTIME,
+                         rrc_instance_p->carrier.servingcellconfigcommon,
                          &rrc_instance_p->carrier.mib,
+                         rrc_instance_p->carrier.siblock1,
                          0,
                          ue_context_pP->ue_context.rnti,
-                         (NR_CellGroupConfig_t *)NULL
-			 );
+                         NULL);
 
   LOG_I(NR_RRC,
         PROTOCOL_NR_RRC_CTXT_UE_FMT" [RAPROC] Logical Channel DL-CCCH, Generating RRCSetup (bytes %d)\n",
@@ -723,6 +721,7 @@ rrc_gNB_generate_defaultRRCReconfiguration(
                                 dedicatedNAS_MessageList,
                                 ue_context_pP,
                                 &rrc->carrier,
+                                &rrc->configuration,
                                 NULL,
                                 ue_p->masterCellGroup);
 
@@ -822,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;
@@ -873,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;
@@ -986,6 +990,7 @@ rrc_gNB_generate_dedicatedRRCReconfiguration(
                                 dedicatedNAS_MessageList,
                                 ue_context_pP,
                                 &rrc->carrier,
+                                &rrc->configuration,
                                 NULL,
                                 cellGroupConfig);
   LOG_DUMPMSG(NR_RRC,DEBUG_RRC,(char *)buffer,size,"[MSG] RRC Reconfiguration\n");
@@ -1159,6 +1164,7 @@ rrc_gNB_modify_dedicatedRRCReconfiguration(
                                 NULL,
                                 NULL,
                                 NULL,
+                                NULL,
                                 NULL);
   LOG_DUMPMSG(NR_RRC, DEBUG_RRC, (char *)buffer, size, "[MSG] RRC Reconfiguration\n");
 
@@ -1259,6 +1265,7 @@ rrc_gNB_generate_dedicatedRRCReconfiguration_release(
                                NULL,
                                NULL,
                                NULL,
+                               NULL,
                                NULL);
 
   ue_context_pP->ue_context.pdu_session_release_command_flag = 1;
@@ -1362,17 +1369,17 @@ rrc_gNB_process_RRCReconfigurationComplete(
 
   if (!NODE_IS_CU(RC.nrrrc[ctxt_pP->module_id]->node_type)) {
     rrc_mac_config_req_gNB(rrc->module_id,
-                           rrc->carrier.ssb_SubcarrierOffset,
-                           rrc->carrier.pdsch_AntennaPorts,
-                           rrc->carrier.pusch_AntennaPorts,
-                           rrc->carrier.sib1_tda,
-                           rrc->carrier.minRXTXTIME,
+                           rrc->configuration.ssb_SubcarrierOffset,
+                           rrc->configuration.pdsch_AntennaPorts,
+                           rrc->configuration.pusch_AntennaPorts,
+                           rrc->configuration.sib1_tda,
+                           rrc->configuration.minRXTXTIME,
+                           NULL,
                            NULL,
                            NULL,
                            0,
                            ue_context_pP->ue_context.rnti,
-                           ue_context_pP->ue_context.masterCellGroup
-                           );
+                           ue_context_pP->ue_context.masterCellGroup);
     LOG_D(NR_RRC,"Configuring RLC DRBs/SRBs for UE %x\n",ue_context_pP->ue_context.rnti);
     nr_rrc_rlc_config_asn1_req(ctxt_pP,
                                SRB_configList, // NULL,
@@ -1810,6 +1817,7 @@ rrc_gNB_process_RRCConnectionReestablishmentComplete(
                                 NULL,
                                 NULL,
                                 NULL,
+                                NULL,
                                 NULL);
   LOG_DUMPMSG(NR_RRC,DEBUG_RRC,(char *)buffer,size,
               "[MSG] RRC Reconfiguration\n");
diff --git a/openair2/RRC/NR/rrc_gNB_nsa.c b/openair2/RRC/NR/rrc_gNB_nsa.c
index 70dfebaaf7d60a5a1f7520babfee1ed492dc90bb..bb66d1513b77d43c20c9a0897556123f6a578b7c 100644
--- a/openair2/RRC/NR/rrc_gNB_nsa.c
+++ b/openair2/RRC/NR/rrc_gNB_nsa.c
@@ -116,6 +116,7 @@ RB_PROTOTYPE(rrc_nr_ue_tree_s, rrc_gNB_ue_context_s, entries,
 void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_p, x2ap_ENDC_sgnb_addition_req_t *m) {
   // generate nr-Config-r15 containers for LTE RRC : inside message for X2 EN-DC (CG-Config Message from 38.331)
   rrc_gNB_carrier_data_t *carrier=&rrc->carrier;
+  const gNB_RrcConfigurationReq *configuration = &rrc->configuration;
   MessageDef *msg;
   msg = itti_alloc_new_message(TASK_RRC_ENB, 0, X2AP_ENDC_SGNB_ADDITION_REQ_ACK);
   gtpv1u_enb_create_tunnel_req_t  create_tunnel_req;
@@ -240,29 +241,16 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_
                           cipher_algo,
                           NR_SecurityConfig__keyToUse_secondary);
   }
-  if (ue_context_p->ue_context.spCellConfig) {
-    fill_default_reconfig(carrier->servingcellconfigcommon,
-                          ue_context_p->ue_context.spCellConfig->spCellConfigDedicated,
-                          reconfig_ies,
-                          ue_context_p->ue_context.secondaryCellGroup,
-                          ue_context_p->ue_context.UE_Capability_nr,
-                          carrier->pdsch_AntennaPorts,
-                          carrier->minRXTXTIME,
-                          carrier->do_CSIRS,
-                          carrier->do_SRS,
-                          ue_context_p->local_uid);
-  } else {
-    fill_default_reconfig(carrier->servingcellconfigcommon,
-                          NULL,
-                          reconfig_ies,
-                          ue_context_p->ue_context.secondaryCellGroup,
-                          ue_context_p->ue_context.UE_Capability_nr,
-                          carrier->pdsch_AntennaPorts,
-                          carrier->minRXTXTIME,
-                          carrier->do_CSIRS,
-                          carrier->do_SRS,
-                          ue_context_p->local_uid);
-  }
+  NR_ServingCellConfig_t *scc = ue_context_p->ue_context.spCellConfig
+      ? ue_context_p->ue_context.spCellConfig->spCellConfigDedicated
+      : NULL;
+  fill_default_reconfig(carrier->servingcellconfigcommon,
+                        scc,
+                        reconfig_ies,
+                        ue_context_p->ue_context.secondaryCellGroup,
+                        ue_context_p->ue_context.UE_Capability_nr,
+                        configuration,
+                        ue_context_p->local_uid);
   ue_context_p->ue_id_rnti = ue_context_p->ue_context.secondaryCellGroup->spCellConfig->reconfigurationWithSync->newUE_Identity;
   NR_CG_Config_t *CG_Config = calloc(1,sizeof(*CG_Config));
   memset((void *)CG_Config,0,sizeof(*CG_Config));
@@ -359,23 +347,25 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_
   // configure MAC and RLC
   if (NODE_IS_DU(rrc->node_type)) {
     rrc_mac_config_req_gNB(rrc->module_id,
-                           rrc->carrier.ssb_SubcarrierOffset,
-                           rrc->carrier.pdsch_AntennaPorts,
-			   rrc->carrier.pusch_AntennaPorts,
-                           rrc->carrier.sib1_tda,
-                           rrc->carrier.minRXTXTIME,
+                           rrc->configuration.ssb_SubcarrierOffset,
+                           rrc->configuration.pdsch_AntennaPorts,
+                           rrc->configuration.pusch_AntennaPorts,
+                           rrc->configuration.sib1_tda,
+                           rrc->configuration.minRXTXTIME,
                            rrc->carrier.servingcellconfigcommon,
                            &rrc->carrier.mib,
+                           NULL,
                            1, // add_ue flag
                            ue_context_p->ue_id_rnti,
                            ue_context_p->ue_context.secondaryCellGroup);
   } else {
     rrc_mac_config_req_gNB(rrc->module_id,
-                           rrc->carrier.ssb_SubcarrierOffset,
-                           rrc->carrier.pdsch_AntennaPorts,
-                           rrc->carrier.pusch_AntennaPorts,
-                           rrc->carrier.sib1_tda,
-                           rrc->carrier.minRXTXTIME,
+                           rrc->configuration.ssb_SubcarrierOffset,
+                           rrc->configuration.pdsch_AntennaPorts,
+                           rrc->configuration.pusch_AntennaPorts,
+                           rrc->configuration.sib1_tda,
+                           rrc->configuration.minRXTXTIME,
+                           NULL,
                            NULL,
                            NULL,
                            1, // add_ue flag
diff --git a/openair2/RRC/NR/rrc_gNB_reconfig.c b/openair2/RRC/NR/rrc_gNB_reconfig.c
index 1a67a9c164df38d3dbf76e01d9bb99ff7ac8e916..36113fb7eea025f70d09e5cf5c70916450f15a5e 100644
--- a/openair2/RRC/NR/rrc_gNB_reconfig.c
+++ b/openair2/RRC/NR/rrc_gNB_reconfig.c
@@ -56,11 +56,12 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco
                                      NR_UE_NR_Capability_t *uecap,
                                      int scg_id,
                                      int servCellIndex,
-                                     int dl_antenna_ports,
-                                     int minRXTXTIME,
-                                     int do_csirs,
-                                     int do_srs,
-                                     int uid) {
+                                     const gNB_RrcConfigurationReq *configuration,
+                                     int uid)
+{
+  const rrc_pdsch_AntennaPorts_t* pdschap = &configuration->pdsch_AntennaPorts;
+  const int dl_antenna_ports = pdschap->N1 * pdschap->N2 * pdschap->XP;
+  const int do_csirs = configuration->do_CSIRS;
 
   AssertFatal(servingcellconfigcommon!=NULL,"servingcellconfigcommon is null\n");
   AssertFatal(secondaryCellGroup!=NULL,"secondaryCellGroup is null\n");
@@ -603,7 +604,10 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco
  bwp->bwp_Dedicated->pdsch_Config->choice.setup->rateMatchPatternGroup1=NULL;
  bwp->bwp_Dedicated->pdsch_Config->choice.setup->rateMatchPatternGroup2=NULL;
  bwp->bwp_Dedicated->pdsch_Config->choice.setup->rbg_Size=NR_PDSCH_Config__rbg_Size_config1;
- set_dl_mcs_table(bwp->bwp_Common->genericParameters.subcarrierSpacing, uecap, bwp->bwp_Dedicated, servingcellconfigcommon);
+ set_dl_mcs_table(bwp->bwp_Common->genericParameters.subcarrierSpacing,
+                  configuration->force_256qam_off ? NULL : uecap,
+                  bwp->bwp_Dedicated,
+                  servingcellconfigcommon);
  bwp->bwp_Dedicated->pdsch_Config->choice.setup->maxNrofCodeWordsScheduledByDCI = calloc(1,sizeof(*bwp->bwp_Dedicated->pdsch_Config->choice.setup->maxNrofCodeWordsScheduledByDCI));
  *bwp->bwp_Dedicated->pdsch_Config->choice.setup->maxNrofCodeWordsScheduledByDCI = NR_PDSCH_Config__maxNrofCodeWordsScheduledByDCI_n1;
  bwp->bwp_Dedicated->pdsch_Config->choice.setup->prb_BundlingType.present = NR_PDSCH_Config__prb_BundlingType_PR_staticBundling;
@@ -768,7 +772,7 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco
  ASN_SEQUENCE_ADD(&srs_resset0->srs_ResourceIdList->list,srs_resset0_id);
  srs_Config->srs_ResourceToReleaseList=NULL;
 
-  if(do_srs) {
+  if (configuration->do_SRS) {
     srs_resset0->resourceType.present =  NR_SRS_ResourceSet__resourceType_PR_periodic;
     srs_resset0->resourceType.choice.periodic = calloc(1,sizeof(*srs_resset0->resourceType.choice.periodic));
     srs_resset0->resourceType.choice.periodic->associatedCSI_RS = NULL;
@@ -812,7 +816,7 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco
      srs_res0->freqHopping.b_SRS);
  srs_res0->groupOrSequenceHopping=NR_SRS_Resource__groupOrSequenceHopping_neither;
 
-  if(do_srs) {
+  if (configuration->do_SRS) {
     srs_res0->resourceType.present= NR_SRS_Resource__resourceType_PR_periodic;
     srs_res0->resourceType.choice.periodic=calloc(1,sizeof(*srs_res0->resourceType.choice.periodic));
     srs_res0->resourceType.choice.periodic->periodicityAndOffset_p.present = NR_SRS_PeriodicityAndOffset_PR_sl160;
@@ -933,7 +937,7 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco
  long *delay[8];
  for (int i=0;i<8;i++) {
    delay[i] = calloc(1,sizeof(*delay[i]));
-   *delay[i] = i+minRXTXTIME;
+   *delay[i] = i + configuration->minRXTXTIME;
    ASN_SEQUENCE_ADD(&pucch_Config->dl_DataToUL_ACK->list,delay[i]);
  }
  pucch_Config->spatialRelationInfoToAddModList = calloc(1,sizeof(*pucch_Config->spatialRelationInfoToAddModList));
@@ -1062,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;
@@ -1098,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;
@@ -1178,19 +1165,50 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco
    csirep1->codebookConfig->codebookType.choice.type1 = calloc(1,sizeof(*csirep1->codebookConfig->codebookType.choice.type1));
    csirep1->codebookConfig->codebookType.choice.type1->subType.present=NR_CodebookConfig__codebookType__type1__subType_PR_typeI_SinglePanel;
    csirep1->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel=calloc(1,sizeof(*csirep1->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel));
-   csirep1->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->nrOfAntennaPorts.present=
-     NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts_PR_two;
-   csirep1->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->nrOfAntennaPorts.choice.two=
-     calloc(1,sizeof(*csirep1->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->nrOfAntennaPorts.choice.two));
-   csirep1->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->nrOfAntennaPorts.choice.two->twoTX_CodebookSubsetRestriction.size=1;
-   csirep1->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->nrOfAntennaPorts.choice.two->twoTX_CodebookSubsetRestriction.bits_unused=2;
-   csirep1->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->nrOfAntennaPorts.choice.two->twoTX_CodebookSubsetRestriction.buf=malloc(1);
-   csirep1->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->nrOfAntennaPorts.choice.two->twoTX_CodebookSubsetRestriction.buf[0]=0xfc;
-   csirep1->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->typeI_SinglePanel_ri_Restriction.size=1;
-   csirep1->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->typeI_SinglePanel_ri_Restriction.bits_unused=0;
-   csirep1->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->typeI_SinglePanel_ri_Restriction.buf=malloc(1);
-   csirep1->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->typeI_SinglePanel_ri_Restriction.buf[0]=0x03;
-   csirep1->codebookConfig->codebookType.choice.type1->codebookMode=1;
+   if (dl_antenna_ports == 2) {
+     csirep1->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->nrOfAntennaPorts.present=
+       NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts_PR_two;
+     csirep1->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->nrOfAntennaPorts.choice.two=
+       calloc(1,sizeof(*csirep1->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->nrOfAntennaPorts.choice.two));
+     csirep1->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->nrOfAntennaPorts.choice.two->twoTX_CodebookSubsetRestriction.size=1;
+     csirep1->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->nrOfAntennaPorts.choice.two->twoTX_CodebookSubsetRestriction.bits_unused=2;
+     csirep1->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->nrOfAntennaPorts.choice.two->twoTX_CodebookSubsetRestriction.buf=malloc(1);
+     csirep1->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->nrOfAntennaPorts.choice.two->twoTX_CodebookSubsetRestriction.buf[0]=0xfc;
+     csirep1->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->typeI_SinglePanel_ri_Restriction.size=1;
+     csirep1->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->typeI_SinglePanel_ri_Restriction.bits_unused=0;
+     csirep1->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->typeI_SinglePanel_ri_Restriction.buf=malloc(1);
+     csirep1->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->typeI_SinglePanel_ri_Restriction.buf[0]=0x03;
+     csirep1->codebookConfig->codebookType.choice.type1->codebookMode=1;
+   } else if (dl_antenna_ports < 16) {
+     csirep1->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->nrOfAntennaPorts.present=
+       NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts_PR_moreThanTwo;
+     csirep1->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->nrOfAntennaPorts.choice.moreThanTwo=
+       calloc(1,sizeof(*csirep1->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->nrOfAntennaPorts.choice.moreThanTwo));
+     if(dl_antenna_ports == 4)
+     csirep1->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->nrOfAntennaPorts.choice.moreThanTwo->n1_n2.present=
+       NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo__n1_n2_PR_two_one_TypeI_SinglePanel_Restriction;
+     else if(dl_antenna_ports == 8)
+       csirep1->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->nrOfAntennaPorts.choice.moreThanTwo->n1_n2.present=
+         NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo__n1_n2_PR_four_one_TypeI_SinglePanel_Restriction;
+     else if(dl_antenna_ports == 12)
+       csirep1->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->nrOfAntennaPorts.choice.moreThanTwo->n1_n2.present=
+         NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo__n1_n2_PR_six_one_TypeI_SinglePanel_Restriction;
+     else//default
+       csirep1->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->nrOfAntennaPorts.choice.moreThanTwo->n1_n2.present=
+         NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo__n1_n2_PR_two_one_TypeI_SinglePanel_Restriction;
+
+     /*csirep1->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->nrOfAntennaPorts.choice.moreThanTwo->n1_n2.choice.two_one_TypeI_SinglePanel_Restriction.size=1;
+     csirep1->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->nrOfAntennaPorts.choice.moreThanTwo->n1_n2.choice.two_one_TypeI_SinglePanel_Restriction.bits_unused=1;
+     csirep1->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->nrOfAntennaPorts.choice.moreThanTwo->n1_n2.choice.two_one_TypeI_SinglePanel_Restriction.buf=malloc(1);
+     csirep1->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->nrOfAntennaPorts.choice.moreThanTwo->n1_n2.choice.two_one_TypeI_SinglePanel_Restriction.buf[0]=0xc0; //'00000011'B
+     csirep1->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->nrOfAntennaPorts.choice.moreThanTwo->typeI_SinglePanel_codebookSubsetRestriction_i2->size = 1;
+     csirep1->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->nrOfAntennaPorts.choice.moreThanTwo->typeI_SinglePanel_codebookSubsetRestriction_i2->bits_unused=1;
+     csirep1->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->nrOfAntennaPorts.choice.moreThanTwo->typeI_SinglePanel_codebookSubsetRestriction_i2->buf=malloc(1);
+     csirep1->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->nrOfAntennaPorts.choice.moreThanTwo->typeI_SinglePanel_codebookSubsetRestriction_i2->buf[0]=0xc0;*/
+     csirep1->codebookConfig->codebookType.choice.type1->codebookMode=1;
+   } else {//32 antennas are Not implemented yet
+     csirep1->codebookConfig->codebookType.choice.type1->codebookMode=2;
+   }
    csirep1->dummy = NULL;
    csirep1->groupBasedBeamReporting.present = NR_CSI_ReportConfig__groupBasedBeamReporting_PR_disabled;
    csirep1->groupBasedBeamReporting.choice.disabled=calloc(1,sizeof(*csirep1->groupBasedBeamReporting.choice.disabled));
@@ -1280,71 +1298,12 @@ 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,
                            NR_CellGroupConfig_t *secondaryCellGroup,
                            NR_UE_NR_Capability_t *uecap,
-                           int dl_antenna_ports,
-                           int minRXTXTIME,
-                           int do_csirs,
-                           int do_srs,
+                           const gNB_RrcConfigurationReq *configuration,
                            int uid) {
   AssertFatal(servingcellconfigcommon!=NULL,"servingcellconfigcommon is null\n");
   AssertFatal(reconfig!=NULL,"reconfig is null\n");
@@ -1358,10 +1317,7 @@ void fill_default_reconfig(NR_ServingCellConfigCommon_t *servingcellconfigcommon
                                   uecap,
                                   1,
                                   1,
-                                  dl_antenna_ports,
-                                  minRXTXTIME,
-                                  do_csirs,
-                                  do_srs,
+                                  configuration,
                                   uid);
 
   xer_fprint(stdout, &asn_DEF_NR_CellGroupConfig, (const void*)secondaryCellGroup);
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/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/simulator.c b/targets/ARCH/rfsimulator/simulator.c
index 013e542689a54ea0982bbde323c1154d71f5ed7b..24a0348d35d6857f13bdfda34dc0f175de3aab96 100644
--- a/targets/ARCH/rfsimulator/simulator.c
+++ b/targets/ARCH/rfsimulator/simulator.c
@@ -736,10 +736,10 @@ static int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimest
                       CirSize
                     );
         else { // no channel modeling
-          double H_awgn_mimo[4][4] ={{1.0, 0.5, 0.25, 0.125},//rx 0
-                                     {0.5, 1.0, 0.5, 0.25},  //rx 1
-                                     {0.25, 0.5, 1.0, 0.5},  //rx 2
-                                     {0.125, 0.25, 0.5, 1.0}};//rx 3
+          double H_awgn_mimo[4][4] ={{1.0, 0.2, 0.1, 0.05}, //rx 0
+                                      {0.2, 1.0, 0.2, 0.1}, //rx 1
+                                     {0.1, 0.2, 1.0, 0.2}, //rx 2
+                                     {0.05, 0.1, 0.2, 1.0}};//rx 3
 
           sample_t *out=(sample_t *)samplesVoid[a];
           int nbAnt_tx = ptr->th.nbAnt;//number of Tx antennas
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/benetel-5g.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/benetel-5g.conf
index f13f20efbab0eba909eac48ade4f9fb2e773fad9..d14267dcd84f89441248b2655789c433c8a7f268 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/benetel-5g.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/benetel-5g.conf
@@ -23,8 +23,6 @@ gNBs =
     ////////// Physical parameters:
 
     ssb_SubcarrierOffset                                      = 31; //0;
-    pdsch_AntennaPorts                                        = 1;
-    pusch_AntennaPorts                                        = 1;
 	
     servingCellConfigCommon = (
     {
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band257.tm1.32PRB.usrpn300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band257.tm1.32PRB.usrpn300.conf
index 483aac6deb9a45c8e936c233054945009c4ed73a..52e4eec30e89325f4eb7f246441ff4cf6e9eb2e7 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band257.tm1.32PRB.usrpn300.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band257.tm1.32PRB.usrpn300.conf
@@ -22,8 +22,6 @@ gNBs =
     ////////// Physical parameters:
 
     ssb_SubcarrierOffset                                      = 0;
-    pdsch_AntennaPorts                                        = 1;
-    pusch_AntennaPorts                                        = 1;
 	
     servingCellConfigCommon = (
     {
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band257.tm1.32PRB.usrpx300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band257.tm1.32PRB.usrpx300.conf
index 9a91640a080d2b2ab14ed402759a35f0ba42fdd4..ab435c9686684d4b97a7b58d017dbd300eea48ee 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band257.tm1.32PRB.usrpx300.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band257.tm1.32PRB.usrpx300.conf
@@ -22,8 +22,6 @@ gNBs =
     ////////// Physical parameters:
 
     ssb_SubcarrierOffset                                      = 0;
-    pdsch_AntennaPorts                                        = 1;
-    pusch_AntennaPorts                                        = 1;
 	
     servingCellConfigCommon = (
     {
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band257.tm1.66PRB.usrpn300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band257.tm1.66PRB.usrpn300.conf
index 05c81b5c512f4e6aa62e2f8ebaa237334cb931a8..a04e0e6123f398948b5bd9f85345998f83a2c0d0 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band257.tm1.66PRB.usrpn300.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band257.tm1.66PRB.usrpn300.conf
@@ -22,9 +22,7 @@ gNBs =
     ////////// Physical parameters:
 
     ssb_SubcarrierOffset                                      = 0;
-    pdsch_AntennaPorts                                        = 1;
-    pusch_AntennaPorts                                        = 1;
-	
+
     servingCellConfigCommon = (
     {
  #spCellConfigCommon
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band261.tm1.32PRB.usrpn300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band261.tm1.32PRB.usrpn300.conf
index fbae1136b0b786c3abcdbff49ad683943e2a7a45..426f9e782b1a0cc3196af816495c936646b0828e 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band261.tm1.32PRB.usrpn300.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band261.tm1.32PRB.usrpn300.conf
@@ -22,8 +22,6 @@ gNBs =
     ////////// Physical parameters:
 
     ssb_SubcarrierOffset                                      = 0;
-    pdsch_AntennaPorts                                        = 1;
-    pusch_AntennaPorts                                        = 1;
 	
     servingCellConfigCommon = (
     {
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band66.tm1.106PRB.usrpn300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band66.tm1.106PRB.usrpn300.conf
index e5685d00a4af4575bebdd277d403e236465d174e..216728577a775fb8db3a4375894753ba49c3435f 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band66.tm1.106PRB.usrpn300.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band66.tm1.106PRB.usrpn300.conf
@@ -22,8 +22,6 @@ gNBs =
     ////////// Physical parameters:
 
     ssb_SubcarrierOffset                                      = 0;
-    pdsch_AntennaPorts                                        = 1;
-    pusch_AntennaPorts                                        = 1;
 
     servingCellConfigCommon = (
     {
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band66.tm1.106PRB.usrpx300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band66.tm1.106PRB.usrpx300.conf
index b0126589cd81461716074401e5bd1494c24908c7..59d466656c66319d08cec18df5c3d9619b20c907 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band66.tm1.106PRB.usrpx300.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band66.tm1.106PRB.usrpx300.conf
@@ -22,8 +22,6 @@ gNBs =
     ////////// Physical parameters:
 
     ssb_SubcarrierOffset                                      = 0;
-    pdsch_AntennaPorts                                        = 1;
-    pusch_AntennaPorts                                        = 1;
 
     servingCellConfigCommon = (
     {
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.106PRB.30kHz,usrpb2x0.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.106PRB.30kHz,usrpb2x0.conf
index 683cdaeb2c40885393fc285eeddff5e5e34f1631..2ae4df07d9c80b3bc2dff2ee4414799279cbcef1 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.106PRB.30kHz,usrpb2x0.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.106PRB.30kHz,usrpb2x0.conf
@@ -22,8 +22,6 @@ gNBs =
     ////////// Physical parameters:
 
     ssb_SubcarrierOffset                                      = 31;
-    pdsch_AntennaPorts                                        = 1;
-    pusch_AntennaPorts                                        = 1;
 	
     servingCellConfigCommon = (
     {
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.106PRB.slave.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.106PRB.slave.conf
index 2d85f446d7b319c79f300f85c92dd27fdc6899f4..21267870bd5e8b468c41afe7fcdd2b2cab91290e 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.106PRB.slave.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.106PRB.slave.conf
@@ -22,9 +22,7 @@ gNBs =
     ////////// Physical parameters:
 
     ssb_SubcarrierOffset                                      = 0;
-    pdsch_AntennaPorts                                        = 1;
-    pusch_AntennaPorts                                        = 1;
-	
+
     servingCellConfigCommon = (
     {
  #spCellConfigCommon
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.slave.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.slave.conf
index e1c9e9e167814760fc4dd204a2c17c8d0b8ae4db..a0fd0bda9f0221dc5c36419a17e9add1fa8f26bf 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.slave.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.slave.conf
@@ -22,8 +22,6 @@ gNBs =
     ////////// Physical parameters:
 
     ssb_SubcarrierOffset                                      = 0;
-    pdsch_AntennaPorts                                        = 1;
-    pusch_AntennaPorts                                        = 1;
 	
     servingCellConfigCommon = (
     {
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.PTRS.usrpx300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.PTRS.usrpx300.conf
index 367ced1c8a936c55fd7b8e8c49910b284c118327..5c8f90d9b5555a1ce02aa3ee8c3743c3d9c20b6f 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.PTRS.usrpx300.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.PTRS.usrpx300.conf
@@ -22,8 +22,6 @@ gNBs =
    ////////// Physical parameters:
 
    ssb_SubcarrierOffset                                           = 0;
-   pdsch_AntennaPorts                                             = 1;
-   pusch_AntennaPorts                                             = 1;
 
    servingCellConfigCommon = (
    {
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpb210.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpb210.conf
index e7d671e6a438f031d5acd08c4d546325039a8cd2..7bf3626870a6604c8a6c576347ceb7425ce6c386 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpb210.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpb210.conf
@@ -22,9 +22,7 @@ gNBs =
     ////////// Physical parameters:
 
     ssb_SubcarrierOffset                                      = 0;
-    pdsch_AntennaPorts                                        = 1;
-    pusch_AntennaPorts                                        = 1;
-	
+
     servingCellConfigCommon = (
     {
  #spCellConfigCommon
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf
index c9363da7f8e9658b03d2c39aa1108e95b17f7831..1773e1fb7921be8a563c70001243c37e547b2e44 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf
@@ -22,8 +22,6 @@ gNBs =
     ////////// Physical parameters:
 
     ssb_SubcarrierOffset                                      = 0;
-    pdsch_AntennaPorts                                        = 1;
-    pusch_AntennaPorts                                        = 1;
 
     servingCellConfigCommon = (
     {
@@ -203,7 +201,7 @@ L1s = (
 RUs = (
     {		  
          local_rf       = "yes"
-         nb_tx          = 1
+         nb_tx          = 4
          nb_rx          = 1
          att_tx         = 0
          att_rx         = 0;
@@ -217,8 +215,10 @@ RUs = (
          #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];
+         ## beamforming 2x4 matrix:
+         #bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x00007fff, 0x0000, 0x0000];
+         #beamforming 4x4 matrix:
+         bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x00007fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x00007fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x00007fff];
          sdr_addrs = "addr=192.168.10.2,mgmt_addr=192.168.10.2,second_addr=192.168.20.2";
          clock_src = "external";
     }
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpx300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpx300.conf
index 0e5ee33950fa5a5a269c9a1c3dfd71666e4cb4fc..d0f394be16a648c0efba3d26bd474647f435e674 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpx300.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpx300.conf
@@ -22,8 +22,6 @@ gNBs =
     ////////// Physical parameters:
 
     ssb_SubcarrierOffset                                      = 0;
-    pdsch_AntennaPorts                                        = 1;
-    pusch_AntennaPorts                                        = 1;
 
     servingCellConfigCommon = (
     {
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.217PRB.usrpn300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.217PRB.usrpn300.conf
index 019a0f0a363664d43f2059018e740e3ce05bbb5f..0438e61337210d1e37ec783d253b983f41d40e26 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.217PRB.usrpn300.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.217PRB.usrpn300.conf
@@ -22,8 +22,6 @@ gNBs =
     ////////// Physical parameters:
 
     ssb_SubcarrierOffset                                      = 0;
-    pdsch_AntennaPorts                                        = 1;
-    pusch_AntennaPorts                                        = 1;
 	
     servingCellConfigCommon = (
     {
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.217PRB.usrpx300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.217PRB.usrpx300.conf
index 35e742900ad5d65cd4af11ceb0bc15c6ea3021fe..66c2151eb83997cabe07d0016c269a01b71c9a10 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.217PRB.usrpx300.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.217PRB.usrpx300.conf
@@ -22,9 +22,7 @@ gNBs =
     ////////// Physical parameters:
 
     ssb_SubcarrierOffset                                      = 0;
-    pdsch_AntennaPorts                                        = 1;
-    pusch_AntennaPorts                                        = 1;
-	
+
     servingCellConfigCommon = (
     {
  #spCellConfigCommon
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.24PRB.usrpb210.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.24PRB.usrpb210.conf
index 37cde2feb1d1217615ddae9bc591e48ce12d35ee..c6ea066fc48aa0c9dae1d446f9f4d6962d438373 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.24PRB.usrpb210.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.24PRB.usrpb210.conf
@@ -22,9 +22,7 @@ gNBs =
     ////////// Physical parameters:
 
     ssb_SubcarrierOffset                                      = 0;
-    pdsch_AntennaPorts                                        = 1;
-    pusch_AntennaPorts                                        = 1;
-	
+
     servingCellConfigCommon = (
     {
  #spCellConfigCommon
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.24PRB.usrpn300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.24PRB.usrpn300.conf
index f3922404010f4d0cbb13ce684c83cea580d8a863..fcfe58a3c024e059e0417d927962531f6c16e4c6 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.24PRB.usrpn300.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.24PRB.usrpn300.conf
@@ -22,9 +22,7 @@ gNBs =
     ////////// Physical parameters:
 
     ssb_SubcarrierOffset                                      = 0;
-    pdsch_AntennaPorts                                        = 1;
-    pusch_AntennaPorts                                        = 1;
-	
+
     servingCellConfigCommon = (
     {
  #spCellConfigCommon
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.24PRB.usrpx300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.24PRB.usrpx300.conf
index 59af2a9187fbc74c0ed21f68f72a69f330fa5a7d..2ad9757cb132fa517500d2d746d4c09572ec08c3 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.24PRB.usrpx300.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.24PRB.usrpx300.conf
@@ -22,8 +22,6 @@ gNBs =
     ////////// Physical parameters:
 
     ssb_SubcarrierOffset                                      = 0;
-    pdsch_AntennaPorts                                        = 1;
-    pusch_AntennaPorts                                        = 1;
 
     servingCellConfigCommon = (
     {
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.273PRB.usrpn300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.273PRB.usrpn300.conf
index 9358c3370f5fa522554f64e96d72c38a556f8311..44074f3fd91e18a00bfe60080484594be6014ecf 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.273PRB.usrpn300.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.273PRB.usrpn300.conf
@@ -22,8 +22,6 @@ gNBs =
     ////////// Physical parameters:
 
     ssb_SubcarrierOffset                                      = 0;
-    pdsch_AntennaPorts                                        = 1;
-    pusch_AntennaPorts                                        = 1;
 	
     servingCellConfigCommon = (
     {
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band78.tm1.106PRB.nfapi.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band78.tm1.106PRB.nfapi.conf
index 004ad4db78ce18775dafe89b569f09c482143d01..7ce150506f0da42c6f2f5c67763e1ce347004dd3 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band78.tm1.106PRB.nfapi.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band78.tm1.106PRB.nfapi.conf
@@ -22,8 +22,6 @@ gNBs =
     ////////// Physical parameters:
 
     ssb_SubcarrierOffset                                      = 0;
-    pdsch_AntennaPorts                                        = 1;
-    pusch_AntennaPorts                                        = 1;
 	
     servingCellConfigCommon = (
     {
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb.conf
index 4ec53064f11c2400c3c0ab53cd069c7cd717c08f..306e652eaa9b5d1e763b3d0e97867173d03565e1 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb.conf
@@ -22,8 +22,6 @@ gNBs =
     ////////// Physical parameters:
 
     ssb_SubcarrierOffset                                      = 31; //0;
-    pdsch_AntennaPorts                                        = 1;
-    pusch_AntennaPorts                                        = 1;
 
     servingCellConfigCommon = (
     {
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb_24PRB.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb_24PRB.conf
index 7c0fa96adbb12b2ed16fcee3bcc23181e69d6165..d08c0f14a08ad55c3b0c30daf6388c416ab59cc4 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb_24PRB.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb_24PRB.conf
@@ -22,8 +22,6 @@ gNBs =
     ////////// Physical parameters:
 
     ssb_SubcarrierOffset                                      = 31; //0;
-    pdsch_AntennaPorts                                        = 1;
-    pusch_AntennaPorts                                        = 1;
 
     servingCellConfigCommon = (
     {
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb_n310.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb_n310.conf
index 57aa459d49e7b00c33eafe565b1f52caa68af29e..e3204db8faeb657aca5ea06d1da289c947266351 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb_n310.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb_n310.conf
@@ -22,8 +22,6 @@ gNBs =
     ////////// Physical parameters:
 
     ssb_SubcarrierOffset                                      = 31; //0;
-    pdsch_AntennaPorts                                        = 1;
-    pusch_AntennaPorts                                        = 1;
 	
     servingCellConfigCommon = (
     {
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb_nsa_n310.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb_nsa_n310.conf
index 89dca2a75c4892f999aa0df87a81875e7199bc46..030dc102267bafc37ce9a97b16d57cad20ae0737 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb_nsa_n310.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb_nsa_n310.conf
@@ -22,8 +22,6 @@ gNBs =
     ////////// Physical parameters:
 
     ssb_SubcarrierOffset                                      = 31; //0;
-    pdsch_AntennaPorts                                        = 1;
-    pusch_AntennaPorts                                        = 1;
     pusch_TargetSNRx10                                        = 200;
     pucch_TargetSNRx10                                        = 200;
 
diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/du_gnb.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/du_gnb.conf
index c30805a2d9b6021db0df7b3c38186a0fd70b0e3d..256d724f3ff9898e942244b2cdc8443de355e515 100644
--- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/du_gnb.conf
+++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/du_gnb.conf
@@ -37,8 +37,6 @@ gNBs =
     ////////// Physical parameters:
 
     ssb_SubcarrierOffset                                      = 0;
-    pdsch_AntennaPorts                                        = 1;
-    pusch_AntennaPorts                                        = 1;
     min_rxtxtime                                              = 6;
     sib1_tda                                                  = 0;
 
diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.band78.tm1.106PRB.usrpn300.gtp-itti.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.band78.tm1.106PRB.usrpn300.gtp-itti.conf
index b0e02ff2bc340a24667934a8a706cfc9c1f19144..726e43d7ad333ed90f1b2f86f3b4eba33d4baf85 100644
--- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.band78.tm1.106PRB.usrpn300.gtp-itti.conf
+++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.band78.tm1.106PRB.usrpn300.gtp-itti.conf
@@ -37,8 +37,6 @@ gNBs =
     ////////// Physical parameters:
 
     ssb_SubcarrierOffset                                      = 0;
-    pdsch_AntennaPorts                                        = 1;
-    pusch_AntennaPorts                                        = 1;
     sib1_tda                                                  = 0;
     servingCellConfigCommon = (
     {
diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band41.fr1.106PRB.usrpb210.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band41.fr1.106PRB.usrpb210.conf
index 9bf20b54aba8c63e71dcb7ddae9aefee8d54ec63..7e2db64aaa72bc1cb5f6e506313e13fd4aeaec6b 100644
--- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band41.fr1.106PRB.usrpb210.conf
+++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band41.fr1.106PRB.usrpb210.conf
@@ -33,8 +33,6 @@ gNBs =
     ////////// Physical parameters:
 
     ssb_SubcarrierOffset                                      = 0;
-    pdsch_AntennaPorts                                        = 1;
-    pusch_AntennaPorts                                        = 1;
     min_rxtxtime                                              = 6;
     sib1_tda                                                  = 0;
     do_SRS                                                    = 1;
diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.2x2.usrpn300.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.2x2.usrpn300.conf
index 9452f00eed10a9e21117a6522df566b9811c47cb..950e9c1d38fb18ba018f68a6506f10771a6eadfe 100644
--- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.2x2.usrpn300.conf
+++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.2x2.usrpn300.conf
@@ -33,7 +33,7 @@ gNBs =
     ////////// Physical parameters:
 
     ssb_SubcarrierOffset                                      = 0;
-    pdsch_AntennaPorts                                        = 1;
+    pdsch_AntennaPorts_N1                                     = 2;
     pusch_AntennaPorts                                        = 2;
     sib1_tda                                                  = 0;
     do_SRS                                                    = 1;
@@ -100,7 +100,7 @@ gNBs =
           prach_msg1_FDM                                            = 0;
           prach_msg1_FrequencyStart                                 = 0;
           zeroCorrelationZoneConfig                                 = 12;
-          preambleReceivedTargetPower                               = -104;
+          preambleReceivedTargetPower                               = -96;
 #preamblTransMax (0...10) = (3,4,5,6,7,8,10,20,50,100,200)
           preambleTransMax                                          = 6;
 #powerRampingStep
diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.conf
index 09cf892b917b009d9dc2729a5744330f9f242868..1dc903b811232d2b01bcacba686646823f480b34 100644
--- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.conf
+++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.conf
@@ -33,8 +33,6 @@ gNBs =
     ////////// Physical parameters:
 
     ssb_SubcarrierOffset                                      = 0;
-    pdsch_AntennaPorts                                        = 1;
-    pusch_AntennaPorts                                        = 1;
     min_rxtxtime                                              = 6;
     sib1_tda                                                  = 0;
 
diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.sabox.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.sabox.conf
index 280461d2abf9be9d65343625afbbe7a5e601081e..8ca0c0887692f7c0a0747556334c245cfc1e4cab 100644
--- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.sabox.conf
+++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.sabox.conf
@@ -31,8 +31,6 @@ gNBs =
     ////////// Physical parameters:
 
     ssb_SubcarrierOffset                                      = 0;
-    pdsch_AntennaPorts                                        = 1;
-    pusch_AntennaPorts                                        = 1;
 
      pdcch_ConfigSIB1 = (
       {
diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.162PRB.2x2.usrpn300.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.162PRB.2x2.usrpn300.conf
index fac54a298b7cf9901c6673efcb97cad30951af6b..74f8f2cb3b50f16f07cb7a3d5d66172152f7d03c 100644
--- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.162PRB.2x2.usrpn300.conf
+++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.162PRB.2x2.usrpn300.conf
@@ -33,10 +33,8 @@ gNBs =
     ////////// Physical parameters:
 
     ssb_SubcarrierOffset                                      = 0;
-    pdsch_AntennaPorts                                        = 1;
+    pdsch_AntennaPorts_N1                                     = 2;
     pusch_AntennaPorts                                        = 2;
-#    do_CSIRS                                                  = 1;
-    min_rxtxtime_pdsch                                        = 2;
     ul_prbblacklist                                           = "79,80,81,82"
     pdcch_ConfigSIB1 = (
       {
@@ -66,7 +64,7 @@ gNBs =
      #initialDownlinkBWP
       #genericParameters
        # this is RBstart=0,L=162 (275*(275-L+1))+(274-RBstart))
-       initialDLBWPlocationAndBandwidth                                        = 31899;
+       initialDLBWPlocationAndBandwidth                                        = 31624;
        #
 # subcarrierSpacing
 # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
@@ -100,7 +98,7 @@ gNBs =
       pMax                                                          = 20;
      #initialUplinkBWP
       #genericParameters
-        initialULBWPlocationAndBandwidth                                        = 31899;
+        initialULBWPlocationAndBandwidth                                        = 31624;
 # subcarrierSpacing
 # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
         initialULBWPsubcarrierSpacing                                           = 1;
@@ -112,7 +110,7 @@ gNBs =
           prach_msg1_FDM                                            = 0;
           prach_msg1_FrequencyStart                                 = 0;
           zeroCorrelationZoneConfig                                 = 12;
-          preambleReceivedTargetPower                               = -104;
+          preambleReceivedTargetPower                               = -96;
 #preamblTransMax (0...10) = (3,4,5,6,7,8,10,20,50,100,200)
           preambleTransMax                                          = 6;
 #powerRampingStep