diff --git a/ci-scripts/Jenkinsfile-trig-nsa b/ci-scripts/Jenkinsfile-trig-nsa
index 44527a1a383d6af80812e0949e763c3ecde9fb07..2dcaf1a04fef5fa7eac155d0e9098d4eaef547bd 100644
--- a/ci-scripts/Jenkinsfile-trig-nsa
+++ b/ci-scripts/Jenkinsfile-trig-nsa
@@ -56,21 +56,21 @@ pipeline {
                             booleanParam(name: 'eNB_AllowMergeRequestProcess', value: Boolean.valueOf(ALLOW_MERGE))
                         ]
                         //calling NSA long sub job
-                        build job: "RAN-NSA-Mini-Module-Long", wait : true, propagate : false, parameters: [
-                            string(name: 'eNB_MR', value: String.valueOf(MR)),                          
-                            string(name: 'eNB_Branch', value: String.valueOf(SRC_BRANCH)),
-                            string(name: 'eNB_CommitID', value: String.valueOf(COMMIT_ID)),
-                            string(name: 'eNB_TargetBranch', value: String.valueOf(TARGET_BRANCH)),
-                            booleanParam(name: 'eNB_AllowMergeRequestProcess', value: Boolean.valueOf(ALLOW_MERGE))
-                        ]
+//                        build job: "RAN-NSA-Mini-Module-Long", wait : true, propagate : false, parameters: [
+//                            string(name: 'eNB_MR', value: String.valueOf(MR)),
+//                            string(name: 'eNB_Branch', value: String.valueOf(SRC_BRANCH)),
+//                            string(name: 'eNB_CommitID', value: String.valueOf(COMMIT_ID)),
+//                            string(name: 'eNB_TargetBranch', value: String.valueOf(TARGET_BRANCH)),
+//                            booleanParam(name: 'eNB_AllowMergeRequestProcess', value: Boolean.valueOf(ALLOW_MERGE))
+//                        ]
                         //calling NSA attach/detach job
-                        build job: "RAN-NSA-Mini-Module-Attach-Detach", wait : true, propagate : false, parameters: [
-                            string(name: 'eNB_MR', value: String.valueOf(MR)),                          
-                            string(name: 'eNB_Branch', value: String.valueOf(SRC_BRANCH)),
-                            string(name: 'eNB_CommitID', value: String.valueOf(COMMIT_ID)),
-                            string(name: 'eNB_TargetBranch', value: String.valueOf(TARGET_BRANCH)),
-                            booleanParam(name: 'eNB_AllowMergeRequestProcess', value: Boolean.valueOf(ALLOW_MERGE))
-                        ]
+//                        build job: "RAN-NSA-Mini-Module-Attach-Detach", wait : true, propagate : false, parameters: [
+//                            string(name: 'eNB_MR', value: String.valueOf(MR)),
+//                            string(name: 'eNB_Branch', value: String.valueOf(SRC_BRANCH)),
+//                            string(name: 'eNB_CommitID', value: String.valueOf(COMMIT_ID)),
+//                            string(name: 'eNB_TargetBranch', value: String.valueOf(TARGET_BRANCH)),
+//                            booleanParam(name: 'eNB_AllowMergeRequestProcess', value: Boolean.valueOf(ALLOW_MERGE))
+//                        ]
 
                     }
                 }                                  
diff --git a/ci-scripts/checkCodingFormattingRules.sh b/ci-scripts/checkCodingFormattingRules.sh
index 3a2fcbb02cbba3692c65b0c597fde6edbc39d4b2..45cf08aa9afeec3a78b761b2ee5f075810601476 100755
--- a/ci-scripts/checkCodingFormattingRules.sh
+++ b/ci-scripts/checkCodingFormattingRules.sh
@@ -76,8 +76,8 @@ then
     do
        IS_NFAPI=`echo $FILE | egrep -c "nfapi/open-nFAPI|nfapi/oai_integration/vendor_ext" || true`
        IS_OAI_LICENCE_PRESENT=`egrep -c "OAI Public License" $FILE || true`
-       IS_BSD_LICENCE_PRESENT=`egrep -c "the terms of the BSD Licence" $FILE || true`
-       IS_EXCEPTION=`echo $FILE | egrep -c "common/utils/collection/tree.h|common/utils/collection/queue.h|common/utils/itti_analyzer/common/queue.h|openair3/UTILS/tree.h|openair3/UTILS/queue.h|openair3/GTPV1-U/nw-gtpv1u|openair2/UTIL/OPT/ws_|openair3/NAS/COMMON/milenage.h" || true`
+       IS_BSD_LICENCE_PRESENT=`egrep -c "the terms of the BSD Licence|License-Identifier: BSD-2-Clause" $FILE || true`
+       IS_EXCEPTION=`echo $FILE | egrep -c "common/utils/collection/tree.h|common/utils/collection/queue.h|common/utils/itti_analyzer/common/queue.h|openair3/UTILS/tree.h|openair3/UTILS/queue.h|openair3/GTPV1-U/nw-gtpv1u|openair2/UTIL/OPT/ws_|openair2/UTIL/OPT/packet-rohc.h|openair3/NAS/COMMON/milenage.h" || true`
        if [ $IS_OAI_LICENCE_PRESENT -eq 0 ] && [ $IS_BSD_LICENCE_PRESENT -eq 0 ]
        then
            if [ $IS_NFAPI -eq 0 ] && [ $IS_EXCEPTION -eq 0 ]
@@ -197,8 +197,8 @@ do
         then
             IS_NFAPI=`echo $FULLFILE | egrep -c "nfapi/open-nFAPI|nfapi/oai_integration/vendor_ext" || true`
             IS_OAI_LICENCE_PRESENT=`egrep -c "OAI Public License" $FULLFILE || true`
-            IS_BSD_LICENCE_PRESENT=`egrep -c "the terms of the BSD Licence" $FULLFILE || true`
-            IS_EXCEPTION=`echo $FULLFILE | egrep -c "common/utils/collection/tree.h|common/utils/collection/queue.h|common/utils/itti_analyzer/common/queue.h|openair3/UTILS/tree.h|openair3/UTILS/queue.h|openair3/GTPV1-U/nw-gtpv1u|openair2/UTIL/OPT/ws_|openair3/NAS/COMMON/milenage.h" || true`
+            IS_BSD_LICENCE_PRESENT=`egrep -c "the terms of the BSD Licence|License-Identifier: BSD-2-Clause" $FULLFILE || true`
+            IS_EXCEPTION=`echo $FULLFILE | egrep -c "common/utils/collection/tree.h|common/utils/collection/queue.h|common/utils/itti_analyzer/common/queue.h|openair3/UTILS/tree.h|openair3/UTILS/queue.h|openair3/GTPV1-U/nw-gtpv1u|openair2/UTIL/OPT/ws_|openair2/UTIL/OPT/packet-rohc.h|openair3/NAS/COMMON/milenage.h" || true`
             if [ $IS_OAI_LICENCE_PRESENT -eq 0 ] && [ $IS_BSD_LICENCE_PRESENT -eq 0 ]
             then
                 if [ $IS_NFAPI -eq 0 ] && [ $IS_EXCEPTION -eq 0 ]
diff --git a/ci-scripts/cls_oaicitest.py b/ci-scripts/cls_oaicitest.py
index 377592781df1c36baba3f730d5f51b0536e165e5..73141aa9b7a6878c30f1857331a3b2d93191a3d2 100644
--- a/ci-scripts/cls_oaicitest.py
+++ b/ci-scripts/cls_oaicitest.py
@@ -2222,6 +2222,24 @@ class OaiCiTest():
 
 	def Iperf_Module(self, lock, UE_IPAddress, device_id, idx, ue_num, statusQueue,EPC, Module_UE):
 		SSH = sshconnection.SSHConnection()
+		#RH temporary quick n dirty for test
+		SSH.open(EPC.IPAddress, EPC.UserName, EPC.Password)
+		cmd = 'echo ' + EPC.Password + ' | sudo -S ip link set dev tun5 mtu 1358'
+		SSH.command(cmd,'\$',5)	
+		SSH.close()
+			
+
+		#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'
+		SSH.command(cmd,'\$',5)
+		SSH.close()
+		SSH.open(EPC.IPAddress, EPC.UserName, EPC.Password)
+		cmd = 'killall --signal=SIGKILL iperf'
+		SSH.command(cmd,'\$',5)
+		SSH.close()
+
+
 		iperf_time = self.Iperf_ComputeTime()	
 		if self.iperf_direction=="DL":
 			logging.debug("Iperf for Module in DL mode detected")
@@ -2231,12 +2249,14 @@ class OaiCiTest():
 			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' 
 			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' 
 			SSH.command(cmd,'\$',int(iperf_time)*5.0)
+			SSH.close()
 			#copy the 2 resulting files locally
 			SSH.copyin(Module_UE.HostIPAddress, Module_UE.HostUsername, Module_UE.HostPassword, 'iperf_server_' + self.testCase_id + '_' + self.ue_id + '.log', '.')
 			SSH.copyin(EPC.IPAddress, EPC.UserName, EPC.Password, 'iperf_client_' + self.testCase_id + '_' + self.ue_id + '.log', '.')
@@ -2252,29 +2272,32 @@ class OaiCiTest():
 			SSH.command(cmd,'\$',5)
 			cmd = 'echo $USER; nohup iperf -s -u 2>&1 > iperf_server_' + self.testCase_id + '_' + self.ue_id + '.log'
 			SSH.command(cmd,'\$',5)
+			SSH.close()
 
 			#client side UE
 			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.close()
 
 			#copy the 2 resulting files locally
 			SSH.copyin(Module_UE.HostIPAddress, Module_UE.HostUsername, Module_UE.HostPassword, 'iperf_client_' + self.testCase_id + '_' + self.ue_id + '.log', '.')
 			SSH.copyin(EPC.IPAddress, EPC.UserName, EPC.Password, 'iperf_server_' + self.testCase_id + '_' + self.ue_id + '.log', '.')
 			#send for analysis
-			filename='iperf_client_' + self.testCase_id + '_' + self.ue_id + '.log'
+			filename='iperf_server_' + self.testCase_id + '_' + self.ue_id + '.log'
 			self.Iperf_analyzeV2Server(lock, UE_IPAddress, device_id, statusQueue, self.iperf_args,filename,1)
 		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'
 		SSH.command(cmd,'\$',5)
+		SSH.close()
 		SSH.open(EPC.IPAddress, EPC.UserName, EPC.Password)
 		cmd = 'killall --signal=SIGKILL iperf'
 		SSH.command(cmd,'\$',5)
-
 		SSH.close()
 		return
 
diff --git a/ci-scripts/conf_files/gnb.band78.sa.fr1.106PRB.usrpb210.conf b/ci-scripts/conf_files/gnb.band78.sa.fr1.106PRB.usrpb210.conf
index 494be845a694c5b3b17d913c4f8ec71ba4ea4e62..0efc071c91ff29af7225442a62afd714935cd841 100644
--- a/ci-scripts/conf_files/gnb.band78.sa.fr1.106PRB.usrpb210.conf
+++ b/ci-scripts/conf_files/gnb.band78.sa.fr1.106PRB.usrpb210.conf
@@ -142,7 +142,7 @@ gNBs =
 
         initialULBWPk2_1                      = 6;  # used for mixed slot
         initialULBWPmappingType_1             = 1;
-        initialULBWPstartSymbolAndLength_1    = 69; # this is SS=0 L=12
+        initialULBWPstartSymbolAndLength_1    = 52; # this is SS=10 L=4
 
         initialULBWPk2_2                      = 7;  # used for Msg.3 during RA
         initialULBWPmappingType_2             = 1;
@@ -225,11 +225,12 @@ gNBs =
 );
 
 MACRLCs = (
-	{
-	num_cc = 1;
-	tr_s_preference = "local_L1";
-	tr_n_preference = "local_RRC";
-        }
+    {
+        num_cc = 1;
+        tr_s_preference = "local_L1";
+        tr_n_preference = "local_RRC";
+        ulsch_max_slots_inactivity = 100;
+    }
 );
 
 L1s = (
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 bc9dcb47cc721158bb1401f0c0c07c9723cf6e28..8d32e8b792e793a9e1a3291f6153e407374c03d3 100644
--- a/ci-scripts/conf_files/gnb.band78.tm1.106PRB.usrpn300.conf
+++ b/ci-scripts/conf_files/gnb.band78.tm1.106PRB.usrpn300.conf
@@ -243,7 +243,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.10.2,mgmt_addr=192.168.10.2,second_addr=192.168.20.2";
+         sdr_addrs = "addr=192.168.30.2,mgmt_addr=192.168.30.2,second_addr=192.168.50.2";
          clock_src = "external";
     }
 );  
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 205922af0c25b6a87766bffd8c80cf7bb14db4d3..86293f2297a343711135a9cc9e1948675235a07b 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
@@ -126,7 +126,7 @@ gNBs =
 
         initialULBWPk2_1                      = 6;  # used for mixed slot
         initialULBWPmappingType_1             = 1;
-        initialULBWPstartSymbolAndLength_1    = 69; # this is SS=10 L=2
+        initialULBWPstartSymbolAndLength_1    = 52; # this is SS=10 L=4
 
         initialULBWPk2_2                      = 7;  # used for Msg.3 during RA
         initialULBWPmappingType_2             = 1;
diff --git a/ci-scripts/datalog_rt_stats.yaml b/ci-scripts/datalog_rt_stats.yaml
index 3680d2a19bdb7f484ab061dfd33db0a65d0a48b5..548caa0bddbb201fc14fdf6c6f66a142d40a5ace 100644
--- a/ci-scripts/datalog_rt_stats.yaml
+++ b/ci-scripts/datalog_rt_stats.yaml
@@ -10,15 +10,15 @@ ColNames :
 Ref : 
   feprx : 60.0
   feptx_prec : 8.0
-  feptx_ofdm : 85.0
+  feptx_ofdm : 50.0
   feptx_total : 75.0
   L1 Tx processing : 300.0
   DLSCH encoding : 230.0
   L1 Rx processing : 175.0
   PUSCH inner-receiver : 100.0
   PUSCH decoding : 140.0 
-  DL & UL scheduling timing stats : 15.0
-  UL Indication : 20.0
+  DL & UL scheduling timing stats : 37.0
+  UL Indication : 38.0
 Threshold :
   feprx : 1.25
   feptx_prec : 1.25
diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt
index b8992573cdaedce50b227cb59eea42e94a0d1a58..e7c2cbc6cdf5cc0d88fe4ccabb133fb14956ec57 100644
--- a/cmake_targets/CMakeLists.txt
+++ b/cmake_targets/CMakeLists.txt
@@ -1021,7 +1021,6 @@ add_boolean_option(PHY_TX_THREAD            False         "enable UE_EXPANSION w
 add_boolean_option(PRE_SCD_THREAD           False         "enable UE_EXPANSION with max 256 UE")
 add_boolean_option(UESIM_EXPANSION          False         "enable UESIM_EXPANSION with max 256 UE")
 add_boolean_option(ITTI_SIM                 False         "enable itti simulator")
-add_boolean_option(RFSIM_NAS                False         "enable rfsim nas")
 
 ########################
 # Include order
@@ -2464,108 +2463,6 @@ set (libnas_utils_OBJS
   ${NAS_SRC}COMMON/UTIL/OctetString.c
 )
 
-if(NAS_UE)
-  set(libnas_ue_api_OBJS
-    ${NAS_SRC}UE/API/USER/at_command.c
-    ${NAS_SRC}UE/API/USER/at_error.c
-    ${NAS_SRC}UE/API/USER/at_response.c
-    ${NAS_SRC}UE/API/USER/user_api.c
-    ${NAS_SRC}UE/API/USER/user_indication.c
-    ${NAS_SRC}UE/API/USIM/aka_functions.c
-    ${NAS_SRC}UE/API/USIM/usim_api.c
-  )
-  set(libnas_ue_emm_OBJS
-    ${NAS_SRC}UE/EMM/Attach.c
-    ${NAS_SRC}UE/EMM/Authentication.c
-    ${NAS_SRC}UE/EMM/Detach.c
-    ${NAS_SRC}UE/EMM/emm_main.c
-    ${NAS_SRC}UE/EMM/EmmStatusHdl.c
-    ${NAS_SRC}UE/EMM/Identification.c
-    ${NAS_SRC}UE/EMM/IdleMode.c
-    ${NAS_SRC}UE/EMM/LowerLayer.c
-    ${NAS_SRC}UE/EMM/SecurityModeControl.c
-    ${NAS_SRC}UE/EMM/ServiceRequestHdl.c
-    ${NAS_SRC}UE/EMM/TrackingAreaUpdate.c
-  )
-  set(libnas_ue_emm_sap_OBJS
-    ${NAS_SRC}UE/EMM/SAP/emm_as.c
-    ${NAS_SRC}UE/EMM/SAP/EmmDeregisteredAttachNeeded.c
-    ${NAS_SRC}UE/EMM/SAP/EmmDeregisteredAttemptingToAttach.c
-    ${NAS_SRC}UE/EMM/SAP/EmmDeregistered.c
-    ${NAS_SRC}UE/EMM/SAP/EmmDeregisteredInitiated.c
-    ${NAS_SRC}UE/EMM/SAP/EmmDeregisteredLimitedService.c
-    ${NAS_SRC}UE/EMM/SAP/EmmDeregisteredNoCellAvailable.c
-    ${NAS_SRC}UE/EMM/SAP/EmmDeregisteredNoImsi.c
-    ${NAS_SRC}UE/EMM/SAP/EmmDeregisteredNormalService.c
-    ${NAS_SRC}UE/EMM/SAP/EmmDeregisteredPlmnSearch.c
-    ${NAS_SRC}UE/EMM/SAP/emm_esm.c
-    ${NAS_SRC}UE/EMM/SAP/emm_fsm.c
-    ${NAS_SRC}UE/EMM/SAP/EmmNull.c
-    ${NAS_SRC}UE/EMM/SAP/emm_recv.c
-    ${NAS_SRC}UE/EMM/SAP/emm_reg.c
-    ${NAS_SRC}UE/EMM/SAP/EmmRegisteredAttemptingToUpdate.c
-    ${NAS_SRC}UE/EMM/SAP/EmmRegistered.c
-    ${NAS_SRC}UE/EMM/SAP/EmmRegisteredImsiDetachInitiated.c
-    ${NAS_SRC}UE/EMM/SAP/EmmRegisteredInitiated.c
-    ${NAS_SRC}UE/EMM/SAP/EmmRegisteredLimitedService.c
-    ${NAS_SRC}UE/EMM/SAP/EmmRegisteredNoCellAvailable.c
-    ${NAS_SRC}UE/EMM/SAP/EmmRegisteredNormalService.c
-    ${NAS_SRC}UE/EMM/SAP/EmmRegisteredPlmnSearch.c
-    ${NAS_SRC}UE/EMM/SAP/EmmRegisteredUpdateNeeded.c
-    ${NAS_SRC}UE/EMM/SAP/emm_sap.c
-    ${NAS_SRC}UE/EMM/SAP/emm_send.c
-    ${NAS_SRC}UE/EMM/SAP/EmmServiceRequestInitiated.c
-    ${NAS_SRC}UE/EMM/SAP/EmmTrackingAreaUpdatingInitiated.c
-  )
-  set (libnas_ue_esm_OBJS
-    ${NAS_SRC}UE/ESM/DedicatedEpsBearerContextActivation.c
-    ${NAS_SRC}UE/ESM/DefaultEpsBearerContextActivation.c
-    ${NAS_SRC}UE/ESM/EpsBearerContextDeactivation.c
-    ${NAS_SRC}UE/ESM/esm_ebr.c
-    ${NAS_SRC}UE/ESM/esm_ebr_context.c
-    ${NAS_SRC}UE/ESM/esm_ip.c
-    ${NAS_SRC}UE/ESM/esm_main.c
-    ${NAS_SRC}UE/ESM/esm_pt.c
-    ${NAS_SRC}UE/ESM/EsmStatusHdl.c
-    ${NAS_SRC}UE/ESM/PdnConnectivity.c
-    ${NAS_SRC}UE/ESM/PdnDisconnect.c
-  )
-  set(libnas_ue_esm_sap_OBJS
-    ${NAS_SRC}UE/ESM/SAP/esm_recv.c
-    ${NAS_SRC}UE/ESM/SAP/esm_send.c
-    ${NAS_SRC}UE/ESM/SAP/esm_sap.c
-  )
-  add_library(LIB_NAS_UE
-    ${NAS_SRC}UE/nas_itti_messaging.c
-    ${NAS_SRC}UE/nas_network.c
-    ${NAS_SRC}UE/nas_parser.c
-    ${NAS_SRC}UE/nas_proc.c
-    ${NAS_SRC}UE/nas_user.c
-    ${libnas_api_OBJS}
-    ${libnas_ue_api_OBJS}
-    ${libnas_emm_msg_OBJS}
-    ${libnas_esm_msg_OBJS}
-    ${libnas_ies_OBJS}
-    ${libnas_utils_OBJS}
-    ${libnas_ue_emm_OBJS}
-    ${libnas_ue_emm_sap_OBJS}
-    ${libnas_ue_esm_OBJS}
-    ${libnas_ue_esm_sap_OBJS}
-  )
-  add_dependencies(LIB_NAS_UE rrc_flag)
-  set(NAS_UE_LIB LIB_NAS_UE)
-
-  include_directories(${NAS_SRC}UE)
-  include_directories(${NAS_SRC}UE/API/USER)
-  include_directories(${NAS_SRC}UE/API/USIM)
-  include_directories(${NAS_SRC}UE/EMM)
-  include_directories(${NAS_SRC}UE/EMM/SAP)
-  include_directories(${NAS_SRC}UE/ESM)
-  include_directories(${NAS_SRC}UE/ESM/SAP)
-endif()
-
-
-if(ITTI_SIM OR RFSIM_NAS)
   set(libnas_ue_api_OBJS
     ${NAS_SRC}UE/API/USER/at_command.c
     ${NAS_SRC}UE/API/USER/at_error.c
@@ -2683,6 +2580,27 @@ if(ITTI_SIM OR RFSIM_NAS)
   add_dependencies(LIB_NAS_SIMUE rrc_flag)
   set(NAS_SIM_LIB LIB_NAS_SIMUE)
 
+  add_library(LIB_NAS_UE
+    ${NAS_SRC}UE/nas_itti_messaging.c
+    ${NAS_SRC}UE/nas_network.c
+    ${NAS_SRC}UE/nas_parser.c
+    ${NAS_SRC}UE/nas_proc.c
+    ${NAS_SRC}UE/nas_user.c
+    ${libnas_api_OBJS}
+    ${libnas_ue_api_OBJS}
+    ${libnas_emm_msg_OBJS}
+    ${libnas_esm_msg_OBJS}
+    ${libnas_ies_OBJS}
+    ${libnas_utils_OBJS}
+    ${libnas_ue_emm_OBJS}
+    ${libnas_ue_emm_sap_OBJS}
+    ${libnas_ue_esm_OBJS}
+    ${libnas_ue_esm_sap_OBJS}
+  )
+  add_dependencies(LIB_NAS_UE rrc_flag)
+  set(NAS_UE_LIB LIB_NAS_UE)
+
+
   include_directories(${NAS_SRC}NR_UE)
   include_directories(${NAS_SRC}UE)
   include_directories(${NAS_SRC}UE/API/USER)
@@ -2691,7 +2609,6 @@ if(ITTI_SIM OR RFSIM_NAS)
   include_directories(${NAS_SRC}UE/EMM/SAP)
   include_directories(${NAS_SRC}UE/ESM)
   include_directories(${NAS_SRC}UE/ESM/SAP)
-endif()
 
 # nbiot
 add_definitions("-DNUMBER_OF_UE_MAX_NB_IoT=16")
diff --git a/cmake_targets/autotests/test_case_list.xml b/cmake_targets/autotests/test_case_list.xml
index 29257e482f3fb745ff2fc2a3907db196191c3de8..3472b14efcf09695f156d57ee6cbd69cc89ff1b3 100755
--- a/cmake_targets/autotests/test_case_list.xml
+++ b/cmake_targets/autotests/test_case_list.xml
@@ -1101,7 +1101,9 @@
                                  (Test16: 11 PTRS, 0 Interpolated Symbols),
                                  (Test17: Mapping type A, 2 DMRS Symbols),
                                  (Test18: Mapping type A, 3 DMRS Symbols),
-                                 (Test19: Mapping type B, 4 DMRS Symbols)</desc>
+                                 (Test19: Mapping type B, 4 DMRS Symbols),
+                                 (Test20: 4x4 MIMO, 1 Layer),
+                                 (Test21: 4x4 MIMO, 2 Layers)</desc>
       <pre_compile_prog></pre_compile_prog>
       <compile_prog>$OPENAIR_DIR/cmake_targets/build_oai</compile_prog>
       <compile_prog_args> --phy_simulators  -c </compile_prog_args>
@@ -1126,8 +1128,10 @@
                   -n100 -s5 -T 2 0 4
                   -n100 -s2 -U 2 0 1
                   -n100 -s2 -U 2 0 2
-                  -n100 -s2 -U 2 1 3</main_exec_args>
-      <tags>nr_dlsim.test1 nr_dlsim.test2 nr_dlsim.test3 nr_dlsim.test4 nr_dlsim.test5 nr_dlsim.test6 nr_dlsim.test7 nr_dlsim.test8 nr_dlsim.test9 nr_dlsim.test10 nr_dlsim.test11 nr_dlsim.test12 nr_dlsim.test13 nr_dlsim.test14 nr_dlsim.test15 nr_dlsim.test16 nr_dlsim.test17 nr_dlsim.test18 nr_dlsim.test19</tags>
+                  -n100 -s2 -U 2 1 3
+                  -n10 -s20 -U 3 0 0 2 -gR -x1 -y4 -z4
+                  -n10 -s20 -U 3 0 0 2 -gR -x2 -y4 -z4</main_exec_args>
+      <tags>nr_dlsim.test1 nr_dlsim.test2 nr_dlsim.test3 nr_dlsim.test4 nr_dlsim.test5 nr_dlsim.test6 nr_dlsim.test7 nr_dlsim.test8 nr_dlsim.test9 nr_dlsim.test10 nr_dlsim.test11 nr_dlsim.test12 nr_dlsim.test13 nr_dlsim.test14 nr_dlsim.test15 nr_dlsim.test16 nr_dlsim.test17 nr_dlsim.test18 nr_dlsim.test19 nr_dlsim.test20 nr_dlsim.test21</tags>
       <search_expr_true>PDSCH test OK</search_expr_true>
       <search_expr_false>segmentation fault|assertion|exiting|fatal</search_expr_false>
       <nruns>3</nruns>
@@ -1314,11 +1318,11 @@
                       -n100 -s5 -T 2 1 2 -U 2 0 2
                       -n100 -s5 -T 2 2 2 -U 2 1 2
                       -n100 -s5 -a4 -b8 -T 2 1 2 -U 2 1 3
-                      -n100 -s2 -Z
-                      -n100 -s2 -Z -r75
-                      -n100 -s2 -Z -r216 -R217
-                      -n100 -s2 -Z -r270 -R273
-                      -n100 -s2 -Z -U 2 0 2
+                      -n100 -s5 -Z
+                      -n100 -s5 -Z -r75
+                      -n50 -s5 -Z -r216 -R217
+                      -n50 -s5 -Z -r270 -R273
+                      -n100 -s5 -Z -U 2 0 2
                       -n100 -m16 -s10 -z2</main_exec_args>
 
       <tags>nr_ulsim.test1 nr_ulsim.test2 nr_ulsim.test3 nr_ulsim.test4 nr_ulsim.test5 nr_ulsim.test6 nr_ulsim.test7 nr_ulsim.test8 nr_ulsim.test9 nr_ulsim.test10 nr_ulsim.test11 nr_ulsim.test12 nr_ulsim.test13 nr_ulsim.test14 nr_ulsim.test15</tags>
diff --git a/cmake_targets/build_oai b/cmake_targets/build_oai
index d95b30e052406ccdf9c95a957caf977d4b65134d..7e7556248eb5461705ff3beb7a0c28b3ead4ae49 100755
--- a/cmake_targets/build_oai
+++ b/cmake_targets/build_oai
@@ -68,7 +68,6 @@ USRP_REC_PLAY="False"
 BUILD_ECLIPSE=0
 NR="False"
 ITTI_SIM="False"
-RFSIM_NAS="False"
 SANITIZE_ADDRESS="False"
 OPTIONAL_LIBRARIES="telnetsrv enbscope uescope nrscope msc"
 RU=0
@@ -275,7 +274,6 @@ function main() {
             RU=0
             nrUE=1
             rfsimNas=1
-            RFSIM_NAS="True"
             NR="True"
             echo_info "Will compile NR UE"
             shift;;
@@ -633,7 +631,6 @@ function main() {
     echo "set ( SKIP_SHARED_LIB_FLAG $SKIP_SHARED_LIB_FLAG )"             >> $cmake_file
     echo "set ( RU $RU )"                                                 >> $cmake_file
     echo "set ( ITTI_SIM $ITTI_SIM )"                                     >> $cmake_file
-    echo "set ( RFSIM_NAS $RFSIM_NAS )"                                   >> $cmake_file
     echo "set ( SANITIZE_ADDRESS $SANITIZE_ADDRESS )"                     >> $cmake_file
     echo 'include(${CMAKE_CURRENT_SOURCE_DIR}/../CMakeLists.txt)'         >> $cmake_file
     cd  $DIR/$build_dir/build
diff --git a/cmake_targets/install_external_packages.ubuntu20 b/cmake_targets/install_external_packages.ubuntu20
index 4b1cda42f8c32e017afb276ed45cbba283b303b7..95293198b971c90e77ada8243831ca334e83fabb 100755
--- a/cmake_targets/install_external_packages.ubuntu20
+++ b/cmake_targets/install_external_packages.ubuntu20
@@ -159,16 +159,8 @@ install_protobuf_from_source(){
 	#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/google/protobuf/releases/download/v3.3.0/protobuf-cpp-3.3.0.tar.gz
-      tar -xzvf protobuf-cpp-3.3.0.tar.gz --owner $(id -u) --group $(id -g) --no-same-owner
-      cd protobuf-3.3.0/
-    else
-      export LD_LIBRARY_PATH=/usr/local/lib #protoc needs to know where toclook for shared libs
-      rm -rf /tmp/protobuf
-      git clone --depth=1 --branch=v3.3.0 https://github.com/protocolbuffers/protobuf.git /tmp/protobuf
-      cd /tmp/protobuf
-      git submodule update --init --recursive
-      ./autogen.sh
-    fi
+	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)"
@@ -339,6 +331,10 @@ check_install_ubuntu_packages() {
 	$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"
diff --git a/cmake_targets/tools/build_helper b/cmake_targets/tools/build_helper
index 30fdb7eb1ec860c22a855465d15d671f4e66947f..9880b66685f6097b720ad2fca8a63ba4aaade752 100755
--- a/cmake_targets/tools/build_helper
+++ b/cmake_targets/tools/build_helper
@@ -113,7 +113,7 @@ check_supported_distribution() {
         "rhel7.6")     return 0 ;;
         "rhel7.7")     return 0 ;;
         "rhel7.8")     return 0 ;;
-	"rhel7.9")     return 0 ;;
+        "rhel7.9")     return 0 ;;
         "rhel8.2")     return 0 ;;
         "rhel8.3")     return 0 ;;
         "rhel8.4")     return 0 ;;
diff --git a/common/utils/LOG/log.h b/common/utils/LOG/log.h
index 0cbae7ae2c79fa784ed078601fc71de313fad6b8..fa95d5a6fee9436755a6c42207cf1a598985742b 100644
--- a/common/utils/LOG/log.h
+++ b/common/utils/LOG/log.h
@@ -434,6 +434,7 @@ int32_t write_file_matlab(const char *fname, const char *vname, void *data, int
 
 #    define LOG_M(file, vector, data, len, dec, format) do { write_file_matlab(file, vector, data, len, dec, format, 0);} while(0)
 #    define LOG_VAR(A,B) A B
+#    define T_ACTIVE(a) (0) 
 #  endif /* T_TRACER */
 /* avoid warnings for variables only used in LOG macro's but set outside debug section */
 #define GCC_NOTUSED   __attribute__((unused))
diff --git a/common/utils/minimal_stub.c b/common/utils/minimal_stub.c
index 86454fe53f87dad750a11d7c0a1f07d67b5e5379..79e35bf7a6f8cef12bd29cb156711f5f67a884d6 100644
--- a/common/utils/minimal_stub.c
+++ b/common/utils/minimal_stub.c
@@ -1,4 +1,6 @@
+#ifndef T_TRACER
 int T_stdout;
+#endif
 
 void exit_function(const char *file, const char *function, const int line, const char *s) {
 }
diff --git a/common/utils/ocp_itti/intertask_interface.cpp b/common/utils/ocp_itti/intertask_interface.cpp
index c774da57e6176a467592ee0ce9b097aee2be4c55..4e5323aec98c85d0c807ad195bbfa6ed4f022c8e 100644
--- a/common/utils/ocp_itti/intertask_interface.cpp
+++ b/common/utils/ocp_itti/intertask_interface.cpp
@@ -136,7 +136,7 @@ extern "C" {
       LOG_E(TMR,"Queue for %s task contains %ld messages\n", itti_get_task_name(destination_task_id), s );
 
     if ( s > 50 )
-      LOG_I(TMR,"Queue for %s task size: %ld\n",itti_get_task_name(destination_task_id), s+1);
+      LOG_I(TMR,"Queue for %s task size: %ld (last message %s)\n",itti_get_task_name(destination_task_id), s+1,ITTI_MSG_NAME(message));
 
     t->message_queue.insert(t->message_queue.begin(), message);
     eventfd_t sem_counter = 1;
diff --git a/common/utils/utils.h b/common/utils/utils.h
index da7c453b0375d25165350b0bb4bcd474e14a7579..16631586c413ec7532812da13f28ecd79dd7a9c1 100644
--- a/common/utils/utils.h
+++ b/common/utils/utils.h
@@ -7,6 +7,7 @@
 extern "C" {
 #endif
 
+#define sizeofArray(a) (sizeof(a)/sizeof(*(a)))
 void *calloc_or_fail(size_t size);
 void *malloc_or_fail(size_t size);
 
diff --git a/doc/FEATURE_SET.md b/doc/FEATURE_SET.md
index 2171fc2f1fd567a655701ea92fa468d9f7c43919..7c202dc52de2c52aefdb53edebb4872b9674266e 100644
--- a/doc/FEATURE_SET.md
+++ b/doc/FEATURE_SET.md
@@ -257,7 +257,7 @@ The following features are valid for the gNB and the 5G-NR UE.
 *  FDD
 *  Normal CP
 *  30 kHz subcarrier spacing
-*  Bandwidths up to 80MHz (217 Physical Resource Blocks)
+*  Bandwidths: 10, 20, 40, 80, 100MHz (273 Physical Resource Blocks)
 *  Intermediate downlink and uplink frequencies to interface with IF equipment
 *  Single antenna port (single beam)
 *  Slot format: 14 OFDM symbols in UL or DL
@@ -277,10 +277,20 @@ The following features are valid for the gNB and the 5G-NR UE.
    - user-specific search space configured by RRC
    - DCI formats: 00, 10 (01 and 11 **under integration**)
 *  Generation of NR-PDSCH (including Segmentation, LDPC encoding, rate matching, scrambling, modulation, RB mapping, etc).
-   - Single symbol DMRS, DMRS-TypeA-Position Pos2,  DMRS configuration type 1
-   - PDSCH mapping type A
+   - PDSCH mapping type A and B
+   - DMRS configuration type 1 and 2
+   - Single and multiple DMRS symbols
+   - PTRS support
+   - Support for 1, 2 and 4 TX antennas
+   - Support for up to 2 layers (currently limited to DMRS configuration type 2)
 *  NR-CSI Generation of sequence at PHY (**under integration**)
 *  NR-PUSCH (including Segmentation, LDPC encoding, rate matching, scrambling, modulation, RB mapping, etc).
+   - PUSCH mapping type A and B
+   - DMRS configuration type 1 and 2
+   - Single and multiple DMRS symbols
+   - PTRS support
+   - Support for 1 RX antenna
+   - Support for 1 layer
 *  NR-PUCCH 
    - Format 0 (2 bits, mainly for ACK/NACK)
    - Format 2 (up to 64 bits, mainly for CSI feedback)
@@ -320,27 +330,33 @@ The following features are valid for the gNB and the 5G-NR UE.
 - Creates TUN interface to PDCP to inject and receive user-place traffic
 - Will only work with OAI gNB configured in the same mode
 
-##  UE PHY Layer ##
+##  NR UE PHY Layer ##
 
 *  Initial synchronization
 *  Time tracking based on PBCH DMRS
-*  Time tracking based on PBCH DMRS
 *  Frequency offset estimation
-*  PBCH RX
-*  PDCCH RX
-*  PDSCH RX, including a first version of dual stream receiver for PDSCH  
 *  30KHz SCS for FR1 and 120 KHz SCS for FR2
-*  Generation of NR-PSS/NR-SSS
+*  Reception of NR-PSS/NR-SSS
 *  NR-PBCH supports multiple SSBs and flexible periodicity
-*  Generation of NR-PDCCH for SIB1 (including generation of DCI, polar encoding, scrambling, modulation, RB mapping, etc)
+*  Reception of NR-PDCCH for SIB1 (including reception of DCI, polar decoding, de-scrambling, de-modulation, RB de-mapping, etc)
    - common search space configured by MIB
    - user-specific search space configured by RRC
    - DCI formats: 00, 10 (01 and 11 **under integration**)
-*  Generation of NR-PDSCH (including Segmentation, LDPC encoding, rate matching, scrambling, modulation, RB mapping, etc).
-   - Single symbol DMRS, DMRS-TypeA-Position Pos2,  DMRS configuration type 1
-   - PDSCH mapping type A
+*  Reception of NR-PDSCH (including Segmentation, LDPC decoding, rate de-matching, de-scrambling, de-modulation, RB de-mapping, etc).
+   - PDSCH mapping type A and B
+   - DMRS configuration type 1 and 2
+   - Single and multiple DMRS symbols
+   - PTRS support
+   - Support for 1, 2 and 4 RX antennas
+   - Support for up to 2 layers (currently limited to DMRS configuration type 2)
 *  NR-CSI Generation of sequence at PHY (**under integration**)
 *  NR-PUSCH (including Segmentation, LDPC encoding, rate matching, scrambling, modulation, RB mapping, etc).
+   - PUSCH mapping type A and B
+   - DMRS configuration type 1 and 2
+   - Single and multiple DMRS symbols
+   - PTRS support
+   - Support for 1 TX antenna
+   - Support for 1 layer
 *  NR-PUCCH 
    - Format 0 (2 bits, mainly for ACK/NACK)
    - Format 2 (up to 64 bits, mainly for CSI feedback)
@@ -351,7 +367,7 @@ The following features are valid for the gNB and the 5G-NR UE.
 *  Encoder and decoder for short block
 
 
-## UE Higher Layers ##
+## NR UE Higher Layers ##
 
 **UE MAC**
 *  Minimum system information (MSI)
diff --git a/executables/main-ocp.c b/executables/main-ocp.c
index c5f18419a3d397319fc106d2086423493738eab7..0355582b2b4e76848588cd22a580dd4577569ab0 100644
--- a/executables/main-ocp.c
+++ b/executables/main-ocp.c
@@ -73,7 +73,6 @@ int sync_var=-1; //!< protected by mutex \ref sync_mutex.
 int config_sync_var=-1;
 volatile int oai_exit = 0;
 double cpuf;
-msc_interface_t msc_interface;
 THREAD_STRUCT thread_struct;
 
 uint16_t sf_ahead=4;
diff --git a/executables/nr-gnb.c b/executables/nr-gnb.c
index ea675eba9e8caf737f41edff715b8135da91ac36..e9319f9d3c1070bc604662e481e352d26d4800f3 100644
--- a/executables/nr-gnb.c
+++ b/executables/nr-gnb.c
@@ -86,7 +86,7 @@
 #include "T.h"
 #include "nfapi/oai_integration/vendor_ext.h"
 #include <nfapi/oai_integration/nfapi_pnf.h>
-#include <PHY/NR_TRANSPORT/nr_ulsch.h>
+#include <openair1/PHY/NR_TRANSPORT/nr_ulsch.h>
 #include <PHY/NR_ESTIMATION/nr_ul_estimation.h>
 //#define DEBUG_THREADS 1
 
@@ -356,7 +356,7 @@ void *nrL1_stats_thread(void *param) {
   while (!oai_exit) {
     sleep(1);
     fd=fopen("nrL1_stats.log","w");
-    AssertFatal(fd!=NULL,"Cannot open ngL1_stats.log\n");
+    AssertFatal(fd!=NULL,"Cannot open nrL1_stats.log\n");
     dump_nr_I0_stats(fd,gNB);
     dump_pusch_stats(fd,gNB);
     //    nr_dump_uci_stats(fd,eNB,eNB->proc.L1_proc_tx.frame_tx);
@@ -383,6 +383,7 @@ void init_gNB_Tpool(int inst) {
     sprintf(ul_pool+2+s_offset,",-1");
     s_offset += 3;
   }
+  if (getenv("noThreads")) strcpy(ul_pool, "n");
   initTpool(ul_pool, gNB->threadPool, false);
   // ULSCH decoder result FIFO
   gNB->respDecode = (notifiedFIFO_t*) malloc(sizeof(notifiedFIFO_t));
diff --git a/executables/nr-ru.c b/executables/nr-ru.c
index 421ff4ad3ec54401399652ad2403343181a6e9b1..be6d13daad99a6d8863032cb4b07551f46a53b7d 100644
--- a/executables/nr-ru.c
+++ b/executables/nr-ru.c
@@ -746,9 +746,9 @@ void tx_rf(RU_t *ru,int frame,int slot, uint64_t timestamp) {
       // currently we switch beams every 10 slots (should = 1 TDD period in FR2) and we take the beam index of the first symbol of the first slot of this period
       int beam=0;
       if (slot%10==0) {
-	if (ru->common.beam_id[0][slot*fp->symbols_per_slot] < 8) {
-	  beam = ru->common.beam_id[0][slot*fp->symbols_per_slot] | 8;
-	}
+        if ( ru->common.beam_id && (ru->common.beam_id[0][slot*fp->symbols_per_slot] < 8)) {
+          beam = ru->common.beam_id[0][slot*fp->symbols_per_slot] | 8;
+        }
       }
       /*
       if (slot==0 || slot==40) beam=0|8;
@@ -892,6 +892,18 @@ void fill_rf_config(RU_t *ru, char *rf_config_file) {
         cfg->tx_bw = 80e6;
         cfg->rx_bw = 80e6;
       }
+      break;
+    case 133 :
+      if (fp->threequarter_fs) {
+	AssertFatal(1==0,"N_RB %d cannot use 3/4 sampling\n",N_RB);
+      }
+      else {
+        cfg->sample_rate=61.44e6;
+        cfg->samples_per_frame = 614400;
+        cfg->tx_bw = 50e6;
+        cfg->rx_bw = 50e6;
+      }
+
       break;
     case 106:
       if (fp->threequarter_fs) {
@@ -906,7 +918,7 @@ void fill_rf_config(RU_t *ru, char *rf_config_file) {
         cfg->tx_bw = 40e6;
         cfg->rx_bw = 40e6;
       }
-      break;
+     break;
     case 51:
       if (fp->threequarter_fs) {
         cfg->sample_rate=23.04e6;
@@ -2049,6 +2061,7 @@ static void NRRCconfig_RU(void)
       RC.ru[j]->att_rx                            = *(RUParamList.paramarray[j][RU_ATT_RX_IDX].uptr);
       RC.ru[j]->if_frequency                      = *(RUParamList.paramarray[j][RU_IF_FREQUENCY].u64ptr);
       RC.ru[j]->if_freq_offset                    = *(RUParamList.paramarray[j][RU_IF_FREQ_OFFSET].iptr);
+      RC.ru[j]->do_precoding                      = *(RUParamList.paramarray[j][RU_DO_PRECODING].iptr);
 
       if (config_isparamset(RUParamList.paramarray[j], RU_BF_WEIGHTS_LIST_IDX)) {
         RC.ru[j]->nb_bfw = RUParamList.paramarray[j][RU_BF_WEIGHTS_LIST_IDX].numelt;
diff --git a/executables/nr-softmodem-common.h b/executables/nr-softmodem-common.h
index 813ffcf8fac29f3060f72dbe74057fb8cb03755a..00f786dfdcfd6d0459a47357431a1595bc4c7e59 100644
--- a/executables/nr-softmodem-common.h
+++ b/executables/nr-softmodem-common.h
@@ -69,6 +69,7 @@
 #define CONFIG_HLP_EXMCAL        "Calibrate the EXMIMO borad, available files: exmimo2_2arxg.lime exmimo2_2brxg.lime \n"
 #define CONFIG_HLP_ITTIL         "Generate ITTI analyzser logs (similar to wireshark logs but with more details)\n"
 #define CONFIG_HLP_DLMCS_PHYTEST "Set the downlink MCS for PHYTEST mode\n"
+#define CONFIG_HLP_DLNL_PHYTEST "Set the downlink nrOfLayers for PHYTEST mode\n"
 #define CONFIG_HLP_STMON         "Enable processing timing measurement of lte softmodem on per subframe basis \n"
 #define CONFIG_HLP_PRB           "Set the PRB, valid values: 6, 25, 50, 100  \n"
 #define CONFIG_HLP_MSLOTS        "Skip the missed slots/subframes \n"
diff --git a/executables/nr-softmodem.h b/executables/nr-softmodem.h
index 928558013c8e6bd3dbc6bbfc4fdecbdadb5b7a43..896c363cbf15ed17d06d6ea242d8c912f9e9b4a1 100644
--- a/executables/nr-softmodem.h
+++ b/executables/nr-softmodem.h
@@ -22,6 +22,7 @@
     {"A" ,                    CONFIG_HLP_TADV,        0,                uptr:&timing_advance,               defintval:0,                   TYPE_UINT,   0},        \
     {"E" ,                    CONFIG_HLP_TQFS,        PARAMFLAG_BOOL,   i8ptr:&threequarter_fs,             defintval:0,                   TYPE_INT8,   0},        \
     {"m" ,                    CONFIG_HLP_DLMCS_PHYTEST,0,               uptr:&target_dl_mcs,                defintval:0,                   TYPE_UINT,   0},        \
+    {"l" ,                    CONFIG_HLP_DLNL_PHYTEST,0,                uptr:&target_dl_Nl,                 defintval:0,                   TYPE_UINT,   0},        \
     {"t" ,                    CONFIG_HLP_ULMCS_PHYTEST,0,               uptr:&target_ul_mcs,                defintval:0,                   TYPE_UINT,   0},        \
     {"M" ,                    CONFIG_HLP_DLBW_PHYTEST,0,                uptr:&target_dl_bw,                 defintval:0,                   TYPE_UINT,   0},        \
     {"T" ,                    CONFIG_HLP_ULBW_PHYTEST,0,                uptr:&target_ul_bw,                 defintval:0,                   TYPE_UINT,   0},        \
@@ -34,6 +35,7 @@
 #include "threads_t.h"
 extern threads_t threads;
 extern uint32_t target_dl_mcs;
+extern uint32_t target_dl_Nl;
 extern uint32_t target_ul_mcs;
 extern uint32_t target_dl_bw;
 extern uint32_t target_ul_bw;
diff --git a/executables/nr-uesoftmodem.c b/executables/nr-uesoftmodem.c
index cbc79912a2c96f0b1679790e72695702dc2008fd..23982c6bc33ffc579b4cf589a00cafc8a5fea007 100644
--- a/executables/nr-uesoftmodem.c
+++ b/executables/nr-uesoftmodem.c
@@ -86,9 +86,7 @@ unsigned short config_frames[4] = {2,9,11,13};
 #include "executables/softmodem-common.h"
 #include "executables/thread-common.h"
 
-#if defined(ITTI_SIM) || defined(RFSIM_NAS)
 #include "nr_nas_msg_sim.h"
-#endif
 
 extern const char *duplex_mode[];
 THREAD_STRUCT thread_struct;
@@ -195,12 +193,10 @@ int create_tasks_nrue(uint32_t ue_nb) {
       LOG_E(NR_RRC, "Create task for RRC UE failed\n");
       return -1;
     }
-#if defined(ITTI_SIM) || defined(RFSIM_NAS)
   if (itti_create_task (TASK_NAS_NRUE, nas_nrue_task, NULL) < 0) {
     LOG_E(NR_RRC, "Create task for NAS UE failed\n");
     return -1;
   }
-#endif
   }
 
   itti_wait_ready(0);
@@ -364,8 +360,8 @@ void init_openair0(void) {
     openair0_cfg[card].num_rb_dl = frame_parms->N_RB_DL;
     openair0_cfg[card].clock_source = get_softmodem_params()->clock_source;
     openair0_cfg[card].time_source = get_softmodem_params()->timing_source;
-    openair0_cfg[card].tx_num_channels = min(2, frame_parms->nb_antennas_tx);
-    openair0_cfg[card].rx_num_channels = min(2, frame_parms->nb_antennas_rx);
+    openair0_cfg[card].tx_num_channels = min(4, frame_parms->nb_antennas_tx);
+    openair0_cfg[card].rx_num_channels = min(4, frame_parms->nb_antennas_rx);
 
     LOG_I(PHY, "HW: Configuring card %d, sample_rate %f, tx/rx num_channels %d/%d, duplex_mode %s\n",
       card,
diff --git a/openair1/PHY/INIT/nr_init.c b/openair1/PHY/INIT/nr_init.c
index f9be62797472f1f3cc7b96977bc1bc08ab4b755e..dcff18f02580f14aefc17d649c798ab1b6b23e42 100644
--- a/openair1/PHY/INIT/nr_init.c
+++ b/openair1/PHY/INIT/nr_init.c
@@ -595,27 +595,6 @@ void init_nr_transport(PHY_VARS_gNB *gNB) {
         exit(-1);
       }
 
-      /*
-      LOG_I(PHY,"Initializing nFAPI for ULSCH, UE %d\n",i);
-      // [hna] added here for RT implementation
-      uint8_t harq_pid = 0;
-      nfapi_nr_ul_config_ulsch_pdu *rel15_ul = &gNB->ulsch[i+1][j]->harq_processes[harq_pid]->ulsch_pdu;
-  
-      // --------- setting rel15_ul parameters ----------
-      rel15_ul->rnti                           = 0x1234;
-      rel15_ul->ulsch_pdu_rel15.start_rb       = 0;
-      rel15_ul->ulsch_pdu_rel15.number_rbs     = 50;
-      rel15_ul->ulsch_pdu_rel15.start_symbol   = 2;
-      rel15_ul->ulsch_pdu_rel15.number_symbols = 12;
-      rel15_ul->ulsch_pdu_rel15.length_dmrs    = gNB->dmrs_UplinkConfig.pusch_maxLength;
-      rel15_ul->ulsch_pdu_rel15.Qm             = 2;
-      rel15_ul->ulsch_pdu_rel15.R              = 679;
-      rel15_ul->ulsch_pdu_rel15.mcs            = 9;
-      rel15_ul->ulsch_pdu_rel15.rv             = 0;
-      rel15_ul->ulsch_pdu_rel15.n_layers       = 1;
-      ///////////////////////////////////////////////////
-      */
-
     }
 
   }
diff --git a/openair1/PHY/INIT/nr_init_ru.c b/openair1/PHY/INIT/nr_init_ru.c
index 8189a7ab341b6ab266df8633e050c3aaf503fe1b..097c2b3ad2dd4e6b95ac5859a23b541070b64a92 100644
--- a/openair1/PHY/INIT/nr_init_ru.c
+++ b/openair1/PHY/INIT/nr_init_ru.c
@@ -122,36 +122,39 @@ int nr_phy_init_RU(RU_t *ru) {
 		ru->num_gNB,NUMBER_OF_gNB_MAX);
 
     LOG_I(PHY,"[INIT] %s() ru->num_gNB:%d \n", __FUNCTION__, ru->num_gNB);
+
+    if (ru->do_precoding == 1) {
+      int beam_count = 0;
+      if (ru->nb_tx>1) {//Enable beamforming when nb_tx > 1
+        for (p=0;p<ru->nb_log_antennas;p++) {
+          //if ((fp->L_ssb >> (63-p)) & 0x01)//64 bit-map with the MSB @2⁶³ corresponds to SSB ssb_index 0
+            beam_count++;
+        }
+        AssertFatal(ru->nb_bfw==(beam_count*ru->nb_tx),"Number of beam weights from config file is %d while the expected number is %d",ru->nb_bfw,(beam_count*ru->nb_tx));
     
-    int beam_count = 0;
-    if (ru->nb_tx>1) {//Enable beamforming when nb_tx > 1
-      for (p=0;p<ru->nb_log_antennas;p++) {
-        //if ((fp->L_ssb >> (63-p)) & 0x01)//64 bit-map with the MSB @2⁶³ corresponds to SSB ssb_index 0
-          beam_count++;
-      }
-      AssertFatal(ru->nb_bfw==(beam_count*ru->nb_tx),"Number of beam weights from config file is %d while the expected number is %d",ru->nb_bfw,(beam_count*ru->nb_tx));
-    
-      int l_ind = 0;
       for (i=0; i<ru->num_gNB; i++) {
+        int l_ind = 0;
         for (p=0;p<ru->nb_log_antennas;p++) {
           //if ((fp->L_ssb >> (63-p)) & 0x01)  {
-	    ru->beam_weights[i][p] = (int32_t **)malloc16_clear(ru->nb_tx*sizeof(int32_t*));
-	    for (j=0; j<ru->nb_tx; j++) {
-	      ru->beam_weights[i][p][j] = (int32_t *)malloc16_clear(fp->ofdm_symbol_size*sizeof(int32_t));
-              for (re=0; re<fp->ofdm_symbol_size; re++) 
-		ru->beam_weights[i][p][j][re] = ru->bw_list[j][l_ind];
-              //printf("Beam Weight %08x for beam %d and tx %d\n",ru->bw_list[i][l_ind],p,j);
-              l_ind++; 
-  	    } // for j
-	  //}
+          ru->beam_weights[i][p] = (int32_t **)malloc16_clear(ru->nb_tx*sizeof(int32_t*));
+          for (j=0; j<ru->nb_tx; j++) {
+            ru->beam_weights[i][p][j] = (int32_t *)malloc16_clear(fp->ofdm_symbol_size*sizeof(int32_t));
+            AssertFatal(ru->bw_list[i],"ru->bw_list[%d] is null\n",i);
+            for (re=0; re<fp->ofdm_symbol_size; re++)
+              ru->beam_weights[i][p][j][re] = ru->bw_list[i][l_ind];
+            //printf("Beam Weight %08x for beam %d and tx %d\n",ru->bw_list[i][l_ind],p,j);
+            l_ind++;
+          } // for j
+          //}
         } // for p
       } //for i
-    }
+      }
 
-    ru->common.beam_id = (uint8_t**)malloc16_clear(ru->nb_tx*sizeof(uint8_t*));
-    for(i=0; i< ru->nb_tx; ++i) {
-      ru->common.beam_id[i] = (uint8_t*)malloc16_clear(fp->symbols_per_slot*fp->slots_per_frame*sizeof(uint8_t));
-      memset(ru->common.beam_id[i],255,fp->symbols_per_slot*fp->slots_per_frame);
+      ru->common.beam_id = (uint8_t**)malloc16_clear(ru->nb_tx*sizeof(uint8_t*));
+      for(i=0; i< ru->nb_tx; ++i) {
+        ru->common.beam_id[i] = (uint8_t*)malloc16_clear(fp->symbols_per_slot*fp->slots_per_frame*sizeof(uint8_t));
+        memset(ru->common.beam_id[i],255,fp->symbols_per_slot*fp->slots_per_frame);
+      }
     }
   } // !=IF5
 
diff --git a/openair1/PHY/INIT/nr_init_ue.c b/openair1/PHY/INIT/nr_init_ue.c
index a9c71d158256b3cbfdb5631977958fb34f19c6a5..68947b0c6bdf4b09b58c878500035c299172e245 100644
--- a/openair1/PHY/INIT/nr_init_ue.c
+++ b/openair1/PHY/INIT/nr_init_ue.c
@@ -143,8 +143,6 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue,
   uint16_t N_n_scid[2] = {0,1}; // [HOTFIX] This is a temporary implementation of scramblingID0 and scramblingID1 which are given by DMRS-UplinkConfig
   int n_scid;
   abstraction_flag = 0;
-  // dmrs_UplinkConfig_t *dmrs_Uplink_Config = &ue->pusch_config.dmrs_UplinkConfig;
-  // ptrs_UplinkConfig_t *ptrs_Uplink_Config = &ue->pusch_config.dmrs_UplinkConfig.ptrs_UplinkConfig;
   LOG_I(PHY, "Initializing UE vars (abstraction %u) for gNB TXant %u, UE RXant %u\n", abstraction_flag, fp->nb_antennas_tx, fp->nb_antennas_rx);
   //LOG_D(PHY,"[MSC_NEW][FRAME 00000][PHY_UE][MOD %02u][]\n", ue->Mod_id+NB_gNB_INST);
   phy_init_nr_top(ue);
@@ -188,29 +186,6 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue,
 
   /////////////////////////PUSCH DMRS init/////////////////////////
   ///////////
-
-  // default values until overwritten by RRCConnectionReconfiguration
-
-  for (i=0; i<MAX_NR_OF_UL_ALLOCATIONS; i++) {
-    ue->pusch_config.pusch_TimeDomainResourceAllocation[i] = (PUSCH_TimeDomainResourceAllocation_t *)malloc16(sizeof(PUSCH_TimeDomainResourceAllocation_t));
-    ue->pusch_config.pusch_TimeDomainResourceAllocation[i]->mappingType = typeB;
-  }
-
-  for (i=0;i<MAX_NR_OF_DL_ALLOCATIONS;i++){
-    ue->PDSCH_Config.pdsch_TimeDomainResourceAllocation[i] = (PDSCH_TimeDomainResourceAllocation_t *)malloc16(sizeof(PDSCH_TimeDomainResourceAllocation_t));
-    ue->PDSCH_Config.pdsch_TimeDomainResourceAllocation[i]->mappingType = typeA;
-  }
-
-  //------------- config DMRS parameters--------------//
-  // dmrs_Uplink_Config->pusch_dmrs_type = pusch_dmrs_type1;
-  // dmrs_Uplink_Config->pusch_dmrs_AdditionalPosition = pusch_dmrs_pos0;
-  // dmrs_Uplink_Config->pusch_maxLength = pusch_len1;
-  //-------------------------------------------------//
-  ue->dmrs_DownlinkConfig.pdsch_dmrs_type = pdsch_dmrs_type1;
-  ue->dmrs_DownlinkConfig.pdsch_dmrs_AdditionalPosition = pdsch_dmrs_pos0;
-  ue->dmrs_DownlinkConfig.pdsch_maxLength = pdsch_len1;
-  //-------------------------------------------------//
-
   ue->nr_gold_pusch_dmrs = (uint32_t ****)malloc16(fp->slots_per_frame*sizeof(uint32_t ***));
   pusch_dmrs             = ue->nr_gold_pusch_dmrs;
   n_scid = 0; // This quantity is indicated by higher layer parameter dmrs-SeqInitialization
diff --git a/openair1/PHY/LTE_TRANSPORT/transport_common.h b/openair1/PHY/LTE_TRANSPORT/transport_common.h
index 93ca7195deeb40a6f9a312ea7ec8134d5ef59556..135f3cdf4bb1b372e775f42e4cbfe04590748568 100644
--- a/openair1/PHY/LTE_TRANSPORT/transport_common.h
+++ b/openair1/PHY/LTE_TRANSPORT/transport_common.h
@@ -65,22 +65,6 @@
 #define MAX_NUM_CHANNEL_BITS (14*1200*6)  // 14 symbols, 1200 REs, 12 bits/RE
 #define MAX_NUM_RE (14*1200)
 
-#if !defined(SI_RNTI)
-  #define SI_RNTI  (rnti_t)0xffff
-  #define SI_RNTI_MBMS  (rnti_t)0xfff9
-#endif
-#if !defined(M_RNTI)
-  #define M_RNTI   (rnti_t)0xfffd
-#endif
-#if !defined(P_RNTI)
-  #define P_RNTI   (rnti_t)0xfffe
-#endif
-#if !defined(CBA_RNTI)
-  #define CBA_RNTI (rnti_t)0xfff4
-#endif
-#if !defined(C_RNTI)
-  #define C_RNTI   (rnti_t)0x1234
-#endif
 // These are the codebook indexes according to Table 6.3.4.2.3-1 of 36.211
 //1 layer
 #define PMI_2A_11  0
diff --git a/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c b/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c
index 5a4b1adbb84ff7dc7a273f223606d058e7ce615d..920b78eac2b0880311bbac733c9b4fcbcd84ca76 100644
--- a/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c
+++ b/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c
@@ -111,9 +111,10 @@ int nr_pdsch_dmrs_rx(PHY_VARS_NR_UE *ue,
                      int32_t *output,
                      unsigned short p,
                      unsigned char lp,
-                     unsigned short nb_pdsch_rb)
+                     unsigned short nb_pdsch_rb,
+                     uint8_t config_type)
 {
-  int8_t w,config_type;
+  int8_t w;
   short *mod_table;
   unsigned char idx=0;
 
@@ -121,18 +122,16 @@ int nr_pdsch_dmrs_rx(PHY_VARS_NR_UE *ue,
   array_of_w *wf;
   array_of_w *wt;
 
-  config_type = ue->dmrs_DownlinkConfig.pdsch_dmrs_type;
-
-  wf = (config_type==pdsch_dmrs_type1) ? wf1 : wf2;
-  wt = (config_type==pdsch_dmrs_type1) ? wt1 : wt2;
+  wf = (config_type==NFAPI_NR_DMRS_TYPE1) ? wf1 : wf2;
+  wt = (config_type==NFAPI_NR_DMRS_TYPE1) ? wt1 : wt2;
 
   if (config_type > 1)
     LOG_E(PHY,"Bad PDSCH DMRS config type %d\n", config_type);
 
-  if ((p>=1000) && (p<((config_type==pdsch_dmrs_type1) ? 1008 : 1012))) {
+  if ((p>=1000) && (p<((config_type==NFAPI_NR_DMRS_TYPE1) ? 1008 : 1012))) {
       if (ue->frame_parms.Ncp == NORMAL) {
 
-        for (int i=0; i<nb_pdsch_rb*((config_type==pdsch_dmrs_type1) ? 6:4); i++) {
+        for (int i=0; i<nb_pdsch_rb*((config_type==NFAPI_NR_DMRS_TYPE1) ? 6:4); i++) {
 
         	w = (wf[p-1000][i&1])*(wt[p-1000][lp]);
         	mod_table = (w==1) ? nr_rx_mod_table : nr_rx_nmod_table;
diff --git a/openair1/PHY/NR_REFSIG/refsig_defs_ue.h b/openair1/PHY/NR_REFSIG/refsig_defs_ue.h
index 54279a8ad5faf85ace67cc4d4a477db15ce151af..1fca2be2a187dd7643d7898ccfba7bd71b09e94c 100644
--- a/openair1/PHY/NR_REFSIG/refsig_defs_ue.h
+++ b/openair1/PHY/NR_REFSIG/refsig_defs_ue.h
@@ -52,7 +52,8 @@ int nr_pdsch_dmrs_rx(PHY_VARS_NR_UE *ue,
                      int32_t *output,
                      unsigned short p,
                      unsigned char lp,
-                     unsigned short nb_pdsch_rb);
+                     unsigned short nb_pdsch_rb,
+                     uint8_t config_type);
 
 void nr_gold_pbch(PHY_VARS_NR_UE* ue);
 
diff --git a/openair1/PHY/NR_TRANSPORT/nr_dci.c b/openair1/PHY/NR_TRANSPORT/nr_dci.c
index ea9675618422895ad556652a0fc8933b13849ebd..54e6b2ac79a497a7660061e738ecea606dba99db 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_dci.c
+++ b/openair1/PHY/NR_TRANSPORT/nr_dci.c
@@ -70,7 +70,7 @@ void nr_generate_dci(PHY_VARS_gNB *gNB,
                         uint32_t **gold_pdcch_dmrs,
                         int32_t *txdataF,
                         int16_t amp,
-                        NR_DL_FRAME_PARMS frame_parms) {
+                        NR_DL_FRAME_PARMS *frame_parms) {
 
   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;
@@ -85,7 +85,7 @@ void nr_generate_dci(PHY_VARS_gNB *gNB,
   // compute rb_offset and n_prb based on frequency allocation
   nr_fill_cce_list(gNB,0,pdcch_pdu_rel15);
   get_coreset_rballoc(pdcch_pdu_rel15->FreqDomainResource,&n_rb,&rb_offset);
-  cset_start_sc = frame_parms.first_carrier_offset + (pdcch_pdu_rel15->BWPStart + rb_offset) * NR_NB_SC_PER_RB;
+  cset_start_sc = frame_parms->first_carrier_offset + (pdcch_pdu_rel15->BWPStart + rb_offset) * NR_NB_SC_PER_RB;
 
   for (int d=0;d<pdcch_pdu_rel15->numDlDci;d++) {
     /*The coreset is initialised
@@ -94,7 +94,6 @@ void nr_generate_dci(PHY_VARS_gNB *gNB,
      * 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];
 
-    LOG_D(PHY,"DCI pdu %d, rnti %x, aggregation %d CCE %d Scrambling_Id %x ScramblingRNTI %x PayloadSizeBits %d\n",d,dci_pdu->RNTI,dci_pdu->AggregationLevel,dci_pdu->CceIndex,dci_pdu->ScramblingId,dci_pdu->ScramblingRNTI,dci_pdu->PayloadSizeBits);
     cset_start_symb = pdcch_pdu_rel15->StartSymbolIndex;
     cset_nsymb = pdcch_pdu_rel15->DurationSymbols;
     dci_idx = 0;
@@ -165,8 +164,8 @@ void nr_generate_dci(PHY_VARS_gNB *gNB,
 
     /// Resource mapping
 
-    if (cset_start_sc >= frame_parms.ofdm_symbol_size)
-      cset_start_sc -= frame_parms.ofdm_symbol_size;
+    if (cset_start_sc >= frame_parms->ofdm_symbol_size)
+      cset_start_sc -= frame_parms->ofdm_symbol_size;
 
     // Get cce_list indices by reg_idx in ascending order
     int reg_list_index = 0;
@@ -191,8 +190,8 @@ void nr_generate_dci(PHY_VARS_gNB *gNB,
 
           k = cset_start_sc + gNB->cce_list[d][cce_idx].reg_list[reg_in_cce_idx].start_sc_idx;
 
-          if (k >= frame_parms.ofdm_symbol_size)
-            k -= frame_parms.ofdm_symbol_size;
+          if (k >= frame_parms->ofdm_symbol_size)
+            k -= frame_parms->ofdm_symbol_size;
 
           l = cset_start_symb + symbol_idx;
 
@@ -206,26 +205,26 @@ void nr_generate_dci(PHY_VARS_gNB *gNB,
 
           for (int m = 0; m < NR_NB_SC_PER_RB; m++) {
             if (m == (k_prime << 2) + 1) { // DMRS if not already mapped
-              ((int16_t *) txdataF)[(l * frame_parms.ofdm_symbol_size + k) << 1] =
+              ((int16_t *) txdataF)[(l * frame_parms->ofdm_symbol_size + k) << 1] =
                   (amp * mod_dmrs[l][dmrs_idx << 1]) >> 15;
-              ((int16_t *) txdataF)[((l * frame_parms.ofdm_symbol_size + k) << 1) + 1] =
+              ((int16_t *) txdataF)[((l * frame_parms->ofdm_symbol_size + k) << 1) + 1] =
                   (amp * mod_dmrs[l][(dmrs_idx << 1) + 1]) >> 15;
 
 #ifdef DEBUG_PDCCH_DMRS
-              printf("PDCCH DMRS: l %d position %d => (%d,%d)\n",l,k,((int16_t *)txdataF)[(l*frame_parms.ofdm_symbol_size + k)<<1],
-               ((int16_t *)txdataF)[((l*frame_parms.ofdm_symbol_size + k)<<1)+1]);
+              printf("PDCCH DMRS: l %d position %d => (%d,%d)\n",l,k,((int16_t *)txdataF)[(l*frame_parms->ofdm_symbol_size + k)<<1],
+               ((int16_t *)txdataF)[((l*frame_parms->ofdm_symbol_size + k)<<1)+1]);
 #endif
 
               dmrs_idx++;
               k_prime++;
 
             } else { // DCI payload
-              ((int16_t *) txdataF)[(l * frame_parms.ofdm_symbol_size + k) << 1] = (amp * mod_dci[dci_idx << 1]) >> 15;
-              ((int16_t *) txdataF)[((l * frame_parms.ofdm_symbol_size + k) << 1) + 1] =
+              ((int16_t *) txdataF)[(l * frame_parms->ofdm_symbol_size + k) << 1] = (amp * mod_dci[dci_idx << 1]) >> 15;
+              ((int16_t *) txdataF)[((l * frame_parms->ofdm_symbol_size + k) << 1) + 1] =
                   (amp * mod_dci[(dci_idx << 1) + 1]) >> 15;
 #ifdef DEBUG_DCI
-              printf("PDCCH: l %d position %d => (%d,%d)\n",l,k,((int16_t *)txdataF)[(l*frame_parms.ofdm_symbol_size + k)<<1],
-               ((int16_t *)txdataF)[((l*frame_parms.ofdm_symbol_size + k)<<1)+1]);
+              printf("PDCCH: l %d position %d => (%d,%d)\n",l,k,((int16_t *)txdataF)[(l*frame_parms->ofdm_symbol_size + k)<<1],
+               ((int16_t *)txdataF)[((l*frame_parms->ofdm_symbol_size + k)<<1)+1]);
 #endif
 
               dci_idx++;
@@ -233,8 +232,8 @@ void nr_generate_dci(PHY_VARS_gNB *gNB,
 
             k++;
 
-            if (k >= frame_parms.ofdm_symbol_size)
-              k -= frame_parms.ofdm_symbol_size;
+            if (k >= frame_parms->ofdm_symbol_size)
+              k -= frame_parms->ofdm_symbol_size;
 
           } // m
         } // reg_in_cce_idx
@@ -254,17 +253,15 @@ void nr_generate_dci_top(PHY_VARS_gNB *gNB,
                             uint32_t **gold_pdcch_dmrs,
                             int32_t *txdataF,
                             int16_t amp,
-                            NR_DL_FRAME_PARMS frame_parms) {
+                            NR_DL_FRAME_PARMS *frame_parms) {
 
   AssertFatal(pdcch_pdu!=NULL || ul_dci_pdu!=NULL,"At least one pointer has to be !NULL\n");
 
-  if (pdcch_pdu && ul_dci_pdu) {
+  if (pdcch_pdu) {
     nr_generate_dci(gNB,&pdcch_pdu->pdcch_pdu_rel15,gold_pdcch_dmrs,txdataF,amp,frame_parms);
-    nr_generate_dci(gNB,&ul_dci_pdu->pdcch_pdu_rel15,gold_pdcch_dmrs,txdataF,amp,frame_parms);
   }
-  else if (pdcch_pdu)
-    nr_generate_dci(gNB,&pdcch_pdu->pdcch_pdu_rel15,gold_pdcch_dmrs,txdataF,amp,frame_parms);
-  else
+  if (ul_dci_pdu) {
     nr_generate_dci(gNB,&ul_dci_pdu->pdcch_pdu_rel15,gold_pdcch_dmrs,txdataF,amp,frame_parms);
+  }
 }
 
diff --git a/openair1/PHY/NR_TRANSPORT/nr_dci.h b/openair1/PHY/NR_TRANSPORT/nr_dci.h
index 1b57acc6f40ff7edb2352486a827b9d446d6e55f..e3b53f9cf9658656cb5bb5132b1f3a65b2ad98bc 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_dci.h
+++ b/openair1/PHY/NR_TRANSPORT/nr_dci.h
@@ -35,7 +35,7 @@ void nr_generate_dci_top(PHY_VARS_gNB *gNB,
 			    uint32_t **gold_pdcch_dmrs,
                             int32_t *txdataF,
                             int16_t amp,
-                            NR_DL_FRAME_PARMS frame_parms);
+                            NR_DL_FRAME_PARMS *frame_parms);
 
 void nr_pdcch_scrambling(uint32_t *in,
                          uint32_t size,
diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch.c b/openair1/PHY/NR_TRANSPORT/nr_dlsch.c
index b1dbc7c7d94fe8a879150098c67fac07acdb8205..03bd0ddf6cffc715982fe69d38e95d597442b437 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_dlsch.c
+++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch.c
@@ -448,7 +448,7 @@ uint8_t nr_generate_pdsch(PHY_VARS_gNB *gNB,
                      (void*)&txdataF_precoding[ap][2*(l*frame_parms->ofdm_symbol_size + txdataF_offset+ k)],
                      NR_NB_SC_PER_RB*sizeof(int32_t));
             else
-              memset((void*)&txdataF[ap][rel15->StartSymbolIndex*frame_parms->ofdm_symbol_size + txdataF_offset +k],
+              memset((void*)&txdataF[ap][l*frame_parms->ofdm_symbol_size + txdataF_offset + k],
                      0,
                      NR_NB_SC_PER_RB*sizeof(int32_t));
             k += NR_NB_SC_PER_RB;
diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c b/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c
index 1e372eb9e0b75704c3750e5eaadbd499440c8330..2ae2549df31743e6d7263e1087c8d0714bf34091 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c
+++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c
@@ -192,14 +192,15 @@ NR_gNB_DLSCH_t *new_gNB_dlsch(NR_DL_FRAME_PARMS *frame_parms,
     AssertFatal(harq->d[r], "cannot allocate harq->d[%d]\n", r); // max size for coded output
     bzero(harq->c[r], 8448);
     bzero(harq->d[r], (3 * 8448));
-    harq->e = malloc16(14 * N_RB * 12 * 8);
-    AssertFatal(harq->e, "cannot allocate harq->e\n");
-    bzero(harq->e, 14 * N_RB * 12 * 8);
-    harq->f = malloc16(14 * N_RB * 12 * 8);
-    AssertFatal(harq->f, "cannot allocate harq->f\n");
-    bzero(harq->f, 14 * N_RB * 12 * 8);
   }
 
+  harq->e = malloc16(N_RB * NR_SYMBOLS_PER_SLOT * NR_NB_SC_PER_RB * 8 * NR_MAX_NB_LAYERS);
+  AssertFatal(harq->e, "cannot allocate harq->e\n");
+  bzero(harq->e, N_RB * NR_SYMBOLS_PER_SLOT * NR_NB_SC_PER_RB * 8 * NR_MAX_NB_LAYERS);
+  harq->f = malloc16(N_RB * NR_SYMBOLS_PER_SLOT * NR_NB_SC_PER_RB * 8 * NR_MAX_NB_LAYERS);
+  AssertFatal(harq->f, "cannot allocate harq->f\n");
+  bzero(harq->f, N_RB * NR_SYMBOLS_PER_SLOT * NR_NB_SC_PER_RB * 8 * NR_MAX_NB_LAYERS);
+
   return(dlsch);
 }
 
@@ -267,6 +268,8 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB,
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_DLSCH_ENCODING, VCD_FUNCTION_IN);
 
   A = rel15->TBSize[0]<<3;
+  if ( dlsch->rnti != SI_RNTI )
+     trace_NRpdu(DIRECTION_DOWNLINK, a, rel15->TBSize[0], 0, WS_C_RNTI, dlsch->rnti, frame, slot,0, 0);
 
   NR_gNB_SCH_STATS_t *stats=NULL;
   int first_free=-1;
diff --git a/openair1/PHY/NR_TRANSPORT/nr_prach.c b/openair1/PHY/NR_TRANSPORT/nr_prach.c
index 34c647810d7ef73712ee08c53374158ea9d90cae..000348ae8728ef2fd2656f86db9ba317c827c5a6 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_prach.c
+++ b/openair1/PHY/NR_TRANSPORT/nr_prach.c
@@ -858,38 +858,50 @@ void rx_nr_prach(PHY_VARS_gNB *gNB,
 
       memset(prachF, 0, sizeof(int16_t)*2*1024 );
       if (LOG_DUMPFLAG(PRACH)) {      
-	LOG_M("prach_rxF0.m","prach_rxF0",rxsigF[0],N_ZC,1,1);
-	LOG_M("prach_rxF1.m","prach_rxF1",rxsigF[1],6144,1,1);
+	       LOG_M("prach_rxF0.m","prach_rxF0",rxsigF[0],N_ZC,1,1);
+	       LOG_M("prach_rxF1.m","prach_rxF1",rxsigF[1],6144,1,1);
       }
    
       for (aa=0;aa<nb_rx; aa++) {
 	// Do componentwise product with Xu* on each antenna 
 
-	for (offset=0; offset<(N_ZC<<1); offset+=2) {
-	  prachF[offset]   = (int16_t)(((int32_t)Xu[offset]*rxsigF[aa][offset]   + (int32_t)Xu[offset+1]*rxsigF[aa][offset+1])>>15);
-	  prachF[offset+1] = (int16_t)(((int32_t)Xu[offset]*rxsigF[aa][offset+1] - (int32_t)Xu[offset+1]*rxsigF[aa][offset])>>15);
-	}
+	       for (offset=0; offset<(N_ZC<<1); offset+=2) {
+	          prachF[offset]   = (int16_t)(((int32_t)Xu[offset]*rxsigF[aa][offset]   + (int32_t)Xu[offset+1]*rxsigF[aa][offset+1])>>15);
+	          prachF[offset+1] = (int16_t)(((int32_t)Xu[offset]*rxsigF[aa][offset+1] - (int32_t)Xu[offset+1]*rxsigF[aa][offset])>>15);
+	       }
 	
-	// Now do IFFT of size 1024 (N_ZC=839) or 256 (N_ZC=139)
-	if (N_ZC == 839) {
-	  log2_ifft_size = 10;
-	  idft(IDFT_1024,prachF,prach_ifft_tmp,1);
-	  // compute energy and accumulate over receive antennas
-	  for (i=0;i<2048;i++)
-	    prach_ifft[i] += ((int32_t)prach_ifft_tmp[i<<1]*(int32_t)prach_ifft_tmp[i<<1] + (int32_t)prach_ifft_tmp[1+(i<<1)]*(int32_t)prach_ifft_tmp[1+(i<<1)])>>10;
-	} else {
-	  idft(IDFT_256,prachF,prach_ifft_tmp,1);
-	  log2_ifft_size = 8;
-	  // compute energy and accumulate over receive antennas and repetitions for BR
-	  for (i=0;i<256;i++)
-	    prach_ifft[i] += ((int32_t)prach_ifft_tmp[i<<1]*(int32_t)prach_ifft_tmp[(i<<1)] + (int32_t)prach_ifft_tmp[1+(i<<1)]*(int32_t)prach_ifft_tmp[1+(i<<1)])>>10;
-	}
-
-	if (LOG_DUMPFLAG(PRACH)) {	
-	  if (aa==0) LOG_M("prach_rxF_comp0.m","prach_rxF_comp0",prachF,1024,1,1);
+	       // Now do IFFT of size 1024 (N_ZC=839) or 256 (N_ZC=139)
+	       if (N_ZC == 839) {
+	         idft(IDFT_1024,prachF,prach_ifft_tmp,1);
+	         // compute energy and accumulate over receive antennas
+	         for (i=0;i<1024;i++)
+	           prach_ifft[i] += (int32_t)prach_ifft_tmp[i<<1]*(int32_t)prach_ifft_tmp[i<<1] + (int32_t)prach_ifft_tmp[1+(i<<1)]*(int32_t)prach_ifft_tmp[1+(i<<1)];
+	       } else {
+	         idft(IDFT_256,prachF,prach_ifft_tmp,1);
+	         log2_ifft_size = 8;
+           // compute energy and accumulate over receive antennas and repetitions for BR
+           for (i=0;i<256;i++)
+             prach_ifft[i] += (int32_t)prach_ifft_tmp[i<<1]*(int32_t)prach_ifft_tmp[(i<<1)] + (int32_t)prach_ifft_tmp[1+(i<<1)]*(int32_t)prach_ifft_tmp[1+(i<<1)];
+         }
+
+        if (LOG_DUMPFLAG(PRACH)) {
+          if (aa==0) LOG_M("prach_rxF_comp0.m","prach_rxF_comp0",prachF,1024,1,1);
           if (aa==1) LOG_M("prach_rxF_comp1.m","prach_rxF_comp1",prachF,1024,1,1);
-	}
+        }
+
       }// antennas_rx
+
+      // Normalization of energy over ifft and receive antennas
+      if (N_ZC == 839) {
+        log2_ifft_size = 10;
+        for (i=0;i<1024;i++)
+          prach_ifft[i] = (prach_ifft[i]>>log2_ifft_size)/nb_rx;
+      } else {
+        log2_ifft_size = 8;
+        for (i=0;i<256;i++)
+          prach_ifft[i] = (prach_ifft[i]>>log2_ifft_size)/nb_rx;
+      }
+
     } // new dft
     
     // check energy in nth time shift, for 
@@ -900,10 +912,10 @@ void rx_nr_prach(PHY_VARS_gNB *gNB,
       lev = (int32_t)prach_ifft[(preamble_shift2+i)];
       levdB = dB_fixed_times10(lev);
       if (levdB>*max_preamble_energy) {
-	LOG_D(PHY,"preamble_index %d, delay %d en %d dB > %d dB\n",preamble_index,i,levdB,*max_preamble_energy);
-	*max_preamble_energy  = levdB;
-	*max_preamble_delay   = i; // Note: This has to be normalized to the 30.72 Ms/s sampling rate 
-	*max_preamble         = preamble_index;
+	      LOG_D(PHY,"preamble_index %d, delay %d en %d dB > %d dB\n",preamble_index,i,levdB,*max_preamble_energy);
+	      *max_preamble_energy  = levdB;
+	      *max_preamble_delay   = i; // Note: This has to be normalized to the 30.72 Ms/s sampling rate 
+	      *max_preamble         = preamble_index;
       }
     }
   }// preamble_index
diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch.h b/openair1/PHY/NR_TRANSPORT/nr_ulsch.h
index 2ca8e24af1315c05230c7c2df20cb90c0b9b3474..80c10d74b15a4c7bc82862efe7142d049975320f 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_ulsch.h
+++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch.h
@@ -91,6 +91,7 @@ int16_t find_nr_ulsch(uint16_t rnti, PHY_VARS_gNB *gNB,find_type_t type);
 
 void dump_pusch_stats(FILE *fd,PHY_VARS_gNB *gNB);
 
+void dump_nr_I0_stats(FILE *fd,PHY_VARS_gNB *gNB);
 void clear_pusch_stats(PHY_VARS_gNB *gNB);
 
 NR_gNB_SCH_STATS_t *get_ulsch_stats(PHY_VARS_gNB *gNB,NR_gNB_ULSCH_t *ulsch);
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 909d0b8954036a72584605e3a996733972b40e4d..8c4394e6e9e933b1a7e17d0290671965fd64897d 100644
--- a/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c
+++ b/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c
@@ -36,7 +36,7 @@
 
 int nr_pbch_dmrs_correlation(PHY_VARS_NR_UE *ue,
                              UE_nr_rxtx_proc_t *proc,
-                             uint8_t eNB_offset,
+                             uint8_t gNB_id,
                              unsigned char Ns,
                              unsigned char symbol,
                              int dmrss,
@@ -70,7 +70,7 @@ int nr_pbch_dmrs_correlation(PHY_VARS_NR_UE *ue,
   k = nushift;
 
 #ifdef DEBUG_CH
-  printf("PBCH DMRS Correlation : ThreadId %d, eNB_offset %d , OFDM size %d, Ncp=%d, Ns=%d, k=%d symbol %d\n",proc->thread_id, eNB_offset,ue->frame_parms.ofdm_symbol_size,
+  printf("PBCH DMRS Correlation : ThreadId %d, gNB_id %d , OFDM size %d, Ncp=%d, Ns=%d, k=%d symbol %d\n",proc->thread_id, gNB_id,ue->frame_parms.ofdm_symbol_size,
          ue->frame_parms.Ncp,Ns,k, symbol);
 #endif
 
@@ -198,7 +198,7 @@ int nr_pbch_dmrs_correlation(PHY_VARS_NR_UE *ue,
 
 int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue,
                                UE_nr_rxtx_proc_t *proc,
-                               uint8_t eNB_offset,
+                               uint8_t gNB_id,
                                unsigned char Ns,
                                unsigned char symbol,
                                int dmrss,
@@ -213,10 +213,8 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue,
   int ch_offset,symbol_offset;
   //int slot_pbch;
 
-  //uint16_t Nid_cell = (eNB_offset == 0) ? ue->frame_parms.Nid_cell : ue->measurements.adj_cell_id[eNB_offset-1];
-
   uint8_t nushift;
-  int **dl_ch_estimates  =ue->pbch_vars[eNB_offset]->dl_ch_estimates;
+  int **dl_ch_estimates  =ue->pbch_vars[gNB_id]->dl_ch_estimates;
   int **rxdataF=ue->common_vars.common_vars_rx_data_per_thread[proc->thread_id].rxdataF;
 
   nushift =  ue->frame_parms.Nid_cell%4;
@@ -239,7 +237,7 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue,
   k = nushift;
 
 #ifdef DEBUG_CH
-  printf("PBCH Channel Estimation : ThreadId %d, eNB_offset %d ch_offset %d, OFDM size %d, Ncp=%d, Ns=%d, k=%d symbol %d\n",proc->thread_id, eNB_offset,ch_offset,ue->frame_parms.ofdm_symbol_size,
+  printf("PBCH Channel Estimation : ThreadId %d, gNB_id %d ch_offset %d, OFDM size %d, Ncp=%d, Ns=%d, k=%d symbol %d\n",proc->thread_id, gNB_id,ch_offset,ue->frame_parms.ofdm_symbol_size,
          ue->frame_parms.Ncp,Ns,k, symbol);
 #endif
 
@@ -456,12 +454,12 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue,
       // do ifft of channel estimate
       for (aarx=0; aarx<ue->frame_parms.nb_antennas_rx; aarx++)
         for (p=0; p<ue->frame_parms.nb_antenna_ports_gNB; p++) {
-          if (ue->pbch_vars[eNB_offset]->dl_ch_estimates[(p*ue->frame_parms.nb_antennas_rx)+aarx])
+          if (ue->pbch_vars[gNB_id]->dl_ch_estimates[(p*ue->frame_parms.nb_antennas_rx)+aarx])
           {
             LOG_D(PHY,"Channel Impulse Computation Slot %d ThreadId %d Symbol %d ch_offset %d\n", Ns, proc->thread_id, symbol, ch_offset);
             idft(idftsizeidx,
-                 (int16_t*) &ue->pbch_vars[eNB_offset]->dl_ch_estimates[(p*ue->frame_parms.nb_antennas_rx)+aarx][ch_offset],
-                 (int16_t*) ue->pbch_vars[eNB_offset]->dl_ch_estimates_time[(p*ue->frame_parms.nb_antennas_rx)+aarx],1);
+                 (int16_t*) &ue->pbch_vars[gNB_id]->dl_ch_estimates[(p*ue->frame_parms.nb_antennas_rx)+aarx][ch_offset],
+                 (int16_t*) ue->pbch_vars[gNB_id]->dl_ch_estimates_time[(p*ue->frame_parms.nb_antennas_rx)+aarx],1);
           }
         }
     }
@@ -474,7 +472,7 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue,
 
 int nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue,
                                 UE_nr_rxtx_proc_t *proc,
-                                uint8_t eNB_offset,
+                                uint8_t gNB_id,
                                 unsigned char Ns,
                                 unsigned char symbol,
                                 unsigned short coreset_start_subcarrier,
@@ -487,9 +485,7 @@ int nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue,
   int16_t ch[2],*pil,*rxF,*dl_ch,*fl,*fm,*fr;
   int ch_offset,symbol_offset;
 
-  //uint16_t Nid_cell = (eNB_offset == 0) ? ue->frame_parms.Nid_cell : ue->measurements.adj_cell_id[eNB_offset-1];
-
-  int **dl_ch_estimates  =ue->pdcch_vars[proc->thread_id][eNB_offset]->dl_ch_estimates;
+  int **dl_ch_estimates  =ue->pdcch_vars[proc->thread_id][gNB_id]->dl_ch_estimates;
   int **rxdataF=ue->common_vars.common_vars_rx_data_per_thread[proc->thread_id].rxdataF;
 
 
@@ -500,10 +496,9 @@ int nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue,
 
   symbol_offset = ue->frame_parms.ofdm_symbol_size*symbol;
 
-  k = coreset_start_subcarrier;
 
 #ifdef DEBUG_PDCCH
-  printf("PDCCH Channel Estimation : ThreadId %d, eNB_offset %d ch_offset %d, OFDM size %d, Ncp=%d, Ns=%d, k=%d symbol %d\n",proc->thread_id, eNB_offset,ch_offset,ue->frame_parms.ofdm_symbol_size,
+  printf("PDCCH Channel Estimation : ThreadId %d, gNB_id %d ch_offset %d, OFDM size %d, Ncp=%d, Ns=%d, k=%d symbol %d\n",proc->thread_id, gNB_id,ch_offset,ue->frame_parms.ofdm_symbol_size,
          ue->frame_parms.Ncp,Ns,k, symbol);
 #endif
 
@@ -521,11 +516,12 @@ int nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue,
 
   // generate pilot
   int pilot[nb_rb_coreset * 3] __attribute__((aligned(16))); 
-  nr_pdcch_dmrs_rx(ue,eNB_offset,Ns,ue->nr_gold_pdcch[eNB_offset][Ns][symbol], &pilot[0],2000,nb_rb_coreset);
+  nr_pdcch_dmrs_rx(ue,gNB_id,Ns,ue->nr_gold_pdcch[gNB_id][Ns][symbol], &pilot[0],2000,nb_rb_coreset);
 
 
   for (aarx=0; aarx<ue->frame_parms.nb_antennas_rx; aarx++) {
 
+    k = coreset_start_subcarrier;
     pil   = (int16_t *)&pilot[0];
     rxF   = (int16_t *)&rxdataF[aarx][(symbol_offset+k+1)];
     dl_ch = (int16_t *)&dl_ch_estimates[aarx][ch_offset];
@@ -656,7 +652,7 @@ int nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue,
 
 int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue,
                                 UE_nr_rxtx_proc_t *proc,
-                                uint8_t eNB_offset,
+                                uint8_t gNB_id,
                                 bool is_SI,
                                 unsigned char Ns,
                                 unsigned short p,
@@ -673,10 +669,12 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue,
   int16_t *fl,*fm,*fr,*fml,*fmr,*fmm,*fdcl,*fdcr,*fdclh,*fdcrh, *frl, *frr;
   int ch_offset,symbol_offset;
 
-  //uint16_t Nid_cell = (eNB_offset == 0) ? ue->frame_parms.Nid_cell : ue->measurements.adj_cell_id[eNB_offset-1];
+  NR_UE_DLSCH_t  **dlsch = ue->dlsch[proc->thread_id][gNB_id];
+  const unsigned char harq_pid = dlsch[0]->current_harq_pid;
+  NR_DL_UE_HARQ_t *dlsch0_harq = dlsch[0]->harq_processes[harq_pid];
 
   uint8_t nushift;
-  int **dl_ch_estimates  =ue->pdsch_vars[proc->thread_id][eNB_offset]->dl_ch_estimates;
+  int **dl_ch_estimates  =ue->pdsch_vars[proc->thread_id][gNB_id]->dl_ch_estimates;
   int **rxdataF=ue->common_vars.common_vars_rx_data_per_thread[proc->thread_id].rxdataF;
 
   if (ue->high_speed_flag == 0)
@@ -690,7 +688,7 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue,
   int re_offset = k;
 
 #ifdef DEBUG_CH
-  printf("PDSCH Channel Estimation : ThreadId %d, eNB_offset %d ch_offset %d, symbol_offset %d OFDM size %d, Ncp=%d, Ns=%d, k=%d symbol %d\n",proc->thread_id, eNB_offset,ch_offset,symbol_offset,ue->frame_parms.ofdm_symbol_size,
+  printf("PDSCH Channel Estimation : ThreadId %d, gNB_id %d ch_offset %d, symbol_offset %d OFDM size %d, Ncp=%d, Ns=%d, k=%d symbol %d\n",proc->thread_id, gNB_id,ch_offset,symbol_offset,ue->frame_parms.ofdm_symbol_size,
          ue->frame_parms.Ncp,Ns,k, symbol);
 #endif
 
@@ -699,19 +697,19 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue,
   if (is_SI) {
     rb_offset -= BWPStart;
   }
-  uint8_t config_type = ue->dmrs_DownlinkConfig.pdsch_dmrs_type;
+  uint8_t config_type = dlsch0_harq->dmrsConfigType;
   int8_t delta = get_delta(p, config_type);
 
   // checking if re-initialization of scrambling IDs is needed
-  if ((ue->dmrs_DownlinkConfig.scramblingID0 != ue->scramblingID[0]) || (ue->dmrs_DownlinkConfig.scramblingID1 != ue->scramblingID[1])){
-    ue->scramblingID[0]=ue->dmrs_DownlinkConfig.scramblingID0;
-    ue->scramblingID[1]=ue->dmrs_DownlinkConfig.scramblingID1;
+  /*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);
-  }
+  }*/
 
-  nr_pdsch_dmrs_rx(ue,Ns,ue->nr_gold_pdsch[eNB_offset][Ns][symbol][0], &pilot[0],1000+p,0,nb_rb_pdsch+rb_offset);
+  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);
 
-  if (config_type == pdsch_dmrs_type1){
+  if (config_type == NFAPI_NR_DMRS_TYPE1){
     nushift = (p>>1)&1;
     if (p<4) ue->frame_parms.nushift = nushift;
     switch (delta) {
@@ -751,7 +749,7 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue,
         return -1;
         break;
     }
-  } else {//pdsch_dmrs_type2
+  } else {//NFAPI_NR_DMRS_TYPE2
     nushift = delta;
     if (p<6) ue->frame_parms.nushift = nushift;
     switch (delta) {
@@ -793,7 +791,7 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue,
   }
 
   for (aarx=0; aarx<ue->frame_parms.nb_antennas_rx; aarx++) {
-    pil   = (int16_t *)&pilot[rb_offset*((config_type==pdsch_dmrs_type1) ? 6:4)];
+    pil   = (int16_t *)&pilot[rb_offset*((config_type==NFAPI_NR_DMRS_TYPE1) ? 6:4)];
     k     = k % ue->frame_parms.ofdm_symbol_size;
     re_offset = k;
     rxF   = (int16_t *)&rxdataF[aarx][(symbol_offset+re_offset+nushift)];
@@ -811,7 +809,7 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue,
     printf("dl_ch addr %p nushift %d\n",dl_ch,nushift);
 #endif
 
-    if (config_type == pdsch_dmrs_type1) {
+    if (config_type == NFAPI_NR_DMRS_TYPE1) {
 
       // Treat first 2 pilots specially (left edge)
       ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
@@ -944,11 +942,11 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue,
     
     // check if PRB crosses DC and improve estimates around DC
     if ((bwp_start_subcarrier < ue->frame_parms.ofdm_symbol_size) && (bwp_start_subcarrier+nb_rb_pdsch*12 >= ue->frame_parms.ofdm_symbol_size)) {
-      dl_ch = (int16_t *)&dl_ch_estimates[aarx][ch_offset];
+      dl_ch = (int16_t *)&dl_ch_estimates[p*ue->frame_parms.nb_antennas_rx+aarx][ch_offset];
       uint16_t idxDC = 2*(ue->frame_parms.ofdm_symbol_size - bwp_start_subcarrier);
       uint16_t idxPil = idxDC/2;
       re_offset = k;
-      pil = (int16_t *)&pilot[rb_offset*((config_type==pdsch_dmrs_type1) ? 6:4)];
+      pil = (int16_t *)&pilot[rb_offset*((config_type==NFAPI_NR_DMRS_TYPE1) ? 6:4)];
       pil += (idxPil-2);
       dl_ch += (idxDC-4);
       dl_ch = memset(dl_ch, 0, sizeof(int16_t)*10);
@@ -994,7 +992,7 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue,
                                            8);
       }
     }
-    } else { //pdsch_dmrs_type2  |dmrs_r,dmrs_l,0,0,0,0,dmrs_r,dmrs_l,0,0,0,0|
+    } else { //NFAPI_NR_DMRS_TYPE2  |dmrs_r,dmrs_l,0,0,0,0,dmrs_r,dmrs_l,0,0,0,0|
 
       // Treat first 4 pilots specially (left edge)
       ch_l[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
@@ -1224,16 +1222,15 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue,
  *
  * NAME :         nr_pdsch_ptrs_processing
  *
- * PARAMETERS :   ue                : ue data structure
+ * PARAMETERS :   PHY_VARS_NR_UE    : ue data structure
  *                NR_UE_PDSCH       : pdsch_vars pointer
  *                NR_DL_FRAME_PARMS : frame_parms pointer
  *                NR_DL_UE_HARQ_t   : dlsch0_harq pointer
  *                NR_DL_UE_HARQ_t   : dlsch1_harq pointer
- *                uint8_t           : eNB_id,
+ *                uint8_t           : gNB_id,
  *                uint8_t           : nr_slot_rx,
  *                unsigned char     : symbol,
  *                uint32_t          : nb_re_pdsch,
- *                unsigned char     : harq_pid
  *                uint16_t          : rnti
  *                RX_type_t         : rx_type
  * RETURN : Nothing
@@ -1249,11 +1246,10 @@ void nr_pdsch_ptrs_processing(PHY_VARS_NR_UE *ue,
                               NR_DL_FRAME_PARMS *frame_parms,
                               NR_DL_UE_HARQ_t *dlsch0_harq,
                               NR_DL_UE_HARQ_t *dlsch1_harq,
-                              uint8_t eNB_id,
+                              uint8_t gNB_id,
                               uint8_t nr_slot_rx,
                               unsigned char symbol,
                               uint32_t nb_re_pdsch,
-                              unsigned char harq_pid,
                               uint16_t rnti,
                               RX_type_t rx_type)
 {
@@ -1284,7 +1280,7 @@ void nr_pdsch_ptrs_processing(PHY_VARS_NR_UE *ue,
     ptrsSymbPos     = &dlsch0_harq->ptrs_symbols;
     ptrsSymbIdx     = &dlsch0_harq->ptrs_symbol_index;
     ptrsReOffset    = &dlsch0_harq->PTRSReOffset;
-    dmrsConfigType  = &dlsch0_harq->ptrs_symbol_index;
+    dmrsConfigType  = &dlsch0_harq->dmrsConfigType;
     nb_rb           = &dlsch0_harq->nb_rb;
   }
   if(dlsch1_harq) {
@@ -1297,13 +1293,13 @@ void nr_pdsch_ptrs_processing(PHY_VARS_NR_UE *ue,
     ptrsSymbPos     = &dlsch1_harq->ptrs_symbols;
     ptrsSymbIdx     = &dlsch1_harq->ptrs_symbol_index;
     ptrsReOffset    = &dlsch1_harq->PTRSReOffset;
-    dmrsConfigType  = &dlsch1_harq->ptrs_symbol_index;
+    dmrsConfigType  = &dlsch1_harq->dmrsConfigType;
     nb_rb           = &dlsch1_harq->nb_rb;
   }
   /* loop over antennas */
   for (int aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
-    phase_per_symbol = (int16_t*)pdsch_vars[eNB_id]->ptrs_phase_per_slot[aarx];
-    ptrs_re_symbol = (int32_t*)pdsch_vars[eNB_id]->ptrs_re_per_slot[aarx];
+    phase_per_symbol = (int16_t*)pdsch_vars[gNB_id]->ptrs_phase_per_slot[aarx];
+    ptrs_re_symbol = (int32_t*)pdsch_vars[gNB_id]->ptrs_re_per_slot[aarx];
     ptrs_re_symbol[symbol] = 0;
     phase_per_symbol[(2*symbol)+1] = 0; // Imag
     /* set DMRS estimates to 0 angle with magnitude 1 */
@@ -1337,11 +1333,11 @@ void nr_pdsch_ptrs_processing(PHY_VARS_NR_UE *ue,
         /*------------------------------------------------------------------------------------------------------- */
         nr_ptrs_cpe_estimation(*K_ptrs,*ptrsReOffset,*dmrsConfigType,*nb_rb,
                                rnti,
-                               (int16_t *)&pdsch_vars[eNB_id]->dl_ch_ptrs_estimates_ext[aarx][symbol*nb_re_pdsch],
+                               (int16_t *)&pdsch_vars[gNB_id]->dl_ch_ptrs_estimates_ext[aarx][symbol*nb_re_pdsch],
                                nr_slot_rx,
                                symbol,frame_parms->ofdm_symbol_size,
-                               (int16_t*)&pdsch_vars[eNB_id]->rxdataF_comp0[aarx][(symbol * nb_re_pdsch)],
-                               ue->nr_gold_pdsch[eNB_id][nr_slot_rx][symbol][0],
+                               (int16_t*)&pdsch_vars[gNB_id]->rxdataF_comp0[aarx][(symbol * nb_re_pdsch)],
+                               ue->nr_gold_pdsch[gNB_id][nr_slot_rx][symbol][0],
                                &phase_per_symbol[2* symbol],
                                &ptrs_re_symbol[symbol]);
       }
@@ -1360,9 +1356,9 @@ void nr_pdsch_ptrs_processing(PHY_VARS_NR_UE *ue,
         }
       }
 #ifdef DEBUG_DL_PTRS
-      LOG_M("ptrsEst.m","est",pdsch_vars[eNB_id]->ptrs_phase_per_slot[aarx],frame_parms->symbols_per_slot,1,1 );
+      LOG_M("ptrsEst.m","est",pdsch_vars[gNB_id]->ptrs_phase_per_slot[aarx],frame_parms->symbols_per_slot,1,1 );
       LOG_M("rxdataF_bf_ptrs_comp.m","bf_ptrs_cmp",
-            &pdsch_vars[eNB_id]->rxdataF_comp0[aarx][(*startSymbIndex) * NR_NB_SC_PER_RB * (*nb_rb) ],
+            &pdsch_vars[gNB_id]->rxdataF_comp0[aarx][(*startSymbIndex) * NR_NB_SC_PER_RB * (*nb_rb) ],
             (*nb_rb) * NR_NB_SC_PER_RB * (*nbSymb),1,1);
 #endif
       /*------------------------------------------------------------------------------------------------------- */
@@ -1375,9 +1371,9 @@ void nr_pdsch_ptrs_processing(PHY_VARS_NR_UE *ue,
 #ifdef DEBUG_DL_PTRS
           printf("[PHY][DL][PTRS]: Rotate Symbol %2d with  %d + j* %d\n", i, phase_per_symbol[2* i],phase_per_symbol[(2* i) +1]);
 #endif
-          rotate_cpx_vector((int16_t*)&pdsch_vars[eNB_id]->rxdataF_comp0[aarx][(i * (*nb_rb) * NR_NB_SC_PER_RB)],
+          rotate_cpx_vector((int16_t*)&pdsch_vars[gNB_id]->rxdataF_comp0[aarx][(i * (*nb_rb) * NR_NB_SC_PER_RB)],
                             &phase_per_symbol[2* i],
-                            (int16_t*)&pdsch_vars[eNB_id]->rxdataF_comp0[aarx][(i * (*nb_rb) * NR_NB_SC_PER_RB)],
+                            (int16_t*)&pdsch_vars[gNB_id]->rxdataF_comp0[aarx][(i * (*nb_rb) * NR_NB_SC_PER_RB)],
                             ((*nb_rb) * NR_NB_SC_PER_RB), 15);
         }// if not DMRS Symbol
       }// symbol loop
diff --git a/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h b/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h
index 1466fabe5d5f1a549922e5729d250d2d22075267..c5330ce2f2e7e2a98f3d77591046f4ea8bb6cc84 100644
--- a/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h
+++ b/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h
@@ -34,17 +34,14 @@
 
 /*!
 \brief This function performs channel estimation including frequency and temporal interpolation
-\param phy_vars_ue Pointer to UE PHY variables
-\param eNB_id Index of target eNB
-\param eNB_offset Offset for interfering eNB (in terms cell ID mod 3)
+\param ue Pointer to UE PHY variables
+\param gNB_id Index of target gNB
 \param Ns slot number (0..19)
-\param p antenna port
-\param l symbol within slot
-\param symbol symbol within frame
+\param symbol symbol within slot
 */
 int nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue,
                                 UE_nr_rxtx_proc_t *proc,
-                                uint8_t eNB_offset,
+                                uint8_t gNB_id,
                                 unsigned char Ns,
                                 unsigned char symbol,
                                 unsigned short coreset_start_subcarrier,
@@ -52,7 +49,7 @@ int nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue,
 
 int nr_pbch_dmrs_correlation(PHY_VARS_NR_UE *ue,
                              UE_nr_rxtx_proc_t *proc,
-                             uint8_t eNB_offset,
+                             uint8_t gNB_id,
                              unsigned char Ns,
                              unsigned char symbol,
                              int dmrss,
@@ -60,7 +57,7 @@ int nr_pbch_dmrs_correlation(PHY_VARS_NR_UE *ue,
 
 int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue,
                                UE_nr_rxtx_proc_t *proc,
-                               uint8_t eNB_offset,
+                               uint8_t gNB_id,
                                unsigned char Ns,
                                unsigned char symbol,
                                int dmrss,
@@ -69,7 +66,7 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue,
 
 int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue,
                                 UE_nr_rxtx_proc_t *proc,
-                                uint8_t eNB_offset,
+                                uint8_t gNB_id,
                                 bool is_SI,
                                 unsigned char Ns,
                                 unsigned short p,
@@ -80,7 +77,7 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue,
 
 void nr_adjust_synch_ue(NR_DL_FRAME_PARMS *frame_parms,
                         PHY_VARS_NR_UE *ue,
-                        module_id_t eNB_id,
+                        module_id_t gNB_id,
                         uint8_t frame,
                         uint8_t subframe,
                         unsigned char clear,
@@ -102,7 +99,7 @@ void nr_ue_rrc_measurements(PHY_VARS_NR_UE *ue,
 
 void phy_adjust_gain_nr(PHY_VARS_NR_UE *ue,
                         uint32_t rx_power_fil_dB,
-                        uint8_t eNB_id);
+                        uint8_t gNB_id);
 
 int16_t get_nr_PL(uint8_t Mod_id, uint8_t CC_id, uint8_t gNB_index);
 
@@ -111,11 +108,10 @@ void nr_pdsch_ptrs_processing(PHY_VARS_NR_UE *ue,
                               NR_DL_FRAME_PARMS *frame_parms,
                               NR_DL_UE_HARQ_t *dlsch0_harq,
                               NR_DL_UE_HARQ_t *dlsch1_harq,
-                              uint8_t eNB_id,
+                              uint8_t gNB_id,
                               uint8_t nr_slot_rx,
                               unsigned char symbol,
                               uint32_t nb_re_pdsch,
-                              unsigned char harq_pid,
                               uint16_t rnti,
                               RX_type_t rx_type);
 
diff --git a/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c b/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c
index 5d4d9df47e26782831a77b9e741d5684497396cc..cffdf5092d90e796dce3efb9164796d6e965ea33 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c
@@ -761,7 +761,7 @@ int32_t nr_rx_pdcch(PHY_VARS_NR_UE *ue,
       for (aarx = 0; aarx < frame_parms->nb_antennas_rx; aarx++)
         avgs = cmax(avgs, avgP[aarx]);
 
-      log2_maxh = (log2_approx(avgs) / 2) + 5;  //+frame_parms->nb_antennas_rx;
+      log2_maxh = (log2_approx(avgs) / 2) + 1;  //+frame_parms->nb_antennas_rx;
 #ifdef UE_DEBUG_TRACE
       LOG_D(PHY,"slot %d: pdcch log2_maxh = %d (%d,%d)\n",slot,log2_maxh,avgP[0],avgs);
 #endif
diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c
index 2046c13eaa626f1caa7c2bf8d801023d00a1a625..2174f569da290c93a1d0887d6782758ea36003ac 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c
@@ -84,8 +84,8 @@ unsigned char offset_mumimo_llr_drange[29][3]={{8,8,8},{7,7,7},{7,7,7},{7,7,7},{
  */
 //unsigned char offset_mumimo_llr_drange[29][3]= {{0, 6, 5},{0, 4, 5},{0, 4, 5},{0, 5, 4},{0, 5, 6},{0, 5, 3},{0, 4, 4},{0, 4, 4},{0, 3, 3},{0, 1, 2},{1, 1, 0},{1, 3, 2},{3, 4, 1},{2, 0, 0},{2, 2, 2},{1, 1, 1},{2, 1, 0},{2, 1, 1},{1, 0, 1},{1, 0, 1},{0, 0, 0},{1, 0, 0},{0, 0, 0},{0, 1, 0},{1, 0, 0},{0, 0, 0},{0, 0, 0},{0, 0, 0},{0, 0, 0}};
 
-#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,%d,%d,%d,%d,%d,%d,%d\n",s,(x)[0],(x)[1],(x)[2],(x)[3],(x)[4],(x)[5],(x)[6],(x)[7])
+#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,
@@ -99,17 +99,21 @@ static void nr_dlsch_dual_stream_correlation_core(int **dl_ch_estimates_ext,
 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);
+                                   unsigned char symbol,
+                                   int length);
 
 static void nr_dlsch_layer_demapping(int16_t **llr_cw,
 				     uint8_t Nl,
 				     uint8_t mod_order,
-				     uint16_t length,
+				     uint32_t length,
+				     int32_t codeword_TB0,
+				     int32_t codeword_TB1,
 				     int16_t **llr_layers);
 
 
@@ -182,8 +186,6 @@ 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;
-  uint8_t pilots=0;
-  uint8_t config_type;// We should not use ue->dmrs_DownlinkConfig.pdsch_dmrs_type;
   uint16_t n_tx=1, n_rx=1;
   int32_t median[16];
   uint32_t len;
@@ -340,8 +342,8 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
   printf("Demod  dlsch0_harq->pmi_alloc %d\n",  dlsch0_harq->pmi_alloc);
 #endif
 
-  pilots = ((1<<symbol)&dlsch0_harq->dlDmrsSymbPos)>0 ? 1 : 0;
-  config_type = dlsch0_harq->dmrsConfigType;
+  uint8_t pilots = (dlsch0_harq->dlDmrsSymbPos >> symbol) & 1;
+  uint8_t config_type = dlsch0_harq->dmrsConfigType;
 
   if (beamforming_mode==0) {//No beamforming
 #if UE_TIMING_TRACE
@@ -385,7 +387,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
     return(-1);
   }
 
-  len = (pilots==1)? ((config_type==pdsch_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);
+  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);
 
 #if UE_TIMING_TRACE
   stop_meas(&ue->generic_stat_bis[proc->thread_id][slot]);
@@ -412,7 +414,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
                          symbol,
                          pilots,
                          len,
-                         nb_rb);
+                         nb_rb_pdsch);
 
 #if UE_TIMING_TRACE
     stop_meas(&ue->generic_stat_bis[proc->thread_id][slot]);
@@ -434,7 +436,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
                              avg,
                              symbol,
                              len,
-                             nb_rb);
+                             nb_rb_pdsch);
       avgs = 0;
       for (aatx=0;aatx<n_tx;aatx++)
         for (aarx=0;aarx<n_rx;aarx++) {
@@ -443,7 +445,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
           //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];
         }
-      pdsch_vars[gNB_id]->log2_maxh = (log2_approx(avgs)/2)+3;
+      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);
 
       if (dlsch0_harq->mimo_mode == NR_DUALSTREAM) {
@@ -505,10 +507,10 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
                                   frame_parms,
                                   n_tx,
                                   symbol,
-                                  pilots,
+                                  len,
                                   first_symbol_flag,
                                   dlsch0_harq->Qm,
-                                  nb_rb,
+                                  nb_rb_pdsch,
                                   pdsch_vars[gNB_id]->log2_maxh,
                                   measurements); // log2_maxh+I0_shift
     }
@@ -556,20 +558,24 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
                              (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);
+                             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,
+                                   nb_rb_pdsch,
                                    n_rx,
                                    dlsch0_harq->Qm,
                                    pdsch_vars[gNB_id]->log2_maxh,
-                                   symbol);
+                                   symbol,
+                                   len);
     }
     else if (dlsch0_harq->mimo_mode == NR_DUALSTREAM) {
       nr_dlsch_detection_mrc_core(pdsch_vars[gNB_id]->rxdataF_comp0,
@@ -635,14 +641,13 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
                                nr_slot_rx,
                                symbol,
                                (nb_rb*12),
-                               harq_pid,
                                dlsch[0]->rnti,rx_type);
       pdsch_vars[gNB_id]->dl_valid_re[symbol-1] -= pdsch_vars[gNB_id]->ptrs_re_per_slot[0][symbol];
     }
 
     /* at last symbol in a slot calculate LLR's for whole slot */
     if(symbol == (startSymbIdx + nbSymb -1)) {
-      for(uint8_t i =startSymbIdx; i <= nbSymb;i++) {
+      for(uint8_t i =startSymbIdx; i < (startSymbIdx+nbSymb);i++) {
         /* re evaluating the first symbol flag as LLR's are done in symbol loop  */
         if(i == startSymbIdx && i < 3) {
           first_symbol_flag =1;
@@ -662,16 +667,29 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
                      pdsch_vars[gNB_id]->dl_valid_re[i-1],
                      nr_slot_rx, beamforming_mode);
       }
-    }
-
-  //nr_dlsch_deinterleaving(symbol,bundle_L,(int16_t*)pllr_symbol_cw0,(int16_t*)pllr_symbol_cw0_deint, nb_rb_pdsch);
 
-    if (rx_type==rx_IC_dual_stream) {
+      int dmrs_type = dlsch[0]->harq_processes[harq_pid]->dmrsConfigType;
+      uint8_t nb_re_dmrs;
+      uint16_t dmrs_len = get_num_dmrs(dlsch[0]->harq_processes[harq_pid]->dlDmrsSymbPos);
+      if (dmrs_type==NFAPI_NR_DMRS_TYPE1) {
+        nb_re_dmrs = 6*dlsch[0]->harq_processes[harq_pid]->n_dmrs_cdm_groups;
+      } else {
+        nb_re_dmrs = 4*dlsch[0]->harq_processes[harq_pid]->n_dmrs_cdm_groups;
+      }
+      dlsch[0]->harq_processes[harq_pid]->G = nr_get_G(dlsch[0]->harq_processes[harq_pid]->nb_rb,
+                                                       dlsch[0]->harq_processes[harq_pid]->nb_symbols,
+                                                       nb_re_dmrs,
+                                                       dmrs_len,
+                                                       dlsch[0]->harq_processes[harq_pid]->Qm,
+                                                       dlsch[0]->harq_processes[harq_pid]->Nl);
       nr_dlsch_layer_demapping(pdsch_vars[gNB_id]->llr,
                                dlsch[0]->harq_processes[harq_pid]->Nl,
                                dlsch[0]->harq_processes[harq_pid]->Qm,
                                dlsch[0]->harq_processes[harq_pid]->G,
+                               codeword_TB0,
+                               codeword_TB1,
                                pdsch_vars[gNB_id]->layer_llr);
+
     }
 
 #if UE_TIMING_TRACE
@@ -780,7 +798,7 @@ void nr_dlsch_channel_compensation(int **rxdataF_ext,
                                 NR_DL_FRAME_PARMS *frame_parms,
                                 uint8_t nb_aatx,
                                 unsigned char symbol,
-                                uint8_t pilots,
+                                int length,
                                 uint8_t first_symbol_flag,
                                 unsigned char mod_order,
                                 unsigned short nb_rb,
@@ -794,8 +812,8 @@ void nr_dlsch_channel_compensation(int **rxdataF_ext,
   unsigned char aatx,aarx,atx;
   __m128i *dl_ch128,*dl_ch128_2,*dl_ch_mag128,*dl_ch_mag128b,*dl_ch_mag128r,*rxdataF128,*rxdataF_comp128,*rho128;
   __m128i mmtmpD0,mmtmpD1,mmtmpD2,mmtmpD3,QAM_amp128,QAM_amp128b,QAM_amp128r;
-  QAM_amp128b = _mm_setzero_si128();
 
+  uint32_t nb_rb_0 = length/12 + ((length%12)?1:0);
   for (aatx=0; aatx<nb_aatx; aatx++) {
     if (mod_order == 4) {
       QAM_amp128 = _mm_set1_epi16(QAM16_n1);  // 2/sqrt(10)
@@ -822,7 +840,7 @@ void nr_dlsch_channel_compensation(int **rxdataF_ext,
       rxdataF128        = (__m128i *)&rxdataF_ext[aarx][symbol*nb_rb*12];
       rxdataF_comp128   = (__m128i *)&rxdataF_comp[(aatx*frame_parms->nb_antennas_rx)+aarx][symbol*nb_rb*12];
 
-      for (rb=0; rb<nb_rb; rb++) {
+      for (rb=0; rb<nb_rb_0; rb++) {
         if (mod_order>2) {
           // get channel amplitude if not QPSK
 
@@ -832,7 +850,7 @@ void nr_dlsch_channel_compensation(int **rxdataF_ext,
           mmtmpD1 = _mm_madd_epi16(dl_ch128[1],dl_ch128[1]);
           mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift);
 
-          mmtmpD0 = _mm_packs_epi32(mmtmpD0,mmtmpD1);
+          mmtmpD0 = _mm_packs_epi32(mmtmpD0,mmtmpD1); //|H[0]|^2 |H[1]|^2 |H[2]|^2 |H[3]|^2 |H[4]|^2 |H[5]|^2 |H[6]|^2 |H[7]|^2
 
           // store channel magnitude here in a new field of dlsch
 
@@ -841,6 +859,13 @@ void nr_dlsch_channel_compensation(int **rxdataF_ext,
           dl_ch_mag128r[0] = dl_ch_mag128[0];
           dl_ch_mag128[0] = _mm_mulhi_epi16(dl_ch_mag128[0],QAM_amp128);
           dl_ch_mag128[0] = _mm_slli_epi16(dl_ch_mag128[0],1);
+
+          dl_ch_mag128b[0] = _mm_mulhi_epi16(dl_ch_mag128b[0],QAM_amp128b);
+          dl_ch_mag128b[0] = _mm_slli_epi16(dl_ch_mag128b[0],1);
+
+          dl_ch_mag128r[0] = _mm_mulhi_epi16(dl_ch_mag128r[0],QAM_amp128r);
+          dl_ch_mag128r[0] = _mm_slli_epi16(dl_ch_mag128r[0],1);
+
     //print_ints("Re(ch):",(int16_t*)&mmtmpD0);
     //print_shorts("QAM_amp:",(int16_t*)&QAM_amp128);
     //print_shorts("mag:",(int16_t*)&dl_ch_mag128[0]);
@@ -850,39 +875,28 @@ void nr_dlsch_channel_compensation(int **rxdataF_ext,
           dl_ch_mag128[1] = _mm_mulhi_epi16(dl_ch_mag128[1],QAM_amp128);
           dl_ch_mag128[1] = _mm_slli_epi16(dl_ch_mag128[1],1);
 
-          if (pilots==0) {
-            mmtmpD0 = _mm_madd_epi16(dl_ch128[2],dl_ch128[2]);
-            mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift);
-            mmtmpD1 = _mm_packs_epi32(mmtmpD0,mmtmpD0);
-
-            dl_ch_mag128[2] = _mm_unpacklo_epi16(mmtmpD1,mmtmpD1);
-            dl_ch_mag128b[2] = dl_ch_mag128[2];
-            dl_ch_mag128r[2] = dl_ch_mag128[2];
-
-            dl_ch_mag128[2] = _mm_mulhi_epi16(dl_ch_mag128[2],QAM_amp128);
-            dl_ch_mag128[2] = _mm_slli_epi16(dl_ch_mag128[2],1);
-          }
-
-          dl_ch_mag128b[0] = _mm_mulhi_epi16(dl_ch_mag128b[0],QAM_amp128b);
-          dl_ch_mag128b[0] = _mm_slli_epi16(dl_ch_mag128b[0],1);
-
-
           dl_ch_mag128b[1] = _mm_mulhi_epi16(dl_ch_mag128b[1],QAM_amp128b);
           dl_ch_mag128b[1] = _mm_slli_epi16(dl_ch_mag128b[1],1);
 
-          dl_ch_mag128r[0] = _mm_mulhi_epi16(dl_ch_mag128r[0],QAM_amp128r);
-          dl_ch_mag128r[0] = _mm_slli_epi16(dl_ch_mag128r[0],1);
-
           dl_ch_mag128r[1] = _mm_mulhi_epi16(dl_ch_mag128r[1],QAM_amp128r);
           dl_ch_mag128r[1] = _mm_slli_epi16(dl_ch_mag128r[1],1);
 
-          if (pilots==0) {
-            dl_ch_mag128b[2] = _mm_mulhi_epi16(dl_ch_mag128b[2],QAM_amp128b);
-            dl_ch_mag128b[2] = _mm_slli_epi16(dl_ch_mag128b[2],1);
+          mmtmpD0 = _mm_madd_epi16(dl_ch128[2],dl_ch128[2]);//[H_I(0)^2+H_Q(0)^2 H_I(1)^2+H_Q(1)^2 H_I(2)^2+H_Q(2)^2 H_I(3)^2+H_Q(3)^2]
+          mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift);
+          mmtmpD1 = _mm_packs_epi32(mmtmpD0,mmtmpD0);//[|H(0)|^2 |H(1)|^2 |H(2)|^2 |H(3)|^2 |H(0)|^2 |H(1)|^2 |H(2)|^2 |H(3)|^2]
 
-            dl_ch_mag128r[2] = _mm_mulhi_epi16(dl_ch_mag128r[2],QAM_amp128r);
-            dl_ch_mag128r[2] = _mm_slli_epi16(dl_ch_mag128r[2],1);
-          }
+          dl_ch_mag128[2] = _mm_unpacklo_epi16(mmtmpD1,mmtmpD1);//[|H(0)|^2 |H(0)|^2 |H(1)|^2 |H(1)|^2 |H(2)|^2 |H(2)|^2 |H(3)|^2 |H(3)|^2]
+          dl_ch_mag128b[2] = dl_ch_mag128[2];
+          dl_ch_mag128r[2] = dl_ch_mag128[2];
+
+          dl_ch_mag128[2] = _mm_mulhi_epi16(dl_ch_mag128[2],QAM_amp128);
+          dl_ch_mag128[2] = _mm_slli_epi16(dl_ch_mag128[2],1);
+
+          dl_ch_mag128b[2] = _mm_mulhi_epi16(dl_ch_mag128b[2],QAM_amp128b);
+          dl_ch_mag128b[2] = _mm_slli_epi16(dl_ch_mag128b[2],1);
+
+          dl_ch_mag128r[2] = _mm_mulhi_epi16(dl_ch_mag128r[2],QAM_amp128r);
+          dl_ch_mag128r[2] = _mm_slli_epi16(dl_ch_mag128r[2],1);
         }
 
         // multiply by conjugated channel
@@ -905,15 +919,17 @@ void nr_dlsch_channel_compensation(int **rxdataF_ext,
         //        print_ints("c0",&mmtmpD2);
         //  print_ints("c1",&mmtmpD3);
         rxdataF_comp128[0] = _mm_packs_epi32(mmtmpD2,mmtmpD3);
-        //printf("arx%d atx%d rb_index %d symbol%d\n",aarx,aatx,rb,symbol);
-        //  print_shorts("rx:",rxdataF128);
-        //  print_shorts("ch:",dl_ch128);
-        //  print_shorts("pack:",rxdataF_comp128);
-
-        //printf("arx%d atx%d rb_index %d symbol%d\n",aarx,aatx,rb,symbol);
-        //print_shorts("rx:",(int16_t*)&rxdataF128[0]);
-        //print_shorts("ch:",(int16_t*)&dl_ch128[0]);
-        //print_shorts("pack:",(int16_t*)&rxdataF_comp128[0]);
+
+#ifdef DEBUG_DLSCH_DEMOD
+        printf("%%arx%d atx%d rb_index %d symbol %d shift %d\n",aarx,aatx,rb,symbol,output_shift);
+        printf("rx_%d(%d,:)",aarx+1,rb+1);
+        print_shorts("  ",(int16_t *)&rxdataF128[0]);
+        printf("ch_%d%d(%d,:)",aarx+1,aatx+1,rb+1);
+        print_shorts("  ",(int16_t *)&dl_ch128[0]);
+        printf("rx_comp_%d%d(%d,:)",aarx+1,aatx+1,rb+1);
+        print_shorts("  ",(int16_t *)&rxdataF_comp128[0]);
+#endif
+
         // multiply by conjugated channel
         mmtmpD0 = _mm_madd_epi16(dl_ch128[1],rxdataF128[1]);
         // mmtmpD0 contains real part of 4 consecutive outputs (32-bit)
@@ -932,40 +948,30 @@ void nr_dlsch_channel_compensation(int **rxdataF_ext,
         //print_shorts("ch:",(int16_t*)&dl_ch128[1]);
         //print_shorts("pack:",(int16_t*)&rxdataF_comp128[1]);
 
-        if (pilots==0) {
-          // multiply by conjugated channel
-          mmtmpD0 = _mm_madd_epi16(dl_ch128[2],rxdataF128[2]);
-          // mmtmpD0 contains real part of 4 consecutive outputs (32-bit)
-          mmtmpD1 = _mm_shufflelo_epi16(dl_ch128[2],_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,rxdataF128[2]);
-          // 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);
+        // multiply by conjugated channel
+        mmtmpD0 = _mm_madd_epi16(dl_ch128[2],rxdataF128[2]);
+        // mmtmpD0 contains real part of 4 consecutive outputs (32-bit)
+        mmtmpD1 = _mm_shufflelo_epi16(dl_ch128[2],_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,rxdataF128[2]);
+        // 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);
 
-          rxdataF_comp128[2] = _mm_packs_epi32(mmtmpD2,mmtmpD3);
-          //print_shorts("rx:",(int16_t*)&rxdataF128[2]);
-          //print_shorts("ch:",(int16_t*)&dl_ch128[2]);
-          //print_shorts("pack:",(int16_t*)&rxdataF_comp128[2]);
-
-          dl_ch128+=3;
-          dl_ch_mag128+=3;
-          dl_ch_mag128b+=3;
-          dl_ch_mag128r+=3;
-          rxdataF128+=3;
-          rxdataF_comp128+=3;
-        }
-        else { // we have a smaller PDSCH in symbols with pilots so skip last group of 4 REs and increment less
-          dl_ch128+=2;
-	      dl_ch_mag128+=2;
-	      dl_ch_mag128b+=2;
-	      dl_ch_mag128r+=2;
-	      rxdataF128+=2;
-	      rxdataF_comp128+=2;
-	    }
+        rxdataF_comp128[2] = _mm_packs_epi32(mmtmpD2,mmtmpD3);
+        //print_shorts("rx:",(int16_t*)&rxdataF128[2]);
+        //print_shorts("ch:",(int16_t*)&dl_ch128[2]);
+        //print_shorts("pack:",(int16_t*)&rxdataF_comp128[2]);
+
+        dl_ch128+=3;
+        dl_ch_mag128+=3;
+        dl_ch_mag128b+=3;
+        dl_ch_mag128r+=3;
+        rxdataF128+=3;
+        rxdataF_comp128+=3;
       }
     }
   }
@@ -989,7 +995,7 @@ void nr_dlsch_channel_compensation(int **rxdataF_ext,
           rho128        = (__m128i *)&rho[aarx][aatx*nb_aatx+atx][symbol*nb_rb*12];
           dl_ch128_2    = (__m128i *)&dl_ch_estimates_ext[atx*frame_parms->nb_antennas_rx+aarx][symbol*nb_rb*12];
 
-          for (rb=0; rb<nb_rb; rb++) {
+          for (rb=0; rb<nb_rb_0; rb++) {
             // multiply by conjugated channel
             mmtmpD0 = _mm_madd_epi16(dl_ch128[0],dl_ch128_2[0]);
             //  print_ints("re",&mmtmpD0);
@@ -1085,7 +1091,7 @@ void nr_dlsch_channel_compensation(int **rxdataF_ext,
             //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);
-            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[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]);
           }
         }
       }
@@ -1097,7 +1103,7 @@ void nr_dlsch_channel_compensation(int **rxdataF_ext,
 #elif defined(__arm__)
 
   unsigned short rb;
-  unsigned char aatx,aarx,symbol_mod,pilots=0;
+  unsigned char aatx,aarx,symbol_mod;
 
   int16x4_t *dl_ch128,*dl_ch128_2,*rxdataF128;
   int32x4_t mmtmpD0,mmtmpD1,mmtmpD0b,mmtmpD1b;
@@ -1110,14 +1116,7 @@ void nr_dlsch_channel_compensation(int **rxdataF_ext,
 
   symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol;
 
-  if ((symbol_mod == 0) || (symbol_mod == (4-frame_parms->Ncp))) {
-    if (frame_parms->nb_antenna_ports_gNB==1) { // 10 out of 12 so don't reduce size
-      nb_rb=1+(5*nb_rb/6);
-    }
-    else {
-      pilots=1;
-    }
-  }
+  uint32_t nb_rb_0 = length/12 + ((length%12)?1:0);
 
   for (aatx=0; aatx<frame_parms->nb_antenna_ports_gNB; aatx++) {
     if (mod_order == 4) {
@@ -1136,7 +1135,7 @@ void nr_dlsch_channel_compensation(int **rxdataF_ext,
       rxdataF128        = (int16x4_t*)&rxdataF_ext[aarx][symbol*frame_parms->N_RB_DL*12];
       rxdataF_comp128   = (int16x4x2_t*)&rxdataF_comp[(aatx<<1)+aarx][symbol*frame_parms->N_RB_DL*12];
 
-      for (rb=0; rb<nb_rb; rb++) {
+      for (rb=0; rb<nb_rb_0; rb++) {
   if (mod_order>2) {
     // get channel amplitude if not QPSK
     mmtmpD0 = vmull_s16(dl_ch128[0], dl_ch128[0]);
@@ -1152,23 +1151,20 @@ void nr_dlsch_channel_compensation(int **rxdataF_ext,
     mmtmpD1 = vmull_s16(dl_ch128[3], dl_ch128[3]);
     mmtmpD1 = vqshlq_s32(vqaddq_s32(mmtmpD1,vrev64q_s32(mmtmpD1)),output_shift128);
     mmtmpD3 = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1));
-    if (pilots==0) {
-      mmtmpD0 = vmull_s16(dl_ch128[4], dl_ch128[4]);
-      mmtmpD0 = vqshlq_s32(vqaddq_s32(mmtmpD0,vrev64q_s32(mmtmpD0)),output_shift128);
-      mmtmpD1 = vmull_s16(dl_ch128[5], dl_ch128[5]);
-      mmtmpD1 = vqshlq_s32(vqaddq_s32(mmtmpD1,vrev64q_s32(mmtmpD1)),output_shift128);
-      mmtmpD4 = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1));
-    }
+
+    mmtmpD0 = vmull_s16(dl_ch128[4], dl_ch128[4]);
+    mmtmpD0 = vqshlq_s32(vqaddq_s32(mmtmpD0,vrev64q_s32(mmtmpD0)),output_shift128);
+    mmtmpD1 = vmull_s16(dl_ch128[5], dl_ch128[5]);
+    mmtmpD1 = vqshlq_s32(vqaddq_s32(mmtmpD1,vrev64q_s32(mmtmpD1)),output_shift128);
+    mmtmpD4 = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1));
 
     dl_ch_mag128b[0] = vqdmulhq_s16(mmtmpD2,QAM_amp128b);
     dl_ch_mag128b[1] = vqdmulhq_s16(mmtmpD3,QAM_amp128b);
     dl_ch_mag128[0] = vqdmulhq_s16(mmtmpD2,QAM_amp128);
     dl_ch_mag128[1] = vqdmulhq_s16(mmtmpD3,QAM_amp128);
 
-    if (pilots==0) {
-      dl_ch_mag128b[2] = vqdmulhq_s16(mmtmpD4,QAM_amp128b);
-      dl_ch_mag128[2]  = vqdmulhq_s16(mmtmpD4,QAM_amp128);
-    }
+    dl_ch_mag128b[2] = vqdmulhq_s16(mmtmpD4,QAM_amp128b);
+    dl_ch_mag128[2]  = vqdmulhq_s16(mmtmpD4,QAM_amp128);
   }
 
   mmtmpD0 = vmull_s16(dl_ch128[0], rxdataF128[0]);
@@ -1202,36 +1198,29 @@ void nr_dlsch_channel_compensation(int **rxdataF_ext,
   mmtmpD1 = vqshlq_s32(mmtmpD1,output_shift128);
   rxdataF_comp128[1] = vzip_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1));
 
-  if (pilots==0) {
-    mmtmpD0 = vmull_s16(dl_ch128[4], rxdataF128[4]);
-    mmtmpD1 = vmull_s16(dl_ch128[5], rxdataF128[5]);
-    mmtmpD0 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0),vget_high_s32(mmtmpD0)),
-         vpadd_s32(vget_low_s32(mmtmpD1),vget_high_s32(mmtmpD1)));
 
-    mmtmpD0b = vmull_s16(vrev32_s16(vmul_s16(dl_ch128[4],*(int16x4_t*)conj)), rxdataF128[4]);
-    mmtmpD1b = vmull_s16(vrev32_s16(vmul_s16(dl_ch128[5],*(int16x4_t*)conj)), rxdataF128[5]);
-    mmtmpD1 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0b),vget_high_s32(mmtmpD0b)),
-         vpadd_s32(vget_low_s32(mmtmpD1b),vget_high_s32(mmtmpD1b)));
+  mmtmpD0 = vmull_s16(dl_ch128[4], rxdataF128[4]);
+  mmtmpD1 = vmull_s16(dl_ch128[5], rxdataF128[5]);
+  mmtmpD0 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0),vget_high_s32(mmtmpD0)),
+                         vpadd_s32(vget_low_s32(mmtmpD1),vget_high_s32(mmtmpD1)));
+
+  mmtmpD0b = vmull_s16(vrev32_s16(vmul_s16(dl_ch128[4],*(int16x4_t*)conj)), rxdataF128[4]);
+  mmtmpD1b = vmull_s16(vrev32_s16(vmul_s16(dl_ch128[5],*(int16x4_t*)conj)), rxdataF128[5]);
+  mmtmpD1 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0b),vget_high_s32(mmtmpD0b)),
+                         vpadd_s32(vget_low_s32(mmtmpD1b),vget_high_s32(mmtmpD1b)));
 
 
-    mmtmpD0 = vqshlq_s32(mmtmpD0,output_shift128);
-    mmtmpD1 = vqshlq_s32(mmtmpD1,output_shift128);
-    rxdataF_comp128[2] = vzip_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1));
+  mmtmpD0 = vqshlq_s32(mmtmpD0,output_shift128);
+  mmtmpD1 = vqshlq_s32(mmtmpD1,output_shift128);
+  rxdataF_comp128[2] = vzip_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1));
 
 
-    dl_ch128+=6;
-    dl_ch_mag128+=3;
-    dl_ch_mag128b+=3;
-    rxdataF128+=6;
-    rxdataF_comp128+=3;
+  dl_ch128+=6;
+  dl_ch_mag128+=3;
+  dl_ch_mag128b+=3;
+  rxdataF128+=6;
+  rxdataF_comp128+=3;
 
-  } else { // we have a smaller PDSCH in symbols with pilots so skip last group of 4 REs and increment less
-    dl_ch128+=4;
-    dl_ch_mag128+=2;
-    dl_ch_mag128b+=2;
-    rxdataF128+=4;
-    rxdataF_comp128+=2;
-  }
       }
     }
   }
@@ -1241,7 +1230,7 @@ void nr_dlsch_channel_compensation(int **rxdataF_ext,
       rho128        = (int16x4x2_t*)&rho[aarx][symbol*frame_parms->N_RB_DL*12];
       dl_ch128      = (int16x4_t*)&dl_ch_estimates_ext[aarx][symbol*frame_parms->N_RB_DL*12];
       dl_ch128_2    = (int16x4_t*)&dl_ch_estimates_ext[2+aarx][symbol*frame_parms->N_RB_DL*12];
-      for (rb=0; rb<nb_rb; rb++) {
+      for (rb=0; rb<nb_rb_0; rb++) {
   mmtmpD0 = vmull_s16(dl_ch128[0], dl_ch128_2[0]);
   mmtmpD1 = vmull_s16(dl_ch128[1], dl_ch128_2[1]);
   mmtmpD0 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0),vget_high_s32(mmtmpD0)),
@@ -1540,14 +1529,10 @@ void nr_dlsch_scale_channel(int **dl_ch_estimates_ext,
         dl_ch128[1] = _mm_mulhi_epi16(dl_ch128[1],ch_amp128);
         dl_ch128[1] = _mm_slli_epi16(dl_ch128[1],3);
 
-        if (pilots) {
-          dl_ch128+=2;
-        } else {
-          dl_ch128[2] = _mm_mulhi_epi16(dl_ch128[2],ch_amp128);
-          dl_ch128[2] = _mm_slli_epi16(dl_ch128[2],3);
-          dl_ch128+=3;
+        dl_ch128[2] = _mm_mulhi_epi16(dl_ch128[2],ch_amp128);
+        dl_ch128[2] = _mm_slli_epi16(dl_ch128[2],3);
+        dl_ch128+=3;
 
-        }
       }
     }
   }
@@ -1579,6 +1564,7 @@ void nr_dlsch_channel_level(int **dl_ch_estimates_ext,
   //x = (x>4) ? 4 : x;
   int16_t y = (len)>>x;
   //printf("len = %d = %d * 2^(%d)\n",len,y,x);
+  uint32_t nb_rb_0 = len/12 + ((len%12)?1:0);
 
   AssertFatal(y!=0,"Cannot divide by zero: in function %s of file %s\n", __func__, __FILE__);
 
@@ -1589,7 +1575,7 @@ void nr_dlsch_channel_level(int **dl_ch_estimates_ext,
 
       dl_ch128=(__m128i *)&dl_ch_estimates_ext[(aatx*frame_parms->nb_antennas_rx)+aarx][symbol*nb_rb*12];
 
-      for (rb=0;rb<nb_rb;rb++) {
+      for (rb=0;rb<nb_rb_0;rb++) {
         avg128D = _mm_add_epi32(avg128D,_mm_srai_epi32(_mm_madd_epi16(dl_ch128[0],dl_ch128[0]),x));
         avg128D = _mm_add_epi32(avg128D,_mm_srai_epi32(_mm_madd_epi16(dl_ch128[1],dl_ch128[1]),x));
         avg128D = _mm_add_epi32(avg128D,_mm_srai_epi32(_mm_madd_epi16(dl_ch128[2],dl_ch128[2]),x));
@@ -1614,7 +1600,7 @@ void nr_dlsch_channel_level(int **dl_ch_estimates_ext,
   int16x4_t *dl_ch128;
 
   symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol;
-
+  uint32_t nb_rb_0 = len/12 + ((len%12)?1:0);
   for (aatx=0; aatx<frame_parms->nb_antenna_ports_gNB; aatx++)
     for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
       //clear average level
@@ -1623,7 +1609,7 @@ void nr_dlsch_channel_level(int **dl_ch_estimates_ext,
 
       dl_ch128=(int16x4_t *)&dl_ch_estimates_ext[(aatx<<1)+aarx][symbol*frame_parms->N_RB_DL*12];
 
-      for (rb=0; rb<nb_rb; rb++) {
+      for (rb=0; rb<nb_rb_0; rb++) {
         //  printf("rb %d : ",rb);
         //  print_shorts("ch",&dl_ch128[0]);
         avg128D = vqaddq_s32(avg128D,vmull_s16(dl_ch128[0],dl_ch128[0]));
@@ -2072,7 +2058,7 @@ unsigned short nr_dlsch_extract_rbs_single(int **rxdataF,
 
   unsigned char j=0;
 
-  if (config_type==pdsch_dmrs_type1) {
+  if (config_type==NFAPI_NR_DMRS_TYPE1) {
     AssertFatal(n_dmrs_cdm_groups == 1 || n_dmrs_cdm_groups == 2,
                 "n_dmrs_cdm_groups %d is illegal\n",n_dmrs_cdm_groups);
     nushift = n_dmrs_cdm_groups -1;//delta in Table 7.4.1.1.2-1
@@ -2097,7 +2083,7 @@ unsigned short nr_dlsch_extract_rbs_single(int **rxdataF,
     rxF       = &rxdataF[aarx][(k+(symbol*(frame_parms->ofdm_symbol_size)))];
     
     for (rb = 0; rb < nb_rb_pdsch; rb++) {
-      if (k>frame_parms->ofdm_symbol_size) {
+      if (k>=frame_parms->ofdm_symbol_size) {
         k = k-frame_parms->ofdm_symbol_size;
         rxF = &rxdataF[aarx][(k+(symbol*(frame_parms->ofdm_symbol_size)))];
       }
@@ -2108,7 +2094,7 @@ unsigned short nr_dlsch_extract_rbs_single(int **rxdataF,
         rxF_ext+=12;
       } else {//the symbol contains DMRS
         j=0;
-        if (config_type==pdsch_dmrs_type1){
+        if (config_type==NFAPI_NR_DMRS_TYPE1){
           if (nushift == 0) {//data is multiplexed
             for (i = (1-nushift); i<12; i+=2) {
               rxF_ext[j]=rxF[i];
@@ -2118,7 +2104,7 @@ unsigned short nr_dlsch_extract_rbs_single(int **rxdataF,
             dl_ch0_ext+=6;
             rxF_ext+=6;
           }
-        } else {//pdsch_dmrs_type2
+        } else {//NFAPI_NR_DMRS_TYPE2
           for (i = (2+nushift); i<6; i++) {
             rxF_ext[j]=rxF[i];
             dl_ch0_ext[j]=dl_ch0[i];
@@ -2166,7 +2152,7 @@ unsigned short nr_dlsch_extract_rbs_multiple(int **rxdataF,
   int *dl_ch0,*dl_ch0_ext,*rxF,*rxF_ext;
   int8_t validDmrsEst = 0; //store last DMRS Symbol index
 
-  if (config_type==pdsch_dmrs_type1) {
+  if (config_type==NFAPI_NR_DMRS_TYPE1) {
     AssertFatal(n_dmrs_cdm_groups == 1 || n_dmrs_cdm_groups == 2,
                 "n_dmrs_cdm_groups %d is illegal\n",n_dmrs_cdm_groups);
     nushift = n_dmrs_cdm_groups -1;//delta in Table 7.4.1.1.2-1
@@ -2181,7 +2167,7 @@ unsigned short nr_dlsch_extract_rbs_multiple(int **rxdataF,
   for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
 
     k = frame_parms->first_carrier_offset + NR_NB_SC_PER_RB*start_rb;
-    if (k>frame_parms->ofdm_symbol_size)
+    if (k>=frame_parms->ofdm_symbol_size)
       k = k-frame_parms->ofdm_symbol_size;
 
     rxF_ext   = &rxdataF_ext[aarx][symbol*(nb_rb_pdsch*12)];
@@ -2204,7 +2190,7 @@ unsigned short nr_dlsch_extract_rbs_multiple(int **rxdataF,
         }
         else {//the symbol contains DMRS
           j=0;
-          if (config_type==pdsch_dmrs_type1) {
+          if (config_type==NFAPI_NR_DMRS_TYPE1) {
             if (nushift == 0) {//data is multiplexed
               for (i = (1-nushift); i<12; i+=2) {
                 if (aatx==0) rxF_ext[j]=rxF[i];
@@ -2215,7 +2201,7 @@ unsigned short nr_dlsch_extract_rbs_multiple(int **rxdataF,
               if (aatx==0) rxF_ext+=6;
             }
           }
-          else {//pdsch_dmrs_type2
+          else {//NFAPI_NR_DMRS_TYPE2
             for (i = (2+nushift); i<6; i++) {
               if (aatx==0) rxF_ext[j]=rxF[i];
               dl_ch0_ext[j]=dl_ch0[i];
@@ -2250,43 +2236,55 @@ void nr_dlsch_detection_mrc(int **rxdataF_comp,
                             int ***rho,
                             int **dl_ch_mag,
                             int **dl_ch_magb,
+                            int **dl_ch_magr,
                             short n_tx,
                             short n_rx,
                             unsigned char symbol,
-                            unsigned short nb_rb) {
+                            unsigned short nb_rb,
+                            int length) {
 #if defined(__x86_64__)||defined(__i386__)
   unsigned char aatx, aarx;
   int i;
-  __m128i *rxdataF_comp128_0,*rxdataF_comp128_1,*dl_ch_mag128_0,*dl_ch_mag128_1,*dl_ch_mag128_0b,*dl_ch_mag128_1b;
+  __m128i *rxdataF_comp128_0,*rxdataF_comp128_1,*dl_ch_mag128_0,*dl_ch_mag128_1,*dl_ch_mag128_0b,*dl_ch_mag128_1b,*dl_ch_mag128_0r,*dl_ch_mag128_1r;
+
+  uint32_t nb_rb_0 = length/12 + ((length%12)?1:0);
 
   if (n_rx>1) {
     for (aatx=0; aatx<n_tx; aatx++) {
       rxdataF_comp128_0   = (__m128i *)&rxdataF_comp[(aatx*n_rx)][symbol*nb_rb*12];//aarx=0
       dl_ch_mag128_0      = (__m128i *)&dl_ch_mag[(aatx*n_rx)][symbol*nb_rb*12];//aarx=0
       dl_ch_mag128_0b     = (__m128i *)&dl_ch_magb[(aatx*n_rx)][symbol*nb_rb*12];
+      dl_ch_mag128_0r     = (__m128i *)&dl_ch_magr[(aatx*n_rx)][symbol*nb_rb*12];
       for (aarx=1; aarx<n_rx; aarx++) {
         rxdataF_comp128_1   = (__m128i *)&rxdataF_comp[(aatx*n_rx)+aarx][symbol*nb_rb*12];// aarx=1,..., n_rx-1
         dl_ch_mag128_1      = (__m128i *)&dl_ch_mag[(aatx*n_rx)+aarx][symbol*nb_rb*12];
         dl_ch_mag128_1b     = (__m128i *)&dl_ch_magb[(aatx*n_rx)+aarx][symbol*nb_rb*12];
+        dl_ch_mag128_1r     = (__m128i *)&dl_ch_magr[(aatx*n_rx)+aarx][symbol*nb_rb*12];
 
-        // MRC on each re of rb, both on MF output and magnitude (for 16QAM/64QAM llr computation)
-        for (i=0; i<nb_rb*3; i++) {
+        // MRC on each re of rb, both on MF output and magnitude (for 16QAM/64QAM/256 llr computation)
+        for (i=0; i<nb_rb_0*3; i++) {
           rxdataF_comp128_0[i] = _mm_adds_epi16(rxdataF_comp128_0[i],rxdataF_comp128_1[i]);
           dl_ch_mag128_0[i]    = _mm_adds_epi16(dl_ch_mag128_0[i],dl_ch_mag128_1[i]);
           dl_ch_mag128_0b[i]   = _mm_adds_epi16(dl_ch_mag128_0b[i],dl_ch_mag128_1b[i]);
-          /*if (i==0) {
-           * printf("atx%d symbol%d\n",aatx,symbol);
-           * printf("mrc comp0 re: %d mrc comp0 im: %d \n",((int16_t*)&rxdataF_comp128_0[0])[0],((int16_t*)&rxdataF_comp128_0[0])[1]);
-           * printf("mrc mag0 = %d = %d \n",((int16_t*)&dl_ch_mag128_0[0])[0],((int16_t*)&dl_ch_mag128_0[0])[1]);
-           * printf("mrc mag0b = %d = %d \n",((int16_t*)&dl_ch_mag128_0b[0])[0],((int16_t*)&dl_ch_mag128_0b[0])[1]);
-           * }*/
+          dl_ch_mag128_0r[i]   = _mm_adds_epi16(dl_ch_mag128_0r[i],dl_ch_mag128_1r[i]);
         }
       }
     }
+#ifdef DEBUG_DLSCH_DEMOD
+    for (i=0; i<nb_rb_0*3; i++) {
+    printf("symbol%d RB %d\n",symbol,i/3);
+    rxdataF_comp128_0   = (__m128i *)&rxdataF_comp[0][symbol*nb_rb*12];
+    rxdataF_comp128_1   = (__m128i *)&rxdataF_comp[n_rx][symbol*nb_rb*12];
+    print_shorts("tx 1 mrc_re/mrc_Im:",(int16_t*)&rxdataF_comp128_0[i]);
+    print_shorts("tx 2 mrc_re/mrc_Im:",(int16_t*)&rxdataF_comp128_1[i]);
+    // printf("mrc mag0 = %d = %d \n",((int16_t*)&dl_ch_mag128_0[0])[0],((int16_t*)&dl_ch_mag128_0[0])[1]);
+    // printf("mrc mag0b = %d = %d \n",((int16_t*)&dl_ch_mag128_0b[0])[0],((int16_t*)&dl_ch_mag128_0b[0])[1]);
+    }
+#endif
     if (rho) {
       /*rho128_0 = (__m128i *) &rho[0][symbol*frame_parms->N_RB_DL*12];
       rho128_1 = (__m128i *) &rho[1][symbol*frame_parms->N_RB_DL*12];
-      for (i=0; i<nb_rb*3; i++) {
+      for (i=0; i<nb_rb_0*3; i++) {
         //      print_shorts("mrc rho0:",&rho128_0[i]);
         //      print_shorts("mrc rho1:",&rho128_1[i]);
         rho128_0[i] = _mm_adds_epi16(_mm_srai_epi16(rho128_0[i],1),_mm_srai_epi16(rho128_1[i],1));
@@ -2308,7 +2306,8 @@ void nr_det_HhH(int32_t *after_mf_00,//a
                 int32_t *after_mf_11,//d
                 int32_t *det_fin,//1/ad-bc
                 unsigned short nb_rb,
-                unsigned char symbol)
+                unsigned char symbol,
+                int32_t shift)
 {
   int16_t nr_conjug2[8]__attribute__((aligned(16))) = {1,-1,1,-1,1,-1,1,-1} ;
   unsigned short rb;
@@ -2343,24 +2342,16 @@ void nr_det_HhH(int32_t *after_mf_00,//a
     det_re_128 = _mm_sub_epi32(ad_re_128, bc_re_128);
     //det_im_128 = _mm_sub_epi32(ad_im_128, bc_im_128);
 
-    //convert back to Q15 before packing
-    det_re_128 = _mm_srai_epi32(det_re_128,8);//(2^15/64*2)
-    //det_im_128 = _mm_srai_epi32(det_im_128,8);
-
-    //tmp_det0  = _mm_unpacklo_epi32(det_re_128,det_im_128);
-    ////print_ints("unpack lo:",&tmp_det0[rb]);
-    //tmp_det1  = _mm_unpackhi_epi32(det_re_128,det_im_128);
-    ////print_ints("unpack hi:",&tmp_det1[rb]);
-    //det_matrix_128[0] = _mm_packs_epi32(tmp_det0,tmp_det1);
+    //det in Q30 format
     det_fin_128[0] = _mm_abs_epi32(det_re_128);
 
-    /*if ((rb==0)&&(symbol==1)) {
-     * printf("\n Computing det_HhH_inv \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]);
-     * }*/
 
+#ifdef DEBUG_DLSCH_DEMOD
+     printf("\n Computing det_HhH_inv \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]);
+#endif
     det_fin_128+=1;
     after_mf_00_128+=1;
     after_mf_01_128+=1;
@@ -2455,7 +2446,67 @@ 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()
  *
  *
@@ -2534,15 +2585,16 @@ void nr_construct_HhH_elements(int *conjch00_ch00,
     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]);
 
-    /*if ((rb==0)&&(symbol==1))
+#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]);
-    }*/
-
+    }
+#endif
     conjch00_ch00_128+=1;
     conjch10_ch10_128+=1;
     conjch01_ch01_128+=1;
@@ -2579,16 +2631,18 @@ void nr_construct_HhH_elements(int *conjch00_ch00,
 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)
+                                   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)
    */
@@ -2656,49 +2710,49 @@ uint8_t nr_zero_forcing_rx_2layers(int **rxdataF_comp,
     nr_conjch0_mult_ch1(ch00,
                         ch00,
                         conjch00_ch00,
-                        nb_rb,
+                        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,
+                        nb_rb_0,
                         shift);
     // conj_H_00xH_01
     nr_conjch0_mult_ch1(ch00,
                         ch01,
                         conjch00_ch01,
-                        nb_rb,
+                        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,
+                        nb_rb_0,
                         shift);
     // conj_H_01xH_01
     nr_conjch0_mult_ch1(ch01,
                         ch01,
                         conjch01_ch01,
-                        nb_rb,
+                        nb_rb_0,
                         shift);
     // conj_H_11xH_11
     nr_conjch0_mult_ch1(ch11,
                         ch11,
                         conjch11_ch11,
-                        nb_rb,
+                        nb_rb_0,
                         shift);
     // conj_H_01xH_00
     nr_conjch0_mult_ch1(ch01,
                         ch00,
                         conjch01_ch00,
-                        nb_rb,
+                        nb_rb_0,
                         shift);
     // conj_H_11xH_10
     nr_conjch0_mult_ch1(ch11,
                         ch10,
                         conjch11_ch10,
-                        nb_rb,
+                        nb_rb_0,
                         shift);
   }
   if (n_rx==4){
@@ -2706,52 +2760,52 @@ uint8_t nr_zero_forcing_rx_2layers(int **rxdataF_comp,
     nr_conjch0_mult_ch1(ch20,
                         ch20,
                         conjch20_ch20,
-                        nb_rb,
+                        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,
+                        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,
+                        nb_rb_0,
                         shift);
 
     nr_conjch0_mult_ch1(ch30,
                         ch31,
                         conjch30_ch31,
-                        nb_rb,
+                        nb_rb_0,
                         shift);
 
     nr_conjch0_mult_ch1(ch21,
                         ch21,
                         conjch21_ch21,
-                        nb_rb,
+                        nb_rb_0,
                         shift);
 
     nr_conjch0_mult_ch1(ch31,
                         ch31,
                         conjch31_ch31,
-                        nb_rb,
+                        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,
+                        nb_rb_0,
                         shift);
 
     nr_conjch0_mult_ch1(ch31,
                         ch30,
                         conjch31_ch30,
-                        nb_rb,
+                        nb_rb_0,
                         shift);
 
     nr_construct_HhH_elements(conjch00_ch00,
@@ -2774,7 +2828,7 @@ uint8_t nr_zero_forcing_rx_2layers(int **rxdataF_comp,
                               af_mf_01,
                               af_mf_10,
                               af_mf_11,
-                              nb_rb,
+                              nb_rb_0,
                               symbol);
   }
   if (n_rx==2){
@@ -2798,7 +2852,7 @@ uint8_t nr_zero_forcing_rx_2layers(int **rxdataF_comp,
                               af_mf_01,
                               af_mf_10,
                               af_mf_11,
-                              nb_rb,
+                              nb_rb_0,
                               symbol);
   }
   //det_HhH = ad -bc
@@ -2807,8 +2861,9 @@ uint8_t nr_zero_forcing_rx_2layers(int **rxdataF_comp,
              af_mf_10,//c
              af_mf_11,//d
              determ_fin,
-             nb_rb,
-             symbol);
+             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)|
@@ -2822,92 +2877,106 @@ uint8_t nr_zero_forcing_rx_2layers(int **rxdataF_comp,
      *
      *
      **************************************************************************/
-  __m128i *rxdataF_comp128_0,*rxdataF_comp128_1,*dl_ch_mag128_0,*dl_ch_mag128b_0,*dl_ch_mag128_1,*dl_ch_mag128b_1,*determ_fin_128;
-  __m128i mmtmpD2,mmtmpD3,mmtmpD0,mmtmpD1,QAM_amp128,QAM_amp128b;
+  __m128i *rxdataF_comp128_0,*rxdataF_comp128_1,*dl_ch_mag128_0,*dl_ch_mag128b_0,*dl_ch_mag128r_0,*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,QAM_amp128b,QAM_amp128r;
 
   determ_fin_128      = (__m128i *)&determ_fin[0];
 
   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
 
-  dl_ch_mag128_0      = (__m128i *)&dl_ch_mag[0][symbol*nb_rb*12];
-  dl_ch_mag128_1      = (__m128i *)&dl_ch_mag[n_rx][symbol*nb_rb*12];
-  dl_ch_mag128b_0     = (__m128i *)&dl_ch_magb[0][symbol*nb_rb*12];
-  dl_ch_mag128b_1     = (__m128i *)&dl_ch_magb[n_rx][symbol*nb_rb*12];
-
   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;
 
-  QAM_amp128b = _mm_setzero_si128();
-
-  if (mod_order == 4) {
-    QAM_amp128 = _mm_set1_epi16(QAM16_n1);  // 2/sqrt(10)
-    QAM_amp128b = _mm_setzero_si128();
-  } else if (mod_order == 6) {
-    QAM_amp128  = _mm_set1_epi16(QAM64_n1); //
-    QAM_amp128b = _mm_set1_epi16(QAM64_n2);
+  if (mod_order>2) {
+    if (mod_order == 4) {
+      QAM_amp128 = _mm_set1_epi16(QAM16_n1);  //2/sqrt(10)
+      QAM_amp128b = _mm_setzero_si128();
+      QAM_amp128r = _mm_setzero_si128();
+    } else if (mod_order == 6) {
+      QAM_amp128  = _mm_set1_epi16(QAM64_n1); //4/sqrt{42}
+      QAM_amp128b = _mm_set1_epi16(QAM64_n2); //2/sqrt{42}
+      QAM_amp128r = _mm_setzero_si128();
+    } else if (mod_order == 8) {
+      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; rb++) {
+  for (int rb=0; rb<3*nb_rb_0; rb++) {
     if (mod_order>2) {
-      // get channel determ (da -bc) if not QPSK
-      mmtmpD0 = _mm_packs_epi32(determ_fin_128[0],determ_fin_128[0]);//convert 32 bits to 16 bits
+      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);
 
-      dl_ch_mag128_0[0] = _mm_unpacklo_epi16(mmtmpD0,mmtmpD0);
-      dl_ch_mag128b_0[0] = dl_ch_mag128_0[0];
+      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] = _mm_mulhi_epi16(dl_ch_mag128_0[0],QAM_amp128);
-      dl_ch_mag128_0[0] = _mm_slli_epi16(dl_ch_mag128_0[0],1);//aatx=0 @ aarx =0
-      dl_ch_mag128_1[0] = dl_ch_mag128_0[0];//aatx=1 @ aarx =0
+      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);//aatx=0 @ aarx =
-      dl_ch_mag128b_1[0] = dl_ch_mag128b_0[0];//aatx=1 @ aarx =0
-
-      if ((rb==0)&&(symbol==1)) {
-        printf("\n Signal mag after ZF \n");
-        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]);
-       }
+      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]);
     }
     // 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
-    mmtmpD2 = nr_inv_comp_muli(rxdataF_comp128_0[0],//x
-                               after_mf_d_128[0]);//y
-    mmtmpD3 = nr_inv_comp_muli(rxdataF_comp128_1[0],//x
-                               after_mf_b_128[0]);//y
-    //mmtmpD2[0] - mmtmpD3[0]
-    //rxdataF_zf128_0
-    mmtmpD0 = _mm_sub_epi16(mmtmpD2, mmtmpD3);
-
-    mmtmpD2 = nr_inv_comp_muli(rxdataF_comp128_1[0],//x
-                               after_mf_a_128[0]);//y
-    mmtmpD3 = nr_inv_comp_muli(rxdataF_comp128_0[0],//x
-                               after_mf_c_128[0]);//y
-    //mmtmpD2[0] - mmtmpD3[0]
-    //rxdataF_zf128_1
-    mmtmpD1 = _mm_sub_epi16(mmtmpD2, mmtmpD3);
+    //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;
-
-    /*if ((rb==0)&&(symbol==1)) {
-      printf("\n Rx signal after ZF \n");
-      print_shorts("Rx layer 1:",(int16_t*)&rxdataF_comp128_0[0]);
-      print_shorts("Rx layer 2:",(int16_t*)&rxdataF_comp128_1[0]);
-    }*/
-
+#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_mag128_1 += 1;
-    dl_ch_mag128b_1 += 1;
+    dl_ch_mag128r_0 += 1;
     rxdataF_comp128_0 += 1;
     rxdataF_comp128_1 += 1;
     after_mf_a_128 += 1;
@@ -2923,13 +2992,18 @@ uint8_t nr_zero_forcing_rx_2layers(int **rxdataF_comp,
 static void nr_dlsch_layer_demapping(int16_t **llr_cw,
 				     uint8_t Nl,
 				     uint8_t mod_order,
-				     uint16_t length,
+				     uint32_t length,
+				     int32_t codeword_TB0,
+				     int32_t codeword_TB1,
 				     int16_t **llr_layers) {
 
   switch (Nl) {
-
     case 1:
-      memcpy((void*)llr_layers[0], (void*)llr_cw[0], (length)*sizeof(int16_t));
+      if (codeword_TB1 == -1)
+        memcpy((void*)llr_cw[0], (void*)llr_layers[0], (length)*sizeof(int16_t));
+      else if (codeword_TB0 == -1)
+        memcpy((void*)llr_cw[1], (void*)llr_layers[0], (length)*sizeof(int16_t));
+
     break;
 
     case 2:
@@ -2937,11 +3011,15 @@ static void nr_dlsch_layer_demapping(int16_t **llr_cw,
     case 4:
       for (int i=0; i<(length/Nl/mod_order); i++){
         for (int l=0; l<Nl; l++) {
-        	for (int m=0; m<mod_order; m++){
-        		llr_cw[0][Nl*i+l*mod_order+m] = llr_layers[l][i*mod_order+m];
-        	}
+          for (int m=0; m<mod_order; m++){
+            if (codeword_TB1 == -1)
+              llr_cw[0][Nl*mod_order*i+l*mod_order+m] = llr_layers[l][i*mod_order+m];//i:0 -->0 1 2 3
+            else if (codeword_TB0 == -1)
+              llr_cw[1][Nl*mod_order*i+l*mod_order+m] = llr_layers[l][i*mod_order+m];//i:0 -->0 1 2 3
+            //if (i<4) printf("length%d: llr_layers[l%d][m%d]=%d: \n",length,l,m,llr_layers[l][i*mod_order+m]);
+            }
+          }
         }
-  	  }
     break;
 
   default:
@@ -3009,299 +3087,110 @@ static int nr_dlsch_llr(NR_UE_PDSCH **pdsch_vars,
 
   switch (dlsch0_harq->Qm) {
   case 2 :
-    if ((rx_type==rx_standard) || (codeword_TB1 == -1)) {
-      nr_dlsch_qpsk_llr(frame_parms,
-                        pdsch_vars[gNB_id]->rxdataF_comp0,
-                        pllr_symbol_cw0,
-                        symbol,
-                        len,
-                        first_symbol_flag,
-                        nb_rb,
-                        beamforming_mode);
-
-    } else if (codeword_TB0 == -1){
-
-      nr_dlsch_qpsk_llr(frame_parms,
-                        pdsch_vars[gNB_id]->rxdataF_comp0,
-                        pllr_symbol_cw1,
-                        symbol,
-                        len,
-                        first_symbol_flag,
-                        nb_rb,
-                        beamforming_mode);
-    }
-    else if (rx_type >= rx_IC_single_stream) {
-      if (dlsch1_harq->Qm == 2) {
-        nr_dlsch_qpsk_qpsk_llr(frame_parms,
+    switch (rx_type) {
+      case rx_standard :
+        for(int l =0; l<dlsch0_harq->Nl; l++)
+          nr_dlsch_qpsk_llr(frame_parms,
+                            pdsch_vars[gNB_id]->rxdataF_comp0[l*frame_parms->nb_antennas_rx],
+                            pdsch_vars[gNB_id]->layer_llr[l]+llr_offset_symbol,
+                            symbol,
+                            len,
+                            first_symbol_flag,
+                            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);
-        if (rx_type==rx_IC_dual_stream) {
-          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);
-        }
-      }
-      else if (dlsch1_harq->Qm == 4) {
-        nr_dlsch_qpsk_16qam_llr(frame_parms,
-                                pdsch_vars[gNB_id]->rxdataF_comp0,
-                                rxdataF_comp_ptr,//i
-                                dl_ch_mag_ptr,//i
-                                pdsch_vars[gNB_id]->dl_ch_rho2_ext,
-                                pdsch_vars[gNB_id]->layer_llr[0],
-                                symbol,first_symbol_flag,nb_rb,
-                                adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,2,nr_slot_rx,symbol),
-                                pdsch_vars[gNB_id]->llr128);
-        if (rx_type==rx_IC_dual_stream) {
-          nr_dlsch_16qam_qpsk_llr(frame_parms,
-                                  rxdataF_comp_ptr,
-                                  pdsch_vars[gNB_id]->rxdataF_comp0,//i
-                                  dl_ch_mag_ptr,
-                                  pdsch_vars[gNB_id]->dl_ch_rho_ext[harq_pid][round],
-                                  pdsch_vars[gNB_id]->layer_llr[1],
-                                  symbol,first_symbol_flag,nb_rb,
-                                  adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,4,nr_slot_rx,symbol),
-                                  pdsch_vars[gNB_id]->llr128_2ndstream);
-        }
-      }
-      else {
-        nr_dlsch_qpsk_64qam_llr(frame_parms,
-                                pdsch_vars[gNB_id]->rxdataF_comp0,
-                                rxdataF_comp_ptr,//i
-                                dl_ch_mag_ptr,//i
-                                pdsch_vars[gNB_id]->dl_ch_rho2_ext,
-                                pdsch_vars[gNB_id]->layer_llr[0],
-                                symbol,first_symbol_flag,nb_rb,
-                                adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,2,nr_slot_rx,symbol),
-                                pdsch_vars[gNB_id]->llr128);
-        if (rx_type==rx_IC_dual_stream) {
-          nr_dlsch_64qam_qpsk_llr(frame_parms,
-                                  rxdataF_comp_ptr,
-                                  pdsch_vars[gNB_id]->rxdataF_comp0,//i
-                                  dl_ch_mag_ptr,
-                                  pdsch_vars[gNB_id]->dl_ch_rho_ext[harq_pid][round],
-                                  pdsch_vars[gNB_id]->layer_llr[1],
-                                  symbol,first_symbol_flag,nb_rb,
-                                  adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,6,nr_slot_rx,symbol),
-                                  pdsch_vars[gNB_id]->llr128_2ndstream);
-        }
-      }
+                               pdsch_vars[gNB_id]->llr128);*/
+        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);*/
+        break;
+      case rx_SIC_dual_stream ://not implemented yet
+        break;
     }
     break;
   case 4 :
-    if ((rx_type==rx_standard ) || (codeword_TB1 == -1)) {
-      nr_dlsch_16qam_llr(frame_parms,
-                         pdsch_vars[gNB_id]->rxdataF_comp0,
-                         pdsch_vars[gNB_id]->llr[0],
-                         pdsch_vars[gNB_id]->dl_ch_mag0,
-                         symbol,len,first_symbol_flag,nb_rb,
-                         pdsch_vars[gNB_id]->llr128,
-                         beamforming_mode);
-    } else if (codeword_TB0 == -1){
-      nr_dlsch_16qam_llr(frame_parms,
-                         pdsch_vars[gNB_id]->rxdataF_comp0,
-                         pdsch_vars[gNB_id]->llr[1],
-                         pdsch_vars[gNB_id]->dl_ch_mag0,
-                         symbol,len,first_symbol_flag,nb_rb,
-                         pdsch_vars[gNB_id]->llr128_2ndstream,
-                         beamforming_mode);
-    }
-    else if (rx_type >= rx_IC_single_stream) {
-      if (dlsch1_harq->Qm == 2) {
-        nr_dlsch_16qam_qpsk_llr(frame_parms,
-                                pdsch_vars[gNB_id]->rxdataF_comp0,
-                                rxdataF_comp_ptr,//i
-                                pdsch_vars[gNB_id]->dl_ch_mag0,
-                                pdsch_vars[gNB_id]->dl_ch_rho2_ext,
-                                pdsch_vars[gNB_id]->layer_llr[0],
-                                symbol,first_symbol_flag,nb_rb,
-                                adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,4,nr_slot_rx,symbol),
-                                pdsch_vars[gNB_id]->llr128);
-        if (rx_type==rx_IC_dual_stream) {
-          nr_dlsch_qpsk_16qam_llr(frame_parms,
-                                  rxdataF_comp_ptr,
-                                  pdsch_vars[gNB_id]->rxdataF_comp0,//i
-                                  pdsch_vars[gNB_id]->dl_ch_mag0,//i
-                                  pdsch_vars[gNB_id]->dl_ch_rho_ext[harq_pid][round],
-                                  pdsch_vars[gNB_id]->layer_llr[1],
-                                  symbol,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);
-        }
-      }
-      else if (dlsch1_harq->Qm == 4) {
-        nr_dlsch_16qam_16qam_llr(frame_parms,
-                                 pdsch_vars[gNB_id]->rxdataF_comp0,
-                                 rxdataF_comp_ptr,//i
-                                 pdsch_vars[gNB_id]->dl_ch_mag0,
-                                 dl_ch_mag_ptr,//i
-                                 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,4,nr_slot_rx,symbol),
-                                 pdsch_vars[gNB_id]->llr128);
-        if (rx_type==rx_IC_dual_stream) {
-          nr_dlsch_16qam_16qam_llr(frame_parms,
-                                   rxdataF_comp_ptr,
-                                   pdsch_vars[gNB_id]->rxdataF_comp0,//i
-                                   dl_ch_mag_ptr,
-                                   pdsch_vars[gNB_id]->dl_ch_mag0,//i
-                                   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,4,nr_slot_rx,symbol),
-                                   pdsch_vars[gNB_id]->llr128_2ndstream);
-        }
-      }
-      else {
-        nr_dlsch_16qam_64qam_llr(frame_parms,
-                                 pdsch_vars[gNB_id]->rxdataF_comp0,
-                                 rxdataF_comp_ptr,//i
-                                 pdsch_vars[gNB_id]->dl_ch_mag0,
-                                 dl_ch_mag_ptr,//i
-                                 pdsch_vars[gNB_id]->dl_ch_rho2_ext,
-                                 pdsch_vars[gNB_id]->layer_llr[0],
-                                 symbol,first_symbol_flag,nb_rb,
-                                 adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,4,nr_slot_rx,symbol),
-                                 pdsch_vars[gNB_id]->llr128);
-        if (rx_type==rx_IC_dual_stream) {
-          nr_dlsch_64qam_16qam_llr(frame_parms,
-                                   rxdataF_comp_ptr,
-                                   pdsch_vars[gNB_id]->rxdataF_comp0,
-                                   dl_ch_mag_ptr,
-                                   pdsch_vars[gNB_id]->dl_ch_mag0,
-                                   pdsch_vars[gNB_id]->dl_ch_rho_ext[harq_pid][round],
-                                   pdsch_vars[gNB_id]->layer_llr[1],
-                                   symbol,first_symbol_flag,nb_rb,
-                                   adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,6,nr_slot_rx,symbol),
-                                   pdsch_vars[gNB_id]->llr128_2ndstream);
-        }
-      }
+    switch (rx_type) {
+      case rx_standard :
+        for(int l =0; l<dlsch0_harq->Nl; l++)
+          nr_dlsch_16qam_llr(frame_parms,
+                             pdsch_vars[gNB_id]->rxdataF_comp0[l*frame_parms->nb_antennas_rx],
+                             pdsch_vars[gNB_id]->layer_llr[l]+llr_offset_symbol,
+                             pdsch_vars[gNB_id]->dl_ch_mag0[0],
+                             symbol,
+                             len,
+                             first_symbol_flag,
+                             nb_rb,
+                             beamforming_mode);
+        break;
+      case rx_IC_single_stream ://not implemented yet
+        break;
+      case rx_IC_dual_stream ://not implemented yet
+        break;
+      case rx_SIC_dual_stream ://not implemented yet
+        break;
     }
     break;
   case 6 :
-    if ((rx_type==rx_standard) || (codeword_TB1 == -1))  {
-      nr_dlsch_64qam_llr(frame_parms,
-                         pdsch_vars[gNB_id]->rxdataF_comp0,
-                         (int16_t*)pllr_symbol_cw0,
-                         pdsch_vars[gNB_id]->dl_ch_mag0,
-                         pdsch_vars[gNB_id]->dl_ch_magb0,
-                         symbol,len,first_symbol_flag,nb_rb,
-                         pdsch_vars[gNB_id]->llr_offset[symbol],
-                         beamforming_mode);
-    } else if (codeword_TB0 == -1){
-      nr_dlsch_64qam_llr(frame_parms,
-                         pdsch_vars[gNB_id]->rxdataF_comp0,
-                         pllr_symbol_cw1,
-                         pdsch_vars[gNB_id]->dl_ch_mag0,
-                         pdsch_vars[gNB_id]->dl_ch_magb0,
-                         symbol,len,first_symbol_flag,nb_rb,
-                         pdsch_vars[gNB_id]->llr_offset[symbol],
-                         beamforming_mode);
-    }
-    else if (rx_type >= rx_IC_single_stream) {
-      if (dlsch1_harq->Qm == 2) {
-        nr_dlsch_64qam_qpsk_llr(frame_parms,
-                                pdsch_vars[gNB_id]->rxdataF_comp0,
-                                rxdataF_comp_ptr,//i
-                                pdsch_vars[gNB_id]->dl_ch_mag0,
-                                pdsch_vars[gNB_id]->dl_ch_rho2_ext,
-                                pdsch_vars[gNB_id]->layer_llr[0],
-                                symbol,first_symbol_flag,nb_rb,
-                                adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,6,nr_slot_rx,symbol),
-                                pdsch_vars[gNB_id]->llr128);
-        if (rx_type==rx_IC_dual_stream) {
-          nr_dlsch_qpsk_64qam_llr(frame_parms,
-                                  rxdataF_comp_ptr,
-                                  pdsch_vars[gNB_id]->rxdataF_comp0,//i
-                                  pdsch_vars[gNB_id]->dl_ch_mag0,
-                                  pdsch_vars[gNB_id]->dl_ch_rho_ext[harq_pid][round],
-                                  pdsch_vars[gNB_id]->layer_llr[1],
-                                  symbol,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);
-        }
-      }
-      else if (dlsch1_harq->Qm == 4) {
-        nr_dlsch_64qam_16qam_llr(frame_parms,
-                                 pdsch_vars[gNB_id]->rxdataF_comp0,
-                                 rxdataF_comp_ptr,//i
-                                 pdsch_vars[gNB_id]->dl_ch_mag0,
-                                 dl_ch_mag_ptr,//i
-                                 pdsch_vars[gNB_id]->dl_ch_rho2_ext,
-                                 pdsch_vars[gNB_id]->layer_llr[0],
-                                 symbol,first_symbol_flag,nb_rb,
-                                 adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,6,nr_slot_rx,symbol),
-                                 pdsch_vars[gNB_id]->llr128);
-        if (rx_type==rx_IC_dual_stream) {
-          nr_dlsch_16qam_64qam_llr(frame_parms,
-                                   rxdataF_comp_ptr,
-                                   pdsch_vars[gNB_id]->rxdataF_comp0,//i
-                                   dl_ch_mag_ptr,
-                                   pdsch_vars[gNB_id]->dl_ch_mag0,//i
-                                   pdsch_vars[gNB_id]->dl_ch_rho_ext[harq_pid][round],
-                                   pdsch_vars[gNB_id]->layer_llr[1],
-                                   symbol,first_symbol_flag,nb_rb,
-                                   adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,4,nr_slot_rx,symbol),
-                                   pdsch_vars[gNB_id]->llr128_2ndstream);
-        }
-      }
-      else {
-        nr_dlsch_64qam_64qam_llr(frame_parms,
-                                 pdsch_vars[gNB_id]->rxdataF_comp0,
-                                 rxdataF_comp_ptr,//i
-                                 pdsch_vars[gNB_id]->dl_ch_mag0,
-                                 dl_ch_mag_ptr,//i
-                                 pdsch_vars[gNB_id]->dl_ch_rho2_ext,
-                                 (int16_t*)pllr_symbol_layer0,
-                                 symbol,len,first_symbol_flag,nb_rb,
-                                 adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,6,nr_slot_rx,symbol),
-                                 pdsch_vars[gNB_id]->llr_offset[symbol]);
-        if (rx_type==rx_IC_dual_stream) {
-          nr_dlsch_64qam_64qam_llr(frame_parms,
-                                   rxdataF_comp_ptr,
-                                   pdsch_vars[gNB_id]->rxdataF_comp0,//i
-                                   dl_ch_mag_ptr,
-                                   pdsch_vars[gNB_id]->dl_ch_mag0,//i
-                                   pdsch_vars[gNB_id]->dl_ch_rho_ext[harq_pid][round],
-                                   pllr_symbol_layer1,
-                                   symbol,len,first_symbol_flag,nb_rb,
-                                   adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,6,nr_slot_rx,symbol),
-                                   pdsch_vars[gNB_id]->llr_offset[symbol]);
-        }
-      }
+    switch (rx_type) {
+      case rx_standard :
+        for(int l =0; l<dlsch0_harq->Nl; l++)
+          nr_dlsch_64qam_llr(frame_parms,
+                             pdsch_vars[gNB_id]->rxdataF_comp0[l*frame_parms->nb_antennas_rx],
+                             pdsch_vars[gNB_id]->layer_llr[l]+llr_offset_symbol,
+                             pdsch_vars[gNB_id]->dl_ch_mag0[0],
+                             pdsch_vars[gNB_id]->dl_ch_magb0[0],
+                             symbol,
+                             len,
+                             first_symbol_flag,
+                             nb_rb,
+                             beamforming_mode);
+        break;
+      case rx_IC_single_stream ://not implemented yet
+        break;
+      case rx_IC_dual_stream ://not implemented yet
+        break;
+      case rx_SIC_dual_stream ://not implemented yet
+        break;
     }
+
     break;
   case 8:
-    if ((rx_type==rx_standard) || (codeword_TB1 == -1))  {
-      nr_dlsch_256qam_llr(frame_parms,
-                      pdsch_vars[gNB_id]->rxdataF_comp0,
-                      (int16_t*)pllr_symbol_cw0,
-                      pdsch_vars[gNB_id]->dl_ch_mag0,
-                      pdsch_vars[gNB_id]->dl_ch_magb0,
-                      pdsch_vars[gNB_id]->dl_ch_magr0,
-                      symbol,len,first_symbol_flag,nb_rb,
-                      pdsch_vars[gNB_id]->llr_offset[symbol],
-                      beamforming_mode);
-    } else if (codeword_TB0 == -1){
-      nr_dlsch_256qam_llr(frame_parms,
-                      pdsch_vars[gNB_id]->rxdataF_comp0,
-                      pllr_symbol_cw1,
-                      pdsch_vars[gNB_id]->dl_ch_mag0,
-                      pdsch_vars[gNB_id]->dl_ch_magb0,
-                      pdsch_vars[gNB_id]->dl_ch_magr0,
-                      symbol,len,first_symbol_flag,nb_rb,
-                      pdsch_vars[gNB_id]->llr_offset[symbol],
-                      beamforming_mode);
+    switch (rx_type) {
+      case rx_standard :
+        for(int l =0; l<dlsch0_harq->Nl; l++)
+          nr_dlsch_256qam_llr(frame_parms,
+                              pdsch_vars[gNB_id]->rxdataF_comp0[l*frame_parms->nb_antennas_rx],
+                              pdsch_vars[gNB_id]->layer_llr[l]+llr_offset_symbol,
+                              pdsch_vars[gNB_id]->dl_ch_mag0[0],
+                              pdsch_vars[gNB_id]->dl_ch_magb0[0],
+                              pdsch_vars[gNB_id]->dl_ch_magr0[0],
+                              symbol,
+                              len,
+                              first_symbol_flag,
+                              nb_rb,
+                              beamforming_mode);
+        break;
+      case rx_IC_single_stream ://not implemented yet
+        break;
+      case rx_IC_dual_stream ://not implemented yet
+        break;
+      case rx_SIC_dual_stream ://not implemented yet
+        break;
     }
     break;
   default:
@@ -3315,45 +3204,54 @@ static int nr_dlsch_llr(NR_UE_PDSCH **pdsch_vars,
     case 2 :
       if (rx_type==rx_standard) {
         nr_dlsch_qpsk_llr(frame_parms,
-                          pdsch_vars[gNB_id]->rxdataF_comp0,
-                          pllr_symbol_cw0,
-                          symbol,len,first_symbol_flag,nb_rb,
+                          pdsch_vars[gNB_id]->rxdataF_comp0[0],
+                          pdsch_vars[gNB_id]->layer_llr[0]+llr_offset_symbol,
+                          symbol,
+                          len,
+                          first_symbol_flag,
+                          nb_rb,
                           beamforming_mode);
       }
       break;
     case 4:
       if (rx_type==rx_standard) {
         nr_dlsch_16qam_llr(frame_parms,
-                           pdsch_vars[gNB_id]->rxdataF_comp0,
-                           pdsch_vars[gNB_id]->llr[0],
-                           pdsch_vars[gNB_id]->dl_ch_mag0,
-                           symbol,len,first_symbol_flag,nb_rb,
-                           pdsch_vars[gNB_id]->llr128,
+                           pdsch_vars[gNB_id]->rxdataF_comp0[0],
+                           pdsch_vars[gNB_id]->layer_llr[0]+llr_offset_symbol,
+                           pdsch_vars[gNB_id]->dl_ch_mag0[0],
+                           symbol,
+                           len,
+                           first_symbol_flag,
+                           nb_rb,
                            beamforming_mode);
       }
       break;
     case 6 :
       if (rx_type==rx_standard) {
         nr_dlsch_64qam_llr(frame_parms,
-                           pdsch_vars[gNB_id]->rxdataF_comp0,
-                           pllr_symbol_cw0,
-                             pdsch_vars[gNB_id]->dl_ch_mag0,
-                             pdsch_vars[gNB_id]->dl_ch_magb0,
-                             symbol,len,first_symbol_flag,nb_rb,
-                             pdsch_vars[gNB_id]->llr_offset[symbol],
-                             beamforming_mode);
+                           pdsch_vars[gNB_id]->rxdataF_comp0[0],
+                           pdsch_vars[gNB_id]->layer_llr[0]+llr_offset_symbol,
+                           pdsch_vars[gNB_id]->dl_ch_mag0[0],
+                           pdsch_vars[gNB_id]->dl_ch_magb0[0],
+                           symbol,
+                           len,
+                           first_symbol_flag,
+                           nb_rb,
+                           beamforming_mode);
         }
         break;
     case 8 :
       if (rx_type==rx_standard) {
         nr_dlsch_256qam_llr(frame_parms,
-                            pdsch_vars[gNB_id]->rxdataF_comp0,
-                            pllr_symbol_cw0,
-                            pdsch_vars[gNB_id]->dl_ch_mag0,
-                            pdsch_vars[gNB_id]->dl_ch_magb0,
-                            pdsch_vars[gNB_id]->dl_ch_magr0,
-                            symbol,len,first_symbol_flag,nb_rb,
-                            pdsch_vars[gNB_id]->llr_offset[symbol],
+                            pdsch_vars[gNB_id]->rxdataF_comp0[0],
+                            pdsch_vars[gNB_id]->layer_llr[0]+llr_offset_symbol,
+                            pdsch_vars[gNB_id]->dl_ch_mag0[0],
+                            pdsch_vars[gNB_id]->dl_ch_magb0[0],
+                            pdsch_vars[gNB_id]->dl_ch_magr0[0],
+                            symbol,
+                            len,
+                            first_symbol_flag,
+                            nb_rb,
                             beamforming_mode);
       }
         break;
diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_llr_computation.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_llr_computation.c
index 68a206e7c746ec709312e4cb29bee5e7824ff4c3..a064a91d87eaee53622854dbecb986eadcd69ccb 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_llr_computation.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_llr_computation.c
@@ -629,16 +629,16 @@ __m128i tmp_result4 __attribute__ ((aligned(16)));
 //----------------------------------------------------------------------------------------------
 
 int nr_dlsch_qpsk_llr(NR_DL_FRAME_PARMS *frame_parms,
-                   int32_t **rxdataF_comp,
+                   int32_t *rxdataF_comp,
                    int16_t *dlsch_llr,
                    uint8_t symbol,
-				   uint32_t len,
-				   uint8_t first_symbol_flag,
+                   uint32_t len,
+                   uint8_t first_symbol_flag,
                    uint16_t nb_rb,
                    uint8_t beamforming_mode)
 {
 
-  uint32_t *rxF = (uint32_t*)&rxdataF_comp[0][((int32_t)symbol*nb_rb*12)];
+  uint32_t *rxF = (uint32_t *)&rxdataF_comp[((int32_t)symbol*nb_rb*12)];
   uint32_t *llr32;
   int i;
 
@@ -670,24 +670,23 @@ int nr_dlsch_qpsk_llr(NR_DL_FRAME_PARMS *frame_parms,
 //----------------------------------------------------------------------------------------------
 
 void nr_dlsch_16qam_llr(NR_DL_FRAME_PARMS *frame_parms,
-                     int32_t **rxdataF_comp,
+                     int32_t *rxdataF_comp,
                      int16_t *dlsch_llr,
-                     int32_t **dl_ch_mag,
+                     int32_t *dl_ch_mag,
                      uint8_t symbol,
-					 uint32_t len,
+                     uint32_t len,
                      uint8_t first_symbol_flag,
                      uint16_t nb_rb,
-                     int16_t **llr32p,
                      uint8_t beamforming_mode)
 {
 
 #if defined(__x86_64__) || defined(__i386__)
-  __m128i *rxF = (__m128i*)&rxdataF_comp[0][(symbol*nb_rb*12)];
+  __m128i *rxF = (__m128i*)&rxdataF_comp[(symbol*nb_rb*12)];
   __m128i *ch_mag;
   __m128i llr128[2];
   uint32_t *llr32;
 #elif defined(__arm__)
-  int16x8_t *rxF = (int16x8_t*)&rxdataF_comp[0][(symbol*nb_rb*12)];
+  int16x8_t *rxF = (int16x8_t*)&rxdataF_comp[(symbol*nb_rb*12)];
   int16x8_t *ch_mag;
   int16x8_t xmm0;
   int16_t *llr16;
@@ -699,30 +698,17 @@ void nr_dlsch_16qam_llr(NR_DL_FRAME_PARMS *frame_parms,
 
 
 #if defined(__x86_64__) || defined(__i386__)
-  if (first_symbol_flag==1) {
     llr32 = (uint32_t*)dlsch_llr;
-  } else {
-    llr32 = (uint32_t*)*llr32p;
-  }
 #elif defined(__arm__)
-  if (first_symbol_flag==1) {
     llr16 = (int16_t*)dlsch_llr;
-  } else {
-    llr16 = (int16_t*)*llr32p;
-  }
 #endif
 
 #if defined(__x86_64__) || defined(__i386__)
-  ch_mag = (__m128i*)&dl_ch_mag[0][(symbol*nb_rb*12)];
+  ch_mag = (__m128i*)&dl_ch_mag[(symbol*nb_rb*12)];
 #elif defined(__arm__)
-  ch_mag = (int16x8_t*)&dl_ch_mag[0][(symbol*nb_rb*12)];
+  ch_mag = (int16x8_t*)&dl_ch_mag[(symbol*nb_rb*12)];
 #endif
 
-  // update output pointer according to number of REs in this symbol (<<2 because 4 bits per RE)
-  if (first_symbol_flag == 1)
-    *llr32p = dlsch_llr + (len<<2);
-  else
-    *llr32p += (len<<2);
 
  // printf("len=%d\n", len);
   len_mod4 = len&3;
@@ -786,47 +772,35 @@ void nr_dlsch_16qam_llr(NR_DL_FRAME_PARMS *frame_parms,
 //----------------------------------------------------------------------------------------------
 
 void nr_dlsch_64qam_llr(NR_DL_FRAME_PARMS *frame_parms,
-			int32_t **rxdataF_comp,
+			int32_t *rxdataF_comp,
 			int16_t *dlsch_llr,
-			int32_t **dl_ch_mag,
-			int32_t **dl_ch_magb,
+			int32_t *dl_ch_mag,
+			int32_t *dl_ch_magb,
 			uint8_t symbol,
 			uint32_t len,
 			uint8_t first_symbol_flag,
 			uint16_t nb_rb,
-			uint32_t llr_offset,
 			uint8_t beamforming_mode)
 {
 #if defined(__x86_64__) || defined(__i386__)
-  __m128i *rxF = (__m128i*)&rxdataF_comp[0][(symbol*nb_rb*12)];
+  __m128i *rxF = (__m128i*)&rxdataF_comp[(symbol*nb_rb*12)];
   __m128i *ch_mag,*ch_magb;
 #elif defined(__arm__)
-  int16x8_t *rxF = (int16x8_t*)&rxdataF_comp[0][(symbol*nb_rb*12)];
+  int16x8_t *rxF = (int16x8_t*)&rxdataF_comp[(symbol*nb_rb*12)];
   int16x8_t *ch_mag,*ch_magb,xmm1,xmm2;
 #endif
   int i,len2;
   unsigned char len_mod4;
-  short *llr;
   int16_t *llr2;
-  int8_t *pllr_symbol;
-
-  /*
-  if (first_symbol_flag==1)
-    llr = dlsch_llr;
-  else
-    llr = *llr_save;
-  */
-  llr = dlsch_llr;
 
-  pllr_symbol = (int8_t*)dlsch_llr;
-  pllr_symbol += llr_offset;
+  llr2 = dlsch_llr;
 
 #if defined(__x86_64__) || defined(__i386__)
-  ch_mag = (__m128i*)&dl_ch_mag[0][(symbol*nb_rb*12)];
-  ch_magb = (__m128i*)&dl_ch_magb[0][(symbol*nb_rb*12)];
+  ch_mag = (__m128i*)&dl_ch_mag[(symbol*nb_rb*12)];
+  ch_magb = (__m128i*)&dl_ch_magb[(symbol*nb_rb*12)];
 #elif defined(__arm__)
-  ch_mag = (int16x8_t*)&dl_ch_mag[0][(symbol*nb_rb*12)];
-  ch_magb = (int16x8_t*)&dl_ch_magb[0][(symbol*nb_rb*12)];
+  ch_mag = (int16x8_t*)&dl_ch_mag[(symbol*nb_rb*12)];
+  ch_magb = (int16x8_t*)&dl_ch_magb[(symbol*nb_rb*12)];
 #endif
 
 //  printf("nr_dlsch_64qam_llr: symbol %d,nb_rb %d, len %d,pbch_pss_sss_adjust %d\n",symbol,nb_rb,len,pbch_pss_sss_adjust);
@@ -838,9 +812,6 @@ void nr_dlsch_64qam_llr(NR_DL_FRAME_PARMS *frame_parms,
              dlsch_llr,
              pllr_symbol);*/
 
-  llr2 = llr;
-  llr += (len*6);
-
   len_mod4 =len&3;
   len2=len>>2;  // length in quad words (4 REs)
   len2+=((len_mod4==0)?0:1);
@@ -1095,43 +1066,29 @@ void nr_dlsch_64qam_llr_SIC(NR_DL_FRAME_PARMS *frame_parms,
 //----------------------------------------------------------------------------------------------
 
 void nr_dlsch_256qam_llr(NR_DL_FRAME_PARMS *frame_parms,
-                     int32_t **rxdataF_comp,
+                     int32_t *rxdataF_comp,
                      int16_t *dlsch_llr,
-                     int32_t **dl_ch_mag,
-                     int32_t **dl_ch_magb,
-                     int32_t **dl_ch_magr,
+                     int32_t *dl_ch_mag,
+                     int32_t *dl_ch_magb,
+                     int32_t *dl_ch_magr,
                      uint8_t symbol,
                      uint32_t len,
                      uint8_t first_symbol_flag,
                      uint16_t nb_rb,
-                     uint32_t llr_offset,
                      uint8_t beamforming_mode)
 {
-  __m128i *rxF = (__m128i*)&rxdataF_comp[0][(symbol*nb_rb*12)];
+  __m128i *rxF = (__m128i*)&rxdataF_comp[(symbol*nb_rb*12)];
   __m128i *ch_mag,*ch_magb,*ch_magr;
 
   int i,len2;
   unsigned char len_mod4;
-  short *llr;
   int16_t *llr2;
-  int8_t *pllr_symbol;
-
-  /*
-  if (first_symbol_flag==1)
-    llr = dlsch_llr;
-  else
-    llr = *llr_save;
-  */
-  llr = dlsch_llr;
 
-  pllr_symbol = (int8_t*)dlsch_llr;
-  pllr_symbol += llr_offset;
+  llr2 = dlsch_llr;
 
-  ch_mag = (__m128i*)&dl_ch_mag[0][(symbol*nb_rb*12)];
-  ch_magb = (__m128i*)&dl_ch_magb[0][(symbol*nb_rb*12)];
-  ch_magr = (__m128i*)&dl_ch_magr[0][(symbol*nb_rb*12)];
-  llr2 = llr;
-  llr += (len*8);
+  ch_mag = (__m128i*)&dl_ch_mag[(symbol*nb_rb*12)];
+  ch_magb = (__m128i*)&dl_ch_magb[(symbol*nb_rb*12)];
+  ch_magr = (__m128i*)&dl_ch_magr[(symbol*nb_rb*12)];
 
   len_mod4 =len&3;
   len2=len>>2;  // length in quad words (4 REs)
diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_prach.c b/openair1/PHY/NR_UE_TRANSPORT/nr_prach.c
index 0d372deedf5f94ccbeed8bf3c29a1839bd0f07a6..e7cf3c15a913a3127a1516c9a80fc583d09f62b9 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_prach.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_prach.c
@@ -66,7 +66,7 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){
 
   uint8_t Mod_id, fd_occasion, preamble_index, restricted_set, not_found;
   uint16_t rootSequenceIndex, prach_fmt_id, NCS, *prach_root_sequence_map, preamble_offset = 0;
-  uint16_t preamble_shift = 0, preamble_index0, n_shift_ra, n_shift_ra_bar, d_start=0, numshift, N_ZC, u, offset, offset2, first_nonzero_root_idx;
+  uint16_t preamble_shift = 0, preamble_index0, n_shift_ra, n_shift_ra_bar, d_start=INT16_MAX, numshift, N_ZC, u, offset, offset2, first_nonzero_root_idx;
   int16_t prach_tmp[98304*2*4] __attribute__((aligned(32)));
 
   int16_t Ncp = 0, amp, *prach, *prach2, *prachF, *Xu;
@@ -218,12 +218,12 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){
   k *= 2;
 
   LOG_I(PHY, "PRACH [UE %d] in slot %d, placing PRACH in position %d, msg1 frequency start %d (k1 %d), preamble_offset %d, first_nonzero_root_idx %d\n", Mod_id,
-    slot,
-    k,
-    n_ra_prb,
-    nrUE_config->prach_config.num_prach_fd_occasions_list[fd_occasion].k1,
-    preamble_offset,
-    first_nonzero_root_idx);
+        slot,
+        k,
+        n_ra_prb,
+        nrUE_config->prach_config.num_prach_fd_occasions_list[fd_occasion].k1,
+        preamble_offset,
+        first_nonzero_root_idx);
 
   Xu = (int16_t*)ue->X_u[preamble_offset-first_nonzero_root_idx];
 
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 1e7e10def70891889b033605743d55b403711e95..eb56c76366b1a855affd2d438bca4666b81a2349 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h
@@ -471,7 +471,7 @@ int nr_dlsch_64qam_64qam_llr(NR_DL_FRAME_PARMS *frame_parms,
     @param beamforming_mode beamforming mode
 */
 int32_t nr_dlsch_qpsk_llr(NR_DL_FRAME_PARMS *frame_parms,
-                   int32_t **rxdataF_comp,
+                   int32_t *rxdataF_comp,
                    int16_t *dlsch_llr,
                    uint8_t symbol,
 				   uint32_t len,
@@ -505,14 +505,13 @@ int32_t nr_dlsch_qpsk_llr_SIC(NR_DL_FRAME_PARMS *frame_parms,
                            uint32_t rb_alloc);
 
 void nr_dlsch_16qam_llr(NR_DL_FRAME_PARMS *frame_parms,
-                     int32_t **rxdataF_comp,
+                     int32_t *rxdataF_comp,
                      int16_t *dlsch_llr,
-                     int32_t **dl_ch_mag,
+                     int32_t *dl_ch_mag,
                      uint8_t symbol,
-					 uint32_t len,
+                     uint32_t len,
                      uint8_t first_symbol_flag,
                      uint16_t nb_rb,
-                     int16_t **llr32p,
                      uint8_t beamforming_mode);
 /**
    \brief This function generates log-likelihood ratios (decoder input) for single-stream 16QAM received waveforms
@@ -553,28 +552,26 @@ void dlsch_64qam_llr_SIC(NR_DL_FRAME_PARMS *frame_parms,
                          uint32_t rb_alloc);
 
 void nr_dlsch_64qam_llr(NR_DL_FRAME_PARMS *frame_parms,
-                     int32_t **rxdataF_comp,
+                     int32_t *rxdataF_comp,
                      int16_t *dlsch_llr,
-                     int32_t **dl_ch_mag,
-                     int32_t **dl_ch_magb,
+                     int32_t *dl_ch_mag,
+                     int32_t *dl_ch_magb,
                      uint8_t symbol,
-					 uint32_t len,
+                     uint32_t len,
                      uint8_t first_symbol_flag,
                      uint16_t nb_rb,
-                     uint32_t llr_offset,
                      uint8_t beamforming_mode);
 
 void nr_dlsch_256qam_llr(NR_DL_FRAME_PARMS *frame_parms,
-                     int32_t **rxdataF_comp,
+                     int32_t *rxdataF_comp,
                      int16_t *dlsch_llr,
-                     int32_t **dl_ch_mag,
-                     int32_t **dl_ch_magb,
-                     int32_t **dl_ch_magr,
+                     int32_t *dl_ch_mag,
+                     int32_t *dl_ch_magb,
+                     int32_t *dl_ch_magr,
                      uint8_t symbol,
                      uint32_t len,
                      uint8_t first_symbol_flag,
                      uint16_t nb_rb,
-                     uint32_t llr_offset,
                      uint8_t beamforming_mode);
 
 /** \fn dlsch_siso(NR_DL_FRAME_PARMS *frame_parms,
@@ -807,7 +804,7 @@ void nr_dlsch_channel_compensation(int32_t **rxdataF_ext,
                                 NR_DL_FRAME_PARMS *frame_parms,
                                 uint8_t nb_aatx,
                                 uint8_t symbol,
-								uint8_t start_symbol,
+                                int length,
                                 uint8_t first_symbol_flag,
                                 uint8_t mod_order,
                                 uint16_t nb_rb,
@@ -891,13 +888,15 @@ void nr_dlsch_channel_level_median(int **dl_ch_estimates_ext,
                                 int start_point);
 
 void nr_dlsch_detection_mrc(int **rxdataF_comp,
-        int ***rho,
-        int **dl_ch_mag,
-        int **dl_ch_magb,
-        short n_tx,
-        short n_rx,
-        unsigned char symbol,
-        unsigned short nb_rb);
+                            int ***rho,
+                            int **dl_ch_mag,
+                            int **dl_ch_magb,
+                            int **dl_ch_magr,
+                            short n_tx,
+                            short n_rx,
+                            unsigned char symbol,
+                            unsigned short nb_rb,
+                            int length);
 
 void nr_dlsch_detection_mrc_core(int **rxdataF_comp,
                               int **rxdataF_comp_i,
diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c
index 8f3d1987bcf1a587fdbb449731c59ea70c7cd579..5733ef6eb3c3595481bdc9757a5877140e70e970 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c
@@ -40,6 +40,7 @@
 #include "PHY/NR_UE_TRANSPORT/nr_transport_ue.h"
 #include "common/utils/LOG/vcd_signal_dumper.h"
 #include "LAYER2/NR_MAC_gNB/mac_proto.h"
+#include <openair2/UTIL/OPT/opt.h>
 
 //#define DEBUG_ULSCH_CODING
 
@@ -256,7 +257,7 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch,
   Ilbrm = 0;
   Tbslbrm = 950984; //max tbs
   Coderate = 0.0;
-
+  trace_NRpdu(DIRECTION_UPLINK, harq_process->a, harq_process->pusch_pdu.pusch_data.tb_size, 0, WS_C_RNTI, 0, 0, 0,0, 0);
 ///////////
 /////////////////////////////////////////////////////////////////////////////////////////  
 
diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c
index fae6b5b2e79c4c3570d27420d414fc469b66d40b..bab801e0e36c3aad81b9309e050354b839effb06 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c
@@ -114,7 +114,6 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
 
   NR_DL_FRAME_PARMS *frame_parms = &UE->frame_parms;
   NR_UE_PUSCH *pusch_ue = UE->pusch_vars[thread_id][gNB_id];
-  // ptrs_UplinkConfig_t *ptrs_Uplink_Config = &UE->pusch_config.dmrs_UplinkConfig.ptrs_UplinkConfig;
 
   uint8_t  num_of_codewords = 1; // tmp assumption
   int      Nid_cell = 0;
diff --git a/openair1/PHY/TOOLS/calibration_test.c b/openair1/PHY/TOOLS/calibration_test.c
index 982ca9d254cb47caf105f82a5b2d864d4feaa95b..53baf83d41dbaab0834f88219300ce6fabfe4c43 100644
--- a/openair1/PHY/TOOLS/calibration_test.c
+++ b/openair1/PHY/TOOLS/calibration_test.c
@@ -10,12 +10,17 @@ unsigned int mmapped_dma=0;
 int      single_thread_flag;
 uint32_t timing_advance;
 int8_t threequarter_fs;
-int usrp_tx_thread;
 uint64_t downlink_frequency[MAX_NUM_CCs][4];
 int32_t uplink_frequency_offset[MAX_NUM_CCs][4];
 int opp_enabled;
 static double snr_dB=20;
 THREAD_STRUCT thread_struct;
+uint32_t target_ul_mcs = 9;
+uint32_t target_dl_mcs = 9;
+uint64_t dlsch_slot_bitmap = (1<<1);
+uint64_t ulsch_slot_bitmap = (1<<8);
+uint32_t target_ul_bw = 50;
+uint32_t target_dl_bw = 50;
 #include <executables/nr-softmodem.h>
 
 int read_recplayconfig(recplay_conf_t **recplay_conf, recplay_state_t **recplay_state) {return 0;}
@@ -302,6 +307,9 @@ int main(int argc, char **argv) {
 
   void ** samplesRx = (void **)malloc16(antennas* sizeof(struct complex16 *) );
   void ** samplesTx = (void **)malloc16(antennas* sizeof(struct complex16 *) );
+
+  int fd=open(getenv("rftestInputFile"),O_RDONLY);
+  AssertFatal(fd>=0,"%s",strerror(errno));
   
   for (int i=0; i<antennas; i++) {
     samplesRx[i] = (int32_t *)malloc16_clear( DFT*sizeof(struct complex16) );
@@ -313,14 +321,16 @@ int main(int argc, char **argv) {
   rfdevice.trx_start_func(&rfdevice);
   
   while(!oai_exit) {
+    for (int i=0; i<antennas; i++)
+      read(fd, samplesTx[i], DFT*sizeof(struct complex16));
     int readBlockSize = rfdevice.trx_read_func(&rfdevice,
 					       &timestamp,
-					       samplesTx,
+					       samplesRx,
 					       DFT,
 					       antennas);
     int txs = rfdevice.trx_write_func(&rfdevice,
 					    timestamp+TxAdvanceInDFTSize*DFT,
-					    samplesRx,
+					    samplesTx,
 					    DFT,
 					    antennas,
 					    0);
diff --git a/openair1/PHY/defs_nr_UE.h b/openair1/PHY/defs_nr_UE.h
index e3c0737838005c222b833a0d4b6e8d8aa3f56633..0625c6b05022c86a959818b797ebdb0db8b8a73f 100644
--- a/openair1/PHY/defs_nr_UE.h
+++ b/openair1/PHY/defs_nr_UE.h
@@ -963,25 +963,9 @@ typedef struct {
 
   //#if defined(UPGRADE_RAT_NR)
 #if 1
-
   SystemInformationBlockType1_nr_t systemInformationBlockType1_nr;
-
-  CellGroupConfig_t          cell_group_config;
-  PDSCH_ServingCellConfig_t  PDSCH_ServingCellConfig;
-  PDSCH_Config_t             PDSCH_Config;
-
   PUCCH_ConfigCommon_nr_t    pucch_config_common_nr[NUMBER_OF_CONNECTED_gNB_MAX];
   PUCCH_Config_t             pucch_config_dedicated_nr[NUMBER_OF_CONNECTED_gNB_MAX];
-
-  PUSCH_Config_t             pusch_config;
-  SRS_NR                     srs;
-
-  crossCarrierSchedulingConfig_t crossCarrierSchedulingConfig;
-  supplementaryUplink_t supplementaryUplink;
-  dmrs_DownlinkConfig_t dmrs_DownlinkConfig;
-  csi_MeasConfig_t csi_MeasConfig;
-  PUSCH_ServingCellConfig_t PUSCH_ServingCellConfig;
-
 #endif
 
   uint8_t ncs_cell[20][7];
diff --git a/openair1/PHY/defs_nr_common.h b/openair1/PHY/defs_nr_common.h
index d1d69ecabe8c9682c4fd453af587a4ebcfe40b4c..d333732d1fdbadb64e0a491e88177c493277e855 100644
--- a/openair1/PHY/defs_nr_common.h
+++ b/openair1/PHY/defs_nr_common.h
@@ -93,18 +93,18 @@
 #define NR_MAX_CSET_DURATION 3
 
 #define NR_MAX_NB_RBG 18
-#define NR_MAX_NB_LAYERS 8 // SU-MIMO (3GPP TS 38.211 V15.4.0 section 7.3.1.3)
+#define NR_MAX_NB_LAYERS 2 // 8 // SU-MIMO (3GPP TS 38.211 V15.4.0 section 7.3.1.3)
 #define NR_MAX_NB_CODEWORDS 2
 #define NR_MAX_NB_HARQ_PROCESSES 16
-#define NR_MAX_PDSCH_ENCODED_LENGTH NR_MAX_NB_RB*NR_SYMBOLS_PER_SLOT*NR_NB_SC_PER_RB*8*NR_MAX_NB_LAYERS // 8 is the maximum modulation order (it was 950984 before !!) 
+#define NR_MAX_PDSCH_ENCODED_LENGTH (NR_MAX_NB_RB*NR_SYMBOLS_PER_SLOT*NR_NB_SC_PER_RB*8*NR_MAX_NB_LAYERS) // 8 is the maximum modulation order (it was 950984 before !!)
 #define NR_MAX_PUSCH_ENCODED_LENGTH NR_MAX_PDSCH_ENCODED_LENGTH
 #define NR_MAX_PDSCH_TBS 3824
 #define NR_MAX_SIB_LENGTH 2976 // 3GPP TS 38.331 section 5.2.1 - The physical layer imposes a limit to the maximum size a SIB can take. The maximum SIB1 or SI message size is 2976 bits.
 
-#define MAX_NUM_NR_DLSCH_SEGMENTS 34
+#define MAX_NUM_NR_DLSCH_SEGMENTS (NR_MAX_NB_LAYERS*34)
 #define MAX_NR_DLSCH_PAYLOAD_BYTES (MAX_NUM_NR_DLSCH_SEGMENTS*1056)
 
-#define MAX_NUM_NR_ULSCH_SEGMENTS MAX_NUM_NR_DLSCH_SEGMENTS
+#define MAX_NUM_NR_ULSCH_SEGMENTS 34
 #define MAX_NR_ULSCH_PAYLOAD_BYTES (MAX_NUM_NR_ULSCH_SEGMENTS*1056)
 
 #define MAX_NUM_NR_CHANNEL_BITS (14*273*12*8)  // 14 symbols, 273 RB
diff --git a/openair1/PHY/impl_defs_nr.h b/openair1/PHY/impl_defs_nr.h
index a74c3675a445a65da95b4d5287e4ca5df23fe6b7..93dbf513e85e0c1a944df3e3de4d8a1bbc5ed1f0 100644
--- a/openair1/PHY/impl_defs_nr.h
+++ b/openair1/PHY/impl_defs_nr.h
@@ -339,124 +339,22 @@ typedef struct {
 *
 ************************************************************************/
 
-/* FFS TODO_NR partial structure that should be complete */
-
-typedef enum {
-  semiStatic = 0,
-  dynamic =    1
-} pdsch_HARQ_ACK_Codebook_t;
-
-
-////////////////////////////////////////////////////////////////////////////////################################
 #define MAX_NR_RATE_MATCH_PATTERNS            4
 #define MAX_NR_ZP_CSI_RS_RESOURCES           32
 #define MAX_NR_OF_DL_ALLOCATIONS             16
 #define MAX_NR_OF_UL_ALLOCATIONS            (16)
 
-typedef enum{
-  dl_resourceAllocationType0 = 1,
-  dl_resourceAllocationType1 = 2,
-  dl_dynamicSwitch = 3
-} dl_resourceAllocation_t;
-typedef enum{
-  dl_rgb_config1 = 1,
-  dl_rgb_config2 = 2
-} dl_rgb_Size_t;
-typedef enum {
-  st_n4       = 1,
-  st_wideband = 2
-} static_bundleSize_t;
-typedef enum {
-  dy_1_n4       = 1,
-  dy_1_wideband = 2,
-  dy_1_n2_wideband = 3,
-  dy_1_n4_wideband = 4
-} bundleSizeSet1_t;
-typedef enum {
-  dy_2_n4       = 1,
-  dy_2_wideband = 2,
-} bundleSizeSet2_t;
-typedef struct{
-  bundleSizeSet1_t bundleSizeSet1;
-  bundleSizeSet2_t bundleSizeSet2;
-} dynamic_bundleSize_t;
-typedef struct {
-  static_bundleSize_t staticBundling;
-  dynamic_bundleSize_t dynamicBundlig;
-} prb_bundleType_t;
 typedef enum {
-  nb_code_n1 = 1,
-  nb_code_n2 = 2
-} maxNrofCodeWordsScheduledByDCI_t;
-typedef struct{
-// to be defined FIXME!!!
-}rateMatchPattern_t;
-typedef struct{
-// to be defined FIXME!!!
-}zp_CSI_RS_Resource_t;
-
-typedef struct{
-        int   k0;    
-        int     mappingType;
-        int     startSymbolAndLength;
-
-}PDSCH_TimeDomainResourceAllocation_t;
-typedef struct {
-/*
- * resourceAllocation
- */
-  dl_resourceAllocation_t dl_resourceAllocation;
-/*
- * corresponds to I, where I the number of entries in the higher layer parameter pdsch-AllocationList
- */
-  uint8_t n_pdsh_alloc_list;
-/*
- * rateMatchPatternToAddModList
- */
-  rateMatchPattern_t rateMatchPatternToAddModList[MAX_NR_RATE_MATCH_PATTERNS];
-/*
- * rateMatchPatternToReleaseList
- */
-  uint8_t rateMatchPatternToReleaseList[MAX_NR_RATE_MATCH_PATTERNS];
-  /*
-   * n_rateMatchPatterns indicates the number of rateMatchPatterns defined currently
-   */
-  uint8_t n_rateMatchPatterns;
-  /*
-   * zp-CSI-RS-ResourceToAddModList
-   */
-  zp_CSI_RS_Resource_t zp_CSI_RS_Resource[MAX_NR_ZP_CSI_RS_RESOURCES];
-  /*
-   * zp-CSI-RS-ResourceToReleaseList
-   */
-  uint8_t zp_CSI_RS_ResourceId[MAX_NR_ZP_CSI_RS_RESOURCES];
-  /*
-   * n_zp-CSI-RS-Resource
-   */
-  uint8_t n_zp_CSI_RS_ResourceId;
-/*
- * rgb_Size
- */
-  dl_rgb_Size_t dl_rgbSize;
-/*
- * prb-BundlingType
- */
-  prb_bundleType_t prbBundleType;
-/*
- * pdsch-HARQ-ACK-Codebook: this is part of the IE PhysicalCellGroupConfig which is used to configure cell-group specific L1 parameters (TS 38.331)
- */
-  pdsch_HARQ_ACK_Codebook_t pdsch_HARQ_ACK_Codebook;
-  ////////////////////////////////////////////////////////////////////////////////################################
-
-/*
-  Maximum number of code words that a single DCI may schedule. This changes the number of MCS/RV/NDI bits in the DCI message from 1 to 2.
-*/
-  maxNrofCodeWordsScheduledByDCI_t maxNrofCodeWordsScheduledByDCI;
-
-
-  PDSCH_TimeDomainResourceAllocation_t *pdsch_TimeDomainResourceAllocation[MAX_NR_OF_DL_ALLOCATIONS];
+  typeA = 0,
+  typeB = 1
+} mappingType_t;
 
-} PDSCH_Config_t;
+typedef enum {
+  pdsch_dmrs_pos0 = 0,
+  pdsch_dmrs_pos1 = 1,
+  pdsch_dmrs_pos2 = 2,
+  pdsch_dmrs_pos3 = 3,
+} pdsch_dmrs_AdditionalPosition_t;
 
 /***********************************************************************
 *
@@ -466,128 +364,20 @@ typedef struct {
 *
 ************************************************************************/
 
-
-typedef enum {
-  enable_tpc_accumulation = 0,  /* by default it is enable */
-  disable_tpc_accumulation = 1
-} tpc_Accumulation_t;
-
-typedef enum {
-  typeA = 0,
-  typeB = 1
-} mappingType_t;
-
-typedef struct {
-  tpc_Accumulation_t tpc_Accumulation;
-} PUSCH_PowerControl_t;
-
-typedef struct {
-
-  uint8_t         k2;
-  mappingType_t   mappingType;
-  uint8_t         startSymbolAndLength;
-} PUSCH_TimeDomainResourceAllocation_t;
-////////////////////////////////////////////////////////////////////////////////################################
-typedef enum{
-  maxCodeBlockGroupsPerTransportBlock_n2 = 2,
-  maxCodeBlockGroupsPerTransportBlock_n4 = 4,
-  maxCodeBlockGroupsPerTransportBlock_n6 = 6,
-  maxCodeBlockGroupsPerTransportBlock_n8 = 8
-} maxCodeBlockGroupsPerTransportBlock_t;
-typedef struct{ // The IE PUSCH-ServingCellConfig is used to configure UE specific PUSCH parameters that are common across the UE's BWPs of one serving cell
-	  maxCodeBlockGroupsPerTransportBlock_t maxCodeBlockGroupsPerTransportBlock;
-} PUSCH_ServingCellConfig_t;
-typedef struct{ // CSI-MeasConfig IE is used to configure CSI-RS (reference signals)
-  uint8_t reportTriggerSize;
-} csi_MeasConfig_t;
-typedef enum {
-  pdsch_dmrs_type1 = 0,
-  pdsch_dmrs_type2 = 1
-} pdsch_dmrs_type_t;
 typedef enum {
   pusch_dmrs_type1 = 0,
   pusch_dmrs_type2 = 1
 } pusch_dmrs_type_t;
-typedef enum {
-  pdsch_dmrs_pos0 = 0,
-  pdsch_dmrs_pos1 = 1,
-  pdsch_dmrs_pos3 = 3,
-} pdsch_dmrs_AdditionalPosition_t;
 typedef enum {
   pusch_dmrs_pos0 = 0,
   pusch_dmrs_pos1 = 1,
   pusch_dmrs_pos2 = 2,
   pusch_dmrs_pos3 = 3,
 } pusch_dmrs_AdditionalPosition_t;
-typedef enum {
-  offset00 = 0,
-  offset01 = 1,
-  offset10 = 2,
-  offset11 = 3,
-} ptrs_resource_elementoffset_t;
-typedef enum {
-  pdsch_len1 = 1,
-  pdsch_len2 = 2
-} pdsch_maxLength_t;
 typedef enum {
   pusch_len1 = 1,
   pusch_len2 = 2
 } pusch_maxLength_t;
-typedef struct {
-  uint8_t ptrs_mcs1;
-  uint8_t ptrs_mcs2;
-  uint8_t ptrs_mcs3;
-} ptrs_time_density_t;
-typedef struct {
-  uint16_t n_rb0;
-  uint16_t n_rb1;
-} ptrs_frequency_density_t;
-typedef struct { // The IE PTRS-UplinkConfig is used to configure uplink Phase-Tracking-Reference-Signals (PTRS)
-  uint8_t  num_ptrs_ports;
-  ptrs_resource_elementoffset_t resourceElementOffset;
-  ptrs_time_density_t  timeDensity;
-  ptrs_frequency_density_t  frequencyDensity;
-  uint32_t  ul_ptrs_power;
-} ptrs_UplinkConfig_t;
-typedef struct { // The IE DMRS-DownlinkConfig is used to configure downlink demodulation reference signals for PDSCH
-  pdsch_dmrs_type_t pdsch_dmrs_type;
-  pdsch_dmrs_AdditionalPosition_t pdsch_dmrs_AdditionalPosition;
-  pdsch_maxLength_t pdsch_maxLength;
-  uint16_t scramblingID0;
-  uint16_t scramblingID1;
-} dmrs_DownlinkConfig_t;
-typedef struct { // The IE DMRS-UplinkConfig is used to configure uplink demodulation reference signals for PUSCH
-  pusch_dmrs_type_t pusch_dmrs_type;
-  pusch_dmrs_AdditionalPosition_t pusch_dmrs_AdditionalPosition;
-  pusch_maxLength_t pusch_maxLength;
-  ptrs_UplinkConfig_t ptrs_UplinkConfig;
-  uint16_t scramblingID0;
-  uint16_t scramblingID1;
-} dmrs_UplinkConfig_t;
-typedef struct {
-/*
- * Serving cell ID of a PSCell. The PCell of the Master Cell Group uses ID = 0
- */
-  uint8_t servCellIndex;
-}servCellIndex_t;
-typedef struct{
-  uint8_t cif_presence;
-}own_t;
-typedef struct{
-  servCellIndex_t scheduling_cell_id;
-  uint8_t cif_InSchedulingCell;
-}other_t;
-typedef struct{
- own_t own;
- other_t other;
-}schedulingCellInfo_t;
-typedef struct{
- schedulingCellInfo_t schedulingCellInfo;
-} crossCarrierSchedulingConfig_t;
-typedef struct{
-  // this variable will be filled with '1' if SUL is supported and '0' if SUL is not supported
-  uint8_t supplementaryUplink;
-}supplementaryUplink_t;
 
 typedef enum {
   txConfig_codebook = 1,
@@ -628,57 +418,6 @@ typedef struct {
   betaOffset_type_t betaOffset_type;
   betaOffset_t betaOffset;
 } uci_onPusch_t;
-typedef struct {
-/*
- * txConfig
- */
-  txConfig_t txConfig;
-/*
- * frequencyHopping
- */
-	frequencyHopping_t frequencyHopping;
-/*
- * frequencyHoppingOffsetLists
- */
-  uint16_t frequencyHoppingOffsetLists[4];
-  // n_frequencyHoppingOffsetLists contains the number of offsets listed. We can list up to 4 offsets
-  uint8_t n_frequencyHoppingOffsetLists;
-/*
- * resourceAllocation
- */
-  ul_resourceAllocation_t ul_resourceAllocation;
-/*
- * DMRS-Uplinkconfig
- */
-  dmrs_UplinkConfig_t dmrs_UplinkConfig;
-/*
- * rgb_Size
- */
-  ul_rgb_Size_t ul_rgbSize;
-/*
- * corresponds to I, where I the number of entries in the higher layer parameter pusch-AllocationList
- */
-  uint8_t n_push_alloc_list;
-/*
- * transformPrecoder
- */
-transformPrecoder_t transformPrecoder;
-/*
- * codebookSubset
- */
-codebookSubset_t codebookSubset;
-/*
- * maxRank
- */
-uint8_t maxRank;
-/*
- * uci_onPusch
- */
-uci_onPusch_t uci_onPusch;
-////////////////////////////////////////////////////////////////////////////////################################
-  PUSCH_PowerControl_t                    pusch_PowerControl;
-  PUSCH_TimeDomainResourceAllocation_t    *pusch_TimeDomainResourceAllocation[MAX_NR_OF_UL_ALLOCATIONS];
-} PUSCH_Config_t;
 
 /***********************************************************************
 *
@@ -897,150 +636,6 @@ typedef struct {
   PUCCH_PowerControl_t   pucch_PowerControl;
 } PUCCH_Config_t;
 
-/***********************************************************************
-*
-* FUNCTIONALITY    :  PhysicalCellGroupConfig
-*
-* DESCRIPTION      :  Physical cell group configuration
-*
-************************************************************************/
-
-typedef uint16_t RNTI_value_t;
-
-typedef struct {
-/*
-  -- Enables spatial bundling of HARQ ACKs. It is configured per cell group (i.e. for all the cells within the cell group) for PUCCH
-  -- reporting of HARQ-ACK. It is only applicable when more than 4 layers are possible to schedule.
-  -- Corresponds to L1 parameter 'HARQ-ACK-spatial-bundling' (see 38.213, section FFS_Section)
-  -- Absence indicates that spatial bundling is disabled.
-*/
-  bool                          harq_ACK_SpatialBundlingPUCCH;
-/*
-  -- Enables spatial bundling of HARQ ACKs. It is configured per cell group (i.e. for all the cells within the cell group) for PUSCH
-  -- reporting of HARQ-ACK. It is only applicable when more than 4 layers are possible to schedule.
-  -- Corresponds to L1 parameter 'HARQ-ACK-spatial-bundling' (see 38.213, section FFS_Section)
-  -- Absence indicates that spatial bundling is disabled.
-*/
-  bool                          harq_ACK_SpatialBundlingPUSCH;
-/*
-  -- The maximum transmit power to be used by the UE in this NR cell group.
-*/
-  uint8_t                       p_NR;
-/*
-  -- The PDSCH HARQ-ACK codebook is either semi-static of dynamic. This is applicable to both CA and none CA operation.
-  -- Corresponds to L1 parameter 'HARQ-ACK-codebook' (see 38.213, section FFS_Section)
-*/
-  pdsch_HARQ_ACK_Codebook_t     pdsch_HARQ_ACK_Codebook;
-/*
-  -- RNTI used for SRS TPC commands on DCI. Corresponds to L1 parameter 'TPC-SRS-RNTI' (see 38.213, section 10)
-*/
-  RNTI_value_t                  tpc_SRS_RNTI;
-/*
-  -- RNTI used for PUCCH TPC commands on DCI. Corresponds to L1 parameter 'TPC-PUCCH-RNTI' (see 38.213, section 10).
-*/
-  RNTI_value_t                  tpc_PUCCH_RNTI;
-/*
-  -- RNTI used for PUSCH TPC commands on DCI. Corresponds to L1 parameter 'TPC-PUSCH-RNTI' (see 38.213, section 10)
-*/
-  RNTI_value_t                  tpc_PUSCH_RNTI;
-} PhysicalCellGroupConfig_t;
-
-/***********************************************************************
-*
-* FUNCTIONALITY    :  CellGroupConfig
-*
-* DESCRIPTION      :  Cell Group configuration
-*
-************************************************************************/
-
-/* FFS TODO_NR partial structure that should be complete */
-
-typedef struct {
-/*
-  cellGroupId                 CellGroupId,
-
-  -- Logical Channel configuration and association with radio bearers:
-  rlc-BearerToAddModList            SEQUENCE (SIZE(1..maxLC-ID)) OF RLC-Bearer-Config       OPTIONAL,   -- Need N
-  rlc-BearerToReleaseList           SEQUENCE (SIZE(1..maxLC-ID)) OF LogicalChannelIdentity      OPTIONAL,   -- Need N
-
-  -- Parameters applicable for the entire cell group:
-  mac-CellGroupConfig             MAC-CellGroupConfig                       OPTIONAL, -- Need M
-*/
-  PhysicalCellGroupConfig_t  physicalCellGroupConfig;
-/*
-  -- Serving Cell specific parameters (SpCell and SCells)
-  spCellConfig                SpCellConfig                          OPTIONAL,   -- Need M
-  sCellToAddModList             SEQUENCE (SIZE (1..maxNrofSCells)) OF SCellConfig       OPTIONAL, -- Need N
-  -- List of seconary serving cells to be released (not applicable for SpCells)
-  sCellToReleaseList              SEQUENCE (SIZE (1..maxNrofSCells)) OF SCellIndex        OPTIONAL, -- Need N
-  ...
-  */
-} CellGroupConfig_t;
-
-/***********************************************************************
-*
-* FUNCTIONALITY    :  PDSCH_ServingCellConfig
-*
-* DESCRIPTION      :  pdsch serving cell configuration
-*
-************************************************************************/
-
-/* FFS TODO_NR partial structure that should be complete */
-
-typedef int PDSCH_CodeBlockGroupTransmission_t;  /* dummy struct which should be change by correct structure */
-
-typedef enum {
-  xOh6  = 0,
-  xOh12 = 1,
-  xOh18 = 2
-} xOverhead_t;
-
-typedef enum {
-  n2_dl_harq  = 2,
-  n4_dl_harq  = 4,
-  n6_dl_harq  = 6,
-  n10_dl_harq = 10,
-  n12_dl_harq = 12,
-  n16_dl_harq = 16
-} nrofHARQ_ProcessesForPDSCH_t;
-typedef enum{
-  maxCodeBlockGroupsPerTransportBlock_dl_n2 = 2,
-  maxCodeBlockGroupsPerTransportBlock_dl_n4 = 4,
-  maxCodeBlockGroupsPerTransportBlock_dl_n6 = 6,
-  maxCodeBlockGroupsPerTransportBlock_dl_n8 = 8
-} maxCodeBlockGroupsPerTransportBlock_dl_t;
-
-typedef struct {
-/*
-  -- Enables and configures code-block-group (CBG) based transmission (see 38.213, section 9.1.1)
-*/
-  PDSCH_CodeBlockGroupTransmission_t  *codeBlockGroupTransmission;
-/*
-  -- Accounts for overhead from CSI-RS, CORESET, etc. If the field is absent, the UE applies value xOh0.
-  -- Corresponds to L1 parameter 'Xoh-PDSCH' (see 38.214, section 5.1.3.2)
-*/
-  xOverhead_t                         xOverhead;
-/*
-  -- The number of HARQ processes to be used on the PDSCH of a serving cell. n2 corresponds to 2 HARQ processes, n4 to 4 HARQ processes
-  -- and so on. If the field is absent, the UE uses 8 HARQ processes.
-  -- Corresponds to L1 parameter 'number-HARQ-process-PDSCH' (see 38.214, section REF)
-*/
-  nrofHARQ_ProcessesForPDSCH_t        nrofHARQ_ProcessesForPDSCH;
-/*
-  -- The ID of the serving cell (of the same cell group) to use for PUCCH.
-  -- If the field is absent, the UE sends the HARQ feedback on the PUCCH of the SpCell of this cell group.
-*/
-  uint8_t                            pucch_Cell;
-/*
- * maxCodeBlockGroupsPerTransportBlock_dl_t
- */
-  maxCodeBlockGroupsPerTransportBlock_dl_t maxCodeBlockGroupsPerTransportBlock_dl;
-/*
- * codeBlockGroupFlushIndicator (boolean)
- */
-  uint8_t codeBlockGroupFlushIndicator;
-} PDSCH_ServingCellConfig_t;
-
 /***********************************************************************
 *
 * FUNCTIONALITY    :  Scheduling Request Configuration (SR)
diff --git a/openair1/SCHED_NR/nr_prach_procedures.c b/openair1/SCHED_NR/nr_prach_procedures.c
index c95d3dc937b4b02647563f1d994514adc90ffa88..dfc5376ee7813d2aa6136ecc3bc25e0fd64bea41 100644
--- a/openair1/SCHED_NR/nr_prach_procedures.c
+++ b/openair1/SCHED_NR/nr_prach_procedures.c
@@ -114,22 +114,24 @@ void L1_nr_prach_procedures(PHY_VARS_gNB *gNB,int frame,int slot) {
 		  &max_preamble_delay[0]
 		  );
       free_nr_prach_entry(gNB,prach_id);
-      LOG_D(PHY,"[RAPROC] Frame %d, slot %d, occasion %d (prachStartSymbol %d) : Most likely preamble %d, energy %d dB delay %d (prach_energy counter %d)\n",
+      LOG_D(PHY,"[RAPROC] Frame %d, slot %d, occasion %d (prachStartSymbol %d) : Most likely preamble %d, energy %d.%d dB delay %d (prach_energy counter %d)\n",
 	    frame,slot,prach_oc,prachStartSymbol,
 	    max_preamble[0],
 	    max_preamble_energy[0]/10,
+            max_preamble_energy[0]%10,
 	    max_preamble_delay[0],
 	    gNB->prach_energy_counter);
 
       if ((gNB->prach_energy_counter == 100) && (max_preamble_energy[0] > gNB->measurements.prach_I0+gNB->prach_thres)) {
 	
-	LOG_I(PHY,"[gNB %d][RAPROC] Frame %d, slot %d Initiating RA procedure with preamble %d, energy %d.%d dB, delay %d start symbol %u freq index %u\n",
+	LOG_I(PHY,"[gNB %d][RAPROC] Frame %d, slot %d Initiating RA procedure with preamble %d, energy %d.%d dB (I0 %d, thres %d), delay %d start symbol %u freq index %u\n",
 	      gNB->Mod_id,
 	      frame,
 	      slot,
 	      max_preamble[0],
 	      max_preamble_energy[0]/10,
 	      max_preamble_energy[0]%10,
+              gNB->measurements.prach_I0,gNB->prach_thres,
 	      max_preamble_delay[0],
 	      prachStartSymbol,
 	      prach_pdu->num_ra);
diff --git a/openair1/SCHED_NR/nr_ru_procedures.c b/openair1/SCHED_NR/nr_ru_procedures.c
index c8042ecec35682290a85b2577a45eb4c0a35b2ef..827e986f1b20c9e3bded717c95dc4811811ff523 100644
--- a/openair1/SCHED_NR/nr_ru_procedures.c
+++ b/openair1/SCHED_NR/nr_ru_procedures.c
@@ -197,18 +197,17 @@ void nr_feptx_ofdm_2thread(RU_t *ru,int frame_tx,int tti_tx) {
 
         VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_PREC+j , 1);
         start_meas(&ru->txdataF_copy_stats);
-        if (ru->num_gNB == 1){
-          gNB = ru->gNB_list[0];
-          cfg = &gNB->gNB_config;
+        AssertFatal(ru->num_gNB==1,"num_gNB>1, help\n");
+        gNB = ru->gNB_list[0];
+        cfg = &gNB->gNB_config;
 
-          for(i=0; i<ru->nb_tx; ++i){
-            memcpy((void*)&ru->common.txdataF[i][j*fp->ofdm_symbol_size],
-                   (void*)&gNB->common_vars.txdataF[i][j*fp->ofdm_symbol_size + txdataF_offset],
-                   fp->ofdm_symbol_size*sizeof(int32_t));
+        for(i=0; i<ru->nb_tx; ++i){
+          memcpy((void*)&ru->common.txdataF[i][j*fp->ofdm_symbol_size],
+                 (void*)&gNB->common_vars.txdataF[i][j*fp->ofdm_symbol_size + txdataF_offset],
+                 fp->ofdm_symbol_size*sizeof(int32_t));
 	    
-          }
+        }
 
-        }//num_gNB == 1
         stop_meas(&ru->txdataF_copy_stats);
         VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_PREC+j , 0);
 
@@ -303,19 +302,26 @@ static void *nr_feptx_thread(void *param) {
       ////////////precoding////////////
       VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_PREC+feptx->index+1 , 1);
       
-      start_meas(&ru->precoding_stats);
-
-      for(i=0; i<ru->nb_log_antennas; ++i) {
-	memcpy((void*) &ru->common.beam_id[i][slot*fp->symbols_per_slot+l],
-	       (void*) &ru->gNB_list[0]->common_vars.beam_id[i][slot*fp->symbols_per_slot+l],
-	       (fp->symbols_per_slot>>1)*sizeof(uint8_t));
+      if (aa==0 && l==0) start_meas(&ru->precoding_stats);
+
+      if (ru->do_precoding == 1) {
+        for(i=0; i<ru->nb_log_antennas; ++i) {
+          memcpy((void*) &ru->common.beam_id[i][slot*fp->symbols_per_slot+l],
+                 (void*) &ru->gNB_list[0]->common_vars.beam_id[i][slot*fp->symbols_per_slot+l],
+                 (fp->symbols_per_slot>>1)*sizeof(uint8_t));
+         }
       }
 
-
       if (ru->nb_tx == 1 && ru->nb_log_antennas == 1) {
-	memcpy((void*)&ru->common.txdataF_BF[0][l*fp->ofdm_symbol_size],
-	       (void*)&ru->gNB_list[0]->common_vars.txdataF[0][txdataF_offset + l*fp->ofdm_symbol_size],
-	       (fp->samples_per_slot_wCP>>1)*sizeof(int32_t));
+        memcpy((void*)&ru->common.txdataF_BF[0][l*fp->ofdm_symbol_size],
+               (void*)&ru->gNB_list[0]->common_vars.txdataF[0][txdataF_offset + l*fp->ofdm_symbol_size],
+               (fp->samples_per_slot_wCP>>1)*sizeof(int32_t));
+      }
+      else if (ru->do_precoding == 0) {
+        int gNB_tx = ru->gNB_list[0]->frame_parms.nb_antennas_tx;
+        memcpy((void*)&ru->common.txdataF_BF[aa][l*fp->ofdm_symbol_size],
+               (void*)&ru->gNB_list[0]->common_vars.txdataF[aa%gNB_tx][txdataF_offset + l*fp->ofdm_symbol_size],
+               (fp->samples_per_slot_wCP>>1)*sizeof(int32_t));
       }
       else {
         bw  = ru->beam_weights[0];
@@ -331,13 +337,13 @@ static void *nr_feptx_thread(void *param) {
                         txdataF_offset);//here
         }
       }
-      stop_meas(&ru->precoding_stats);
+      if (aa==0 && l==0) stop_meas(&ru->precoding_stats);
       VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_PREC+feptx->index+1 , 0);
 
       ////////////FEPTX////////////
-      start_meas(&ru->ofdm_mod_stats);
+      if (aa==0 && l==0) start_meas(&ru->ofdm_mod_stats);
       nr_feptx0(ru,slot,start,fp->symbols_per_slot>>1,aa);
-      stop_meas(&ru->ofdm_mod_stats);
+      if (aa==0 && l==0) stop_meas(&ru->ofdm_mod_stats);
 
       if (release_thread(&feptx->mutex_feptx,&feptx->instance_cnt_feptx,"NR feptx thread")<0) break;
 
diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c
index 717487c101539e9ef70814fe053e51060c4aa5c4..550d4c8e31d18bc14d8fcac687f4421097d96c65 100644
--- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c
+++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c
@@ -176,7 +176,7 @@ void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB,
 			ul_pdcch_pdu_id>=0 ? &gNB->ul_pdcch_pdu[ul_pdcch_pdu_id].pdcch_pdu.pdcch_pdu : NULL,
 			gNB->nr_gold_pdcch_dmrs[slot],
 			&gNB->common_vars.txdataF[0][txdataF_offset],
-			AMP, *fp);
+			AMP, fp);
 
     // free up entry in pdcch tables
     if (pdcch_pdu_id>=0) gNB->pdcch_pdu[pdcch_pdu_id].frame = -1;
@@ -686,7 +686,7 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) {
              gNB->pusch_vars[ULSCH_id]->ulsch_power_tot = gNB->pusch_vars[ULSCH_id]->ulsch_noise_power_tot;
              nr_fill_indication(gNB,frame_rx, slot_rx, ULSCH_id, harq_pid, 1);
              gNB->pusch_vars[ULSCH_id]->DTX=1;
-             stats->DTX++;
+             if (stats) stats->DTX++;
              return 1;
           } else gNB->pusch_vars[ULSCH_id]->DTX=0;
 
diff --git a/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c b/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c
index c276de847d1c1e677c56f64f863b3233e0935608..99edbf9a40d0f7907cd531e886734b08284d313c 100644
--- a/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c
+++ b/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c
@@ -80,31 +80,30 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response){
 
         } else {
 
+          fapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_config_pdu = &dl_config->dl_config_list[i].dlsch_config_pdu.dlsch_config_rel15;
+          uint8_t current_harq_pid = dlsch_config_pdu->harq_process_nbr;
+
           if (dl_config->dl_config_list[i].pdu_type == FAPI_NR_DL_CONFIG_TYPE_DLSCH){
             dlsch0 = PHY_vars_UE_g[module_id][cc_id]->dlsch[thread_id][0][0];
           }
           else if (dl_config->dl_config_list[i].pdu_type == FAPI_NR_DL_CONFIG_TYPE_RA_DLSCH){
             dlsch0 = PHY_vars_UE_g[module_id][cc_id]->dlsch_ra[0];
             dlsch0->rnti_type = _RA_RNTI_;
-            dlsch0->harq_processes[dlsch0->current_harq_pid]->status = ACTIVE;
+            dlsch0->harq_processes[current_harq_pid]->status = ACTIVE;
           }
           else if (dl_config->dl_config_list[i].pdu_type == FAPI_NR_DL_CONFIG_TYPE_SI_DLSCH){
             dlsch0 = PHY_vars_UE_g[module_id][cc_id]->dlsch_SI[0];
             dlsch0->rnti_type = _SI_RNTI_;
-            dlsch0->harq_processes[dlsch0->current_harq_pid]->status = ACTIVE;
+            dlsch0->harq_processes[current_harq_pid]->status = ACTIVE;
           }
 
-          fapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_config_pdu = &dl_config->dl_config_list[i].dlsch_config_pdu.dlsch_config_rel15;
-          uint8_t current_harq_pid = dlsch_config_pdu->harq_process_nbr;
-          NR_DL_UE_HARQ_t *dlsch0_harq;
-
           dlsch0->current_harq_pid = current_harq_pid;
           dlsch0->active = 1;
           dlsch0->rnti = dl_config->dl_config_list[i].dlsch_config_pdu.rnti;
-          dlsch0_harq = dlsch0->harq_processes[current_harq_pid];
 
           LOG_D(PHY,"current_harq_pid = %d\n", current_harq_pid);
 
+          NR_DL_UE_HARQ_t *dlsch0_harq = dlsch0->harq_processes[current_harq_pid];
           if (dlsch0_harq){
 
             dlsch0_harq->BWPStart = dlsch_config_pdu->BWPStart;
@@ -121,7 +120,14 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response){
             dlsch0->g_pucch = dlsch_config_pdu->accumulated_delta_PUCCH;
             dlsch0_harq->harq_ack.pucch_resource_indicator = dlsch_config_pdu->pucch_resource_id;
             dlsch0_harq->harq_ack.slot_for_feedback_ack = (slot+dlsch_config_pdu->pdsch_to_harq_feedback_time_ind)%frame_parms.slots_per_frame;
-            dlsch0_harq->Nl=1;
+
+            //get nrOfLayers from DCI info
+            uint8_t Nl = 0;
+            for (i = 0; i < 4; i++) {
+              if (dlsch_config_pdu->dmrs_ports[i] >= i) Nl += 1;
+            }
+            dlsch0_harq->Nl = Nl;
+
             dlsch0_harq->mcs_table=dlsch_config_pdu->mcs_table;
             dlsch0_harq->harq_ack.rx_status = downlink_harq_process(dlsch0_harq, dlsch0->current_harq_pid, dlsch_config_pdu->ndi, dlsch0->rnti_type);
             if (dlsch0_harq->status != ACTIVE) {
diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c
index e3d4c54f5aaa809c8de5985bf87131c8b3e38ba8..18ef2f66f46f5e261a9601cf00d691df77f9896e 100644
--- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c
+++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c
@@ -288,7 +288,7 @@ void phy_procedures_nrUE_TX(PHY_VARS_NR_UE *ue,
 void nr_ue_measurement_procedures(uint16_t l,
                                   PHY_VARS_NR_UE *ue,
                                   UE_nr_rxtx_proc_t *proc,
-                                  uint8_t eNB_id,
+                                  uint8_t gNB_id,
                                   uint16_t slot){
 
   NR_DL_FRAME_PARMS *frame_parms=&ue->frame_parms;
@@ -308,7 +308,7 @@ void nr_ue_measurement_procedures(uint16_t l,
 
 #if T_TRACER
     if(slot == 0)
-      T(T_UE_PHY_MEAS, T_INT(eNB_id),  T_INT(ue->Mod_id), T_INT(frame_rx%1024), T_INT(nr_slot_rx),
+      T(T_UE_PHY_MEAS, T_INT(gNB_id),  T_INT(ue->Mod_id), T_INT(frame_rx%1024), T_INT(nr_slot_rx),
 	T_INT((int)(10*log10(ue->measurements.rsrp[0])-ue->rx_total_gain_dB)),
 	T_INT((int)ue->measurements.rx_rssi_dBm[0]),
 	T_INT((int)(ue->measurements.rx_power_avg_dB[0] - ue->measurements.n0_power_avg_dB)),
@@ -327,8 +327,8 @@ void nr_ue_measurement_procedures(uint16_t l,
     VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_GAIN_CONTROL, VCD_FUNCTION_IN);
 
 
-    //printf("start adjust gain power avg db %d\n", ue->measurements.rx_power_avg_dB[eNB_id]);
-    phy_adjust_gain_nr (ue,ue->measurements.rx_power_avg_dB[eNB_id],eNB_id);
+    //printf("start adjust gain power avg db %d\n", ue->measurements.rx_power_avg_dB[gNB_id]);
+    phy_adjust_gain_nr (ue,ue->measurements.rx_power_avg_dB[gNB_id],gNB_id);
     
     VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_GAIN_CONTROL, VCD_FUNCTION_OUT);
 
@@ -738,12 +738,12 @@ int nr_ue_pdcch_procedures(uint8_t gNB_id,
 }
 #endif // NR_PDCCH_SCHED
 
-int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int eNB_id, PDSCH_t pdsch, NR_UE_DLSCH_t *dlsch0, NR_UE_DLSCH_t *dlsch1) {
+int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int gNB_id, PDSCH_t pdsch, NR_UE_DLSCH_t *dlsch0, NR_UE_DLSCH_t *dlsch1) {
 
   int frame_rx = proc->frame_rx;
   int nr_slot_rx = proc->nr_slot_rx;
   int m;
-  int i_mod,eNB_id_i,dual_stream_UE;
+  int i_mod,gNB_id_i,dual_stream_UE;
   int first_symbol_flag=0;
 
   if (!dlsch0)
@@ -761,14 +761,14 @@ int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int eNB_
     uint16_t s1             = dlsch0_harq->nb_symbols;
     bool is_SI              = dlsch0->rnti_type == _SI_RNTI_;
 
-    LOG_D(PHY,"[UE %d] PDSCH type %d active in nr_slot_rx %d, harq_pid %d (%d), rb_start %d, nb_rb %d, symbol_start %d, nb_symbols %d, DMRS mask %x\n",ue->Mod_id,pdsch,nr_slot_rx,harq_pid,dlsch0->harq_processes[harq_pid]->status,pdsch_start_rb,pdsch_nb_rb,s0,s1,dlsch0->harq_processes[harq_pid]->dlDmrsSymbPos);
+    LOG_D(PHY,"[UE %d] PDSCH type %d active in nr_slot_rx %d, harq_pid %d (%d), rb_start %d, nb_rb %d, symbol_start %d, nb_symbols %d, DMRS mask %x\n",ue->Mod_id,pdsch,nr_slot_rx,harq_pid,dlsch0_harq->status,pdsch_start_rb,pdsch_nb_rb,s0,s1,dlsch0_harq->dlDmrsSymbPos);
 
     for (m = s0; m < (s0 +s1); m++) {
-      if (((1<<m)&dlsch0->harq_processes[harq_pid]->dlDmrsSymbPos) > 0) {
-        for (uint8_t aatx=0; aatx<dlsch0->harq_processes[harq_pid]->Nl; aatx++) {//for MIMO Config: it shall loop over no_layers
+      if (dlsch0_harq->dlDmrsSymbPos & (1 << m)) {
+        for (uint8_t aatx=0; aatx<dlsch0_harq->Nl; aatx++) {//for MIMO Config: it shall loop over no_layers
           nr_pdsch_channel_estimation(ue,
                                       proc,
-                                      0 /*eNB_id*/,
+                                      gNB_id,
                                       is_SI,
                                       nr_slot_rx,
                                       aatx /*p*/,
@@ -783,7 +783,7 @@ int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int eNB_
           char filename[100];
           for (uint8_t aarx=0; aarx<ue->frame_parms.nb_antennas_rx; aarx++) {
             sprintf(filename,"PDSCH_CHANNEL_frame%d_slot%d_sym%d_port%d_rx%d.m", nr_frame_rx, nr_slot_rx, m, aatx,aarx);
-            int **dl_ch_estimates = ue->pdsch_vars[proc->thread_id][eNB_id]->dl_ch_estimates;
+            int **dl_ch_estimates = ue->pdsch_vars[proc->thread_id][gNB_id]->dl_ch_estimates;
             LOG_M(filename,"channel_F",&dl_ch_estimates[aatx*ue->frame_parms.nb_antennas_rx+aarx][ue->frame_parms.ofdm_symbol_size*m],ue->frame_parms.ofdm_symbol_size, 1, 1);
           }
 #endif
@@ -796,7 +796,7 @@ int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int eNB_
     uint16_t first_symbol_with_data = s0;
     uint32_t dmrs_data_re;
 
-    if (ue->dmrs_DownlinkConfig.pdsch_dmrs_type == pdsch_dmrs_type1)
+    if (dlsch0_harq->dmrsConfigType == NFAPI_NR_DMRS_TYPE1)
       dmrs_data_re = 12 - 6 * dlsch0_harq->n_dmrs_cdm_groups;
     else
       dmrs_data_re = 12 - 4 * dlsch0_harq->n_dmrs_cdm_groups;
@@ -808,7 +808,7 @@ int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int eNB_
     for (m = s0; m < (s1 + s0); m++) {
  
       dual_stream_UE = 0;
-      eNB_id_i = eNB_id+1;
+      gNB_id_i = gNB_id+1;
       i_mod = 0;
       if (( m==first_symbol_with_data ) && (m<4))
         first_symbol_flag = 1;
@@ -827,15 +827,15 @@ int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int eNB_
         if (nr_rx_pdsch(ue,
                         proc,
                         pdsch,
-                        eNB_id,
-                        eNB_id_i,
+                        gNB_id,
+                        gNB_id_i,
                         frame_rx,
                         nr_slot_rx,
                         m,
                         first_symbol_flag,
                         dual_stream_UE,
                         i_mod,
-                        dlsch0->current_harq_pid) < 0)
+                        harq_pid) < 0)
           return -1;
       } else AssertFatal(1==0,"Not RA_PDSCH, SI_PDSCH or PDSCH\n");
 
@@ -858,7 +858,7 @@ int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int eNB_
 
 void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue,
        UE_nr_rxtx_proc_t *proc,
-       int eNB_id,
+       int gNB_id,
        PDSCH_t pdsch,
        NR_UE_DLSCH_t *dlsch0,
        NR_UE_DLSCH_t *dlsch1,
@@ -878,7 +878,7 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue,
   fapi_nr_rx_indication_t rx_ind;
   uint16_t number_pdus = 1;
   // params for UL time alignment procedure
-  NR_UL_TIME_ALIGNMENT_t *ul_time_alignment = &ue->ul_time_alignment[eNB_id];
+  NR_UL_TIME_ALIGNMENT_t *ul_time_alignment = &ue->ul_time_alignment[gNB_id];
 
   uint8_t is_cw0_active = dlsch0->harq_processes[harq_pid]->status;
   uint16_t nb_symb_sch = dlsch0->harq_processes[harq_pid]->nb_symbols;
@@ -915,7 +915,7 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue,
     case RA_PDSCH:
     case P_PDSCH:
     case PDSCH:
-      pdsch_vars = ue->pdsch_vars[proc->thread_id][eNB_id];
+      pdsch_vars = ue->pdsch_vars[proc->thread_id][gNB_id];
       break;
     case PMCH:
     case PDSCH1:
@@ -933,8 +933,8 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue,
       *dlsch_errors=0;
 
     if (pdsch == RA_PDSCH) {
-      if (ue->prach_resources[eNB_id]!=NULL)
-	      dlsch0->rnti = ue->prach_resources[eNB_id]->ra_RNTI;
+      if (ue->prach_resources[gNB_id]!=NULL)
+	      dlsch0->rnti = ue->prach_resources[gNB_id]->ra_RNTI;
       else {
 	      LOG_E(PHY,"[UE %d] Frame %d, nr_slot_rx %d: FATAL, prach_resources is NULL\n", ue->Mod_id, frame_rx, nr_slot_rx);
 	      //mac_xface->macphy_exit("prach_resources is NULL");
@@ -975,7 +975,7 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue,
       LOG_I(PHY,"start ldpc decode for CW 0 for AbsSubframe %d.%d / %d  --> Nl %d \n", frame_rx, nr_slot_rx, harq_pid, dlsch0->harq_processes[harq_pid]->Nl);
       LOG_I(PHY,"start ldpc decode for CW 0 for AbsSubframe %d.%d / %d  --> G  %d \n", frame_rx, nr_slot_rx, harq_pid, dlsch0->harq_processes[harq_pid]->G);
       LOG_I(PHY,"start ldpc decode for CW 0 for AbsSubframe %d.%d / %d  --> Kmimo  %d \n", frame_rx, nr_slot_rx, harq_pid, dlsch0->Kmimo);
-      LOG_I(PHY,"start ldpc decode for CW 0 for AbsSubframe %d.%d / %d  --> Pdcch Sym  %d \n", frame_rx, nr_slot_rx, harq_pid, ue->pdcch_vars[proc->thread_id][eNB_id]->num_pdcch_symbols);
+      LOG_I(PHY,"start ldpc decode for CW 0 for AbsSubframe %d.%d / %d  --> Pdcch Sym  %d \n", frame_rx, nr_slot_rx, harq_pid, ue->pdcch_vars[proc->thread_id][gNB_id]->num_pdcch_symbols);
 #endif
 
 #if UE_TIMING_TRACE
@@ -986,7 +986,7 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue,
     {
     ret = nr_dlsch_decoding_mthread(ue,
 			   proc,
-			   eNB_id,
+			   gNB_id,
 			   pdsch_vars->llr[0],
 			   &ue->frame_parms,
 			   dlsch0,
@@ -1003,7 +1003,7 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue,
     {
     ret = nr_dlsch_decoding(ue,
 			   proc,
-			   eNB_id,
+			   gNB_id,
 			   pdsch_vars->llr[0],
 			   &ue->frame_parms,
 			   dlsch0,
@@ -1061,7 +1061,7 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue,
           LOG_I(PHY,"start ldpc decode for CW 1 for AbsSubframe %d.%d / %d  --> Nl %d \n", frame_rx, nr_slot_rx, harq_pid, dlsch1->harq_processes[harq_pid]->Nl);
           LOG_I(PHY,"start ldpc decode for CW 1 for AbsSubframe %d.%d / %d  --> G  %d \n", frame_rx, nr_slot_rx, harq_pid, dlsch1->harq_processes[harq_pid]->G);
           LOG_I(PHY,"start ldpc decode for CW 1 for AbsSubframe %d.%d / %d  --> Kmimo  %d \n", frame_rx, nr_slot_rx, harq_pid, dlsch1->Kmimo);
-          LOG_I(PHY,"start ldpc decode for CW 1 for AbsSubframe %d.%d / %d  --> Pdcch Sym  %d \n", frame_rx, nr_slot_rx, harq_pid, ue->pdcch_vars[proc->thread_id][eNB_id]->num_pdcch_symbols);
+          LOG_I(PHY,"start ldpc decode for CW 1 for AbsSubframe %d.%d / %d  --> Pdcch Sym  %d \n", frame_rx, nr_slot_rx, harq_pid, ue->pdcch_vars[proc->thread_id][gNB_id]->num_pdcch_symbols);
 #endif
 
 #if UE_TIMING_TRACE
@@ -1072,7 +1072,7 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue,
     {
     ret1 = nr_dlsch_decoding_mthread(ue,
                                      proc,
-                                     eNB_id,
+                                     gNB_id,
                                      pdsch_vars->llr[1],
                                      &ue->frame_parms,
                                      dlsch1,
@@ -1089,7 +1089,7 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue,
     {
     ret1 = nr_dlsch_decoding(ue,
 			     proc,
-			     eNB_id,
+			     gNB_id,
                              pdsch_vars->llr[1],
                              &ue->frame_parms,
                              dlsch1,
@@ -1131,18 +1131,18 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue,
 
         switch (pdsch) {
           case RA_PDSCH:
-            nr_fill_dl_indication(&dl_indication, NULL, &rx_ind, proc, ue, eNB_id);
-            nr_fill_rx_indication(&rx_ind, FAPI_NR_RX_PDU_TYPE_RAR, eNB_id, ue, dlsch0, number_pdus);
+            nr_fill_dl_indication(&dl_indication, NULL, &rx_ind, proc, ue, gNB_id);
+            nr_fill_rx_indication(&rx_ind, FAPI_NR_RX_PDU_TYPE_RAR, gNB_id, ue, dlsch0, number_pdus);
 
-            ue->UE_mode[eNB_id] = RA_RESPONSE;
+            ue->UE_mode[gNB_id] = RA_RESPONSE;
             break;
           case PDSCH:
-            nr_fill_dl_indication(&dl_indication, NULL, &rx_ind, proc, ue, eNB_id);
-            nr_fill_rx_indication(&rx_ind, FAPI_NR_RX_PDU_TYPE_DLSCH, eNB_id, ue, dlsch0, number_pdus);
+            nr_fill_dl_indication(&dl_indication, NULL, &rx_ind, proc, ue, gNB_id);
+            nr_fill_rx_indication(&rx_ind, FAPI_NR_RX_PDU_TYPE_DLSCH, gNB_id, ue, dlsch0, number_pdus);
             break;
           case SI_PDSCH:
-            nr_fill_dl_indication(&dl_indication, NULL, &rx_ind, proc, ue, eNB_id);
-            nr_fill_rx_indication(&rx_ind, FAPI_NR_RX_PDU_TYPE_SIB, eNB_id, ue, dlsch0, number_pdus);
+            nr_fill_dl_indication(&dl_indication, NULL, &rx_ind, proc, ue, gNB_id);
+            nr_fill_rx_indication(&rx_ind, FAPI_NR_RX_PDU_TYPE_SIB, gNB_id, ue, dlsch0, number_pdus);
             break;
           default:
             break;
@@ -1156,7 +1156,7 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue,
         }
       }
 
-      if (ue->mac_enabled == 1) {
+      if (ue->mac_enabled == 1) { // TODO: move this from PHY to MAC layer!
 
         /* Time Alignment procedure
         // - UE processing capability 1
@@ -1177,11 +1177,60 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue,
         const int Ta_max = 3846; // Max value of 12 bits TA Command
         const double N_TA_max = Ta_max * bw_scaling * tc_factor;
 
+        NR_UE_MAC_INST_t *mac = get_mac_inst(0);
+
+        NR_PUSCH_TimeDomainResourceAllocationList_t *pusch_TimeDomainAllocationList = NULL;
+        if (mac->ULbwp[0] &&
+            mac->ULbwp[0]->bwp_Dedicated &&
+            mac->ULbwp[0]->bwp_Dedicated->pusch_Config &&
+            mac->ULbwp[0]->bwp_Dedicated->pusch_Config->choice.setup &&
+            mac->ULbwp[0]->bwp_Dedicated->pusch_Config->choice.setup->pusch_TimeDomainAllocationList) {
+          pusch_TimeDomainAllocationList = mac->ULbwp[0]->bwp_Dedicated->pusch_Config->choice.setup->pusch_TimeDomainAllocationList->choice.setup;
+        }
+        else if (mac->ULbwp[0] &&
+                 mac->ULbwp[0]->bwp_Common &&
+                 mac->ULbwp[0]->bwp_Common->pusch_ConfigCommon &&
+                 mac->ULbwp[0]->bwp_Common->pusch_ConfigCommon->choice.setup &&
+                 mac->ULbwp[0]->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList) {
+          pusch_TimeDomainAllocationList = mac->ULbwp[0]->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList;
+        }
+        else if (mac->scc_SIB &&
+                 mac->scc_SIB->uplinkConfigCommon &&
+                 mac->scc_SIB->uplinkConfigCommon->initialUplinkBWP.pusch_ConfigCommon &&
+                 mac->scc_SIB->uplinkConfigCommon->initialUplinkBWP.pusch_ConfigCommon->choice.setup &&
+                 mac->scc_SIB->uplinkConfigCommon->initialUplinkBWP.pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList) {
+          pusch_TimeDomainAllocationList = mac->scc_SIB->uplinkConfigCommon->initialUplinkBWP.pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList;
+        }
+        long mapping_type_ul = pusch_TimeDomainAllocationList ? pusch_TimeDomainAllocationList->list.array[0]->mappingType : NR_PUSCH_TimeDomainResourceAllocation__mappingType_typeA;
+
+        NR_PDSCH_Config_t *pdsch_Config = (mac->DLbwp[0] && mac->DLbwp[0]->bwp_Dedicated->pdsch_Config->choice.setup) ? mac->DLbwp[0]->bwp_Dedicated->pdsch_Config->choice.setup : NULL;
+        NR_PDSCH_TimeDomainResourceAllocationList_t *pdsch_TimeDomainAllocationList = NULL;
+        if (mac->DLbwp[0] && mac->DLbwp[0]->bwp_Dedicated->pdsch_Config->choice.setup->pdsch_TimeDomainAllocationList)
+          pdsch_TimeDomainAllocationList = pdsch_Config->pdsch_TimeDomainAllocationList->choice.setup;
+        else if (mac->DLbwp[0] && mac->DLbwp[0]->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList)
+          pdsch_TimeDomainAllocationList = mac->DLbwp[0]->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList;
+        else if (mac->scc_SIB && mac->scc_SIB->downlinkConfigCommon.initialDownlinkBWP.pdsch_ConfigCommon->choice.setup)
+          pdsch_TimeDomainAllocationList = mac->scc_SIB->downlinkConfigCommon.initialDownlinkBWP.pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList;
+        long mapping_type_dl = pdsch_TimeDomainAllocationList ? pdsch_TimeDomainAllocationList->list.array[0]->mappingType : NR_PDSCH_TimeDomainResourceAllocation__mappingType_typeA;
+
+        NR_DMRS_DownlinkConfig_t *NR_DMRS_dlconfig = NULL;
+        if (pdsch_Config) {
+          if (mapping_type_dl == NR_PDSCH_TimeDomainResourceAllocation__mappingType_typeA)
+            NR_DMRS_dlconfig = (NR_DMRS_DownlinkConfig_t *)pdsch_Config->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup;
+          else
+            NR_DMRS_dlconfig = (NR_DMRS_DownlinkConfig_t *)pdsch_Config->dmrs_DownlinkForPDSCH_MappingTypeB->choice.setup;
+        }
+
+        pdsch_dmrs_AdditionalPosition_t add_pos_dl = pdsch_dmrs_pos2;
+        if (NR_DMRS_dlconfig && NR_DMRS_dlconfig->dmrs_AdditionalPosition)
+          add_pos_dl = *NR_DMRS_dlconfig->dmrs_AdditionalPosition;
+
         /* PDSCH decoding time N_1 for processing capability 1 */
         int N_1;
-        if (ue->dmrs_DownlinkConfig.pdsch_dmrs_AdditionalPosition == pdsch_dmrs_pos0)
+
+        if (add_pos_dl == pdsch_dmrs_pos0)
           N_1 = pdsch_N_1_capability_1[numerology][1];
-        else if (ue->dmrs_DownlinkConfig.pdsch_dmrs_AdditionalPosition == pdsch_dmrs_pos1 || ue->dmrs_DownlinkConfig.pdsch_dmrs_AdditionalPosition == 2) // TODO set to pdsch_dmrs_pos2 when available
+        else if (add_pos_dl == pdsch_dmrs_pos1 || add_pos_dl == pdsch_dmrs_pos2)
           N_1 = pdsch_N_1_capability_1[numerology][2];
         else
           N_1 = pdsch_N_1_capability_1[numerology][3];
@@ -1192,8 +1241,7 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue,
         /* d_1_1 depending on the number of PDSCH symbols allocated */
         const int d = 0; // TODO number of overlapping symbols of the scheduling PDCCH and the scheduled PDSCH
         int d_1_1 = 0;
-        mappingType_t mapping_type_dl = ue->PDSCH_Config.pdsch_TimeDomainResourceAllocation[0]->mappingType;
-        if (mapping_type_dl == typeA)
+        if (mapping_type_dl == NR_PDSCH_TimeDomainResourceAllocation__mappingType_typeA)
          if (nb_symb_sch + start_symbol < 7)
           d_1_1 = 7 - (nb_symb_sch + start_symbol);
          else
@@ -1208,8 +1256,7 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue,
 
         /* d_2_1 */
         int d_2_1;
-        mappingType_t mapping_type_ul = ue->pusch_config.pusch_TimeDomainResourceAllocation[0]->mappingType;
-        if (mapping_type_ul == typeB && start_symbol != 0)
+        if (mapping_type_ul == NR_PUSCH_TimeDomainResourceAllocation__mappingType_typeB && start_symbol != 0)
           d_2_1 = 0;
         else
           d_2_1 = 1;
@@ -1433,9 +1480,9 @@ void *UE_thread_slot1_dl_processing(void *arg) {
 #endif
     // start slave thread for Pdsch Procedure (slot1)
     // do procedures for C-RNTI
-    uint8_t eNB_id = 0;
+    uint8_t gNB_id = 0;
 
-    if (ue->dlsch[proc->thread_id][eNB_id][0]->active == 1) {
+    if (ue->dlsch[proc->thread_id][gNB_id][0]->active == 1) {
       //wait until first ofdm symbol is processed
       //wait = 0;
       //while(proc->first_symbol_available == 0)
@@ -1448,9 +1495,9 @@ void *UE_thread_slot1_dl_processing(void *arg) {
       //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_IN);
       ue_pdsch_procedures(ue,
 			  proc,
-			  eNB_id,
+			  gNB_id,
 			  PDSCH,
-			  ue->dlsch[proc->thread_id][eNB_id][0],
+			  ue->dlsch[proc->thread_id][gNB_id][0],
 			  NULL,
 			  (ue->frame_parms.symbols_per_slot>>1),
 			  ue->frame_parms.symbols_per_slot-1,
@@ -1460,12 +1507,12 @@ void *UE_thread_slot1_dl_processing(void *arg) {
     }
 
     // do procedures for SI-RNTI
-    if ((ue->dlsch_SI[eNB_id]) && (ue->dlsch_SI[eNB_id]->active == 1)) {
+    if ((ue->dlsch_SI[gNB_id]) && (ue->dlsch_SI[gNB_id]->active == 1)) {
       ue_pdsch_procedures(ue,
 			  proc,
-			  eNB_id,
+			  gNB_id,
 			  SI_PDSCH,
-			  ue->dlsch_SI[eNB_id],
+			  ue->dlsch_SI[gNB_id],
 			  NULL,
 			  (ue->frame_parms.symbols_per_slot>>1),
 			  ue->frame_parms.symbols_per_slot-1,
@@ -1473,24 +1520,24 @@ void *UE_thread_slot1_dl_processing(void *arg) {
     }
 
     // do procedures for P-RNTI
-    if ((ue->dlsch_p[eNB_id]) && (ue->dlsch_p[eNB_id]->active == 1)) {
+    if ((ue->dlsch_p[gNB_id]) && (ue->dlsch_p[gNB_id]->active == 1)) {
       ue_pdsch_procedures(ue,
 			  proc,
-			  eNB_id,
+			  gNB_id,
 			  P_PDSCH,
-			  ue->dlsch_p[eNB_id],
+			  ue->dlsch_p[gNB_id],
 			  NULL,
 			  (ue->frame_parms.symbols_per_slot>>1),
 			  ue->frame_parms.symbols_per_slot-1,
 			  abstraction_flag);
     }
     // do procedures for RA-RNTI
-    if ((ue->dlsch_ra[eNB_id]) && (ue->dlsch_ra[eNB_id]->active == 1) && (UE_mode != PUSCH)) {
+    if ((ue->dlsch_ra[gNB_id]) && (ue->dlsch_ra[gNB_id]->active == 1) && (UE_mode != PUSCH)) {
       ue_pdsch_procedures(ue,
 			  proc,
-			  eNB_id,
+			  gNB_id,
 			  RA_PDSCH,
-			  ue->dlsch_ra[eNB_id],
+			  ue->dlsch_ra[gNB_id],
 			  NULL,
 			  (ue->frame_parms.symbols_per_slot>>1),
 			  ue->frame_parms.symbols_per_slot-1,
@@ -1650,7 +1697,7 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,
 #if UE_TIMING_TRACE
       start_meas(&ue->dlsch_channel_estimation_stats);
 #endif
-      nr_pbch_channel_estimation(ue,proc,0,nr_slot_rx,(ue->symbol_offset+i)%(fp->symbols_per_slot),i-1,(fp->ssb_index)&7,fp->half_frame_bit);
+      nr_pbch_channel_estimation(ue,proc,gNB_id,nr_slot_rx,(ue->symbol_offset+i)%(fp->symbols_per_slot),i-1,(fp->ssb_index)&7,fp->half_frame_bit);
 #if UE_TIMING_TRACE
       stop_meas(&ue->dlsch_channel_estimation_stats);
 #endif
@@ -1710,7 +1757,7 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,
     if (coreset_nb_rb > 0)
       nr_pdcch_channel_estimation(ue,
                                   proc,
-                                  0,
+                                  gNB_id,
                                   nr_slot_rx,
                                   l,
                                   fp->first_carrier_offset+(pdcch_vars->pdcch_config[n_ss].BWPStart + coreset_start_rb)*12,
diff --git a/openair1/SCHED_NR_UE/pucch_power_control_ue_nr.c b/openair1/SCHED_NR_UE/pucch_power_control_ue_nr.c
index f43f4d98c99f9c33bd8504b3acd11face872df20..fadfba6bce576d71d1665b930a14095f7da63741 100644
--- a/openair1/SCHED_NR_UE/pucch_power_control_ue_nr.c
+++ b/openair1/SCHED_NR_UE/pucch_power_control_ue_nr.c
@@ -158,13 +158,14 @@ int16_t get_pucch_tx_power_ue(PHY_VARS_NR_UE *ue,
     }
   }
 
-  int k2;
-
   if (power_config->twoPUCCH_PC_AdjustmentStates > 1) {
     LOG_E(PHY,"PUCCH power control adjustment states with 2 states not yet implemented : at line %d in function %s of file %s \n", LINE_FILE , __func__, __FILE__);
     return (PUCCH_POWER_DEFAULT);
   }
 
+#if 0
+  int k2;
+
   /* response to a detection by the UE of a DCI format 1_0 or DCI format 1_1 */
   //int K_PUCCH = 0;
   if (O_ACK != 0) {
@@ -201,6 +202,7 @@ int16_t get_pucch_tx_power_ue(PHY_VARS_NR_UE *ue,
     }
     //K_PUCCH = N_SYMB_SLOT * k2; /* the product of a number of symbols per slot and the minimum of the values provided by higher layer parameter k2 */
   }
+#endif
 
   int contributor = (10 * log10((double)(pow(2,(ue->frame_parms.numerology_index)) * nb_of_prbs)));
 
diff --git a/openair1/SCHED_NR_UE/pucch_uci_ue_nr.c b/openair1/SCHED_NR_UE/pucch_uci_ue_nr.c
index 1c0e4e22a1c640d98daff3c1e675c9ec5300a75a..21672fde2f9b69962243932ae03209c77118d01c 100644
--- a/openair1/SCHED_NR_UE/pucch_uci_ue_nr.c
+++ b/openair1/SCHED_NR_UE/pucch_uci_ue_nr.c
@@ -549,7 +549,7 @@ bool pucch_procedures_ue_nr(PHY_VARS_NR_UE *ue, uint8_t gNB_id, UE_nr_rxtx_proc_
   int occ_length = 0;
   int occ_Index = 0;
   int BWPsize = 0;
-  int BWPstart = 0;
+  int BWPstart = INT_MAX;
 
   NR_UE_HARQ_STATUS_t *harq_status = &ue->dlsch[proc->thread_id][gNB_id][0]->harq_processes[dl_harq_pid]->harq_ack;
 
@@ -620,7 +620,9 @@ bool pucch_procedures_ue_nr(PHY_VARS_NR_UE *ue, uint8_t gNB_id, UE_nr_rxtx_proc_
           mac->ULbwp[bwp_id]->bwp_Dedicated &&
           mac->ULbwp[bwp_id]->bwp_Dedicated->pucch_Config &&
           mac->ULbwp[bwp_id]->bwp_Dedicated->pucch_Config->choice.setup)
-          pucch_Config =  mac->ULbwp[bwp_id]->bwp_Dedicated->pucch_Config->choice.setup;
+        pucch_Config =  mac->ULbwp[bwp_id]->bwp_Dedicated->pucch_Config->choice.setup;
+        BWPsize  =  NRRIV2BW(mac->ULbwp[bwp_id]->bwp_Common->genericParameters.locationAndBandwidth,MAX_BWP_SIZE);
+        BWPstart =  NRRIV2PRBOFFSET(mac->ULbwp[bwp_id]->bwp_Common->genericParameters.locationAndBandwidth,MAX_BWP_SIZE);
       else if (bwp_id==0 &&
                mac->cg &&
                mac->cg->spCellConfig &&
diff --git a/openair1/SIMULATION/NR_PHY/dlsim.c b/openair1/SIMULATION/NR_PHY/dlsim.c
index 848b6d4e7507f1afcf25ea625f27672960bcef2a..fb779be09f866feb037943397fa247ce20085a97 100644
--- a/openair1/SIMULATION/NR_PHY/dlsim.c
+++ b/openair1/SIMULATION/NR_PHY/dlsim.c
@@ -237,12 +237,12 @@ int oai_nfapi_ul_tti_req(nfapi_nr_ul_tti_request_t *ul_tti_req){ return(0);  }
 // needed for some functions
 openair0_config_t openair0_cfg[MAX_CARDS];
 void update_ptrs_config(NR_CellGroupConfig_t *secondaryCellGroup, uint16_t *rbSize, uint8_t *mcsIndex,int8_t *ptrs_arg);
-void update_dmrs_config(NR_CellGroupConfig_t *scg,PHY_VARS_NR_UE *ue, int8_t* dmrs_arg);
+void update_dmrs_config(NR_CellGroupConfig_t *scg, int8_t* dmrs_arg);
 extern void fix_scd(NR_ServingCellConfig_t *scd);// forward declaration
 
-/* specific dlsim DL preprocessor: uses rbStart/rbSize/mcs from command line of
+/* specific dlsim DL preprocessor: uses rbStart/rbSize/mcs/nrOfLayers from command line of
    dlsim, does not search for CCE/PUCCH occasion but simply sets to 0 */
-int g_mcsIndex = -1, g_mcsTableIdx = 0, g_rbStart = -1, g_rbSize = -1;
+int g_mcsIndex = -1, g_mcsTableIdx = 0, g_rbStart = -1, g_rbSize = -1, g_nrOfLayers = 1;
 void nr_dlsim_preprocessor(module_id_t module_id,
                            frame_t frame,
                            sub_frame_t slot) {
@@ -278,6 +278,7 @@ void nr_dlsim_preprocessor(module_id_t module_id,
    * configuration */
   ps->mcsTableIdx = g_mcsTableIdx;
 
+  sched_pdsch->nrOfLayers = g_nrOfLayers;
   sched_pdsch->Qm = nr_get_Qm_dl(sched_pdsch->mcs, ps->mcsTableIdx);
   sched_pdsch->R = nr_get_code_rate_dl(sched_pdsch->mcs, ps->mcsTableIdx);
   sched_pdsch->tb_size = nr_compute_tbs(sched_pdsch->Qm,
@@ -287,7 +288,7 @@ void nr_dlsim_preprocessor(module_id_t module_id,
                                         ps->N_PRB_DMRS * ps->N_DMRS_SLOT,
                                         0 /* N_PRB_oh, 0 for initialBWP */,
                                         0 /* tb_scaling */,
-                                        1 /* nrOfLayers */)
+                                        sched_pdsch->nrOfLayers)
                          >> 3;
 
   /* the simulator assumes the HARQ PID is equal to the slot number */
@@ -355,7 +356,7 @@ int main(int argc, char **argv)
   //  char fname[40], vname[40];
   int trial, n_trials = 1, n_errors = 0, n_false_positive = 0;
   //int n_errors2, n_alamouti;
-  uint8_t transmission_mode = 1,n_tx=1,n_rx=1;
+  uint8_t n_tx=1,n_rx=1;
   uint8_t round;
   uint8_t num_rounds = 4;
 
@@ -397,7 +398,7 @@ int main(int argc, char **argv)
   int8_t enable_ptrs = 0;
   int8_t modify_dmrs = 0;
 
-  int8_t dmrs_arg[2] = {-1,-1};// Invalid values
+  int8_t dmrs_arg[3] = {-1,-1,-1};// Invalid values
   /* L_PTRS = ptrs_arg[0], K_PTRS = ptrs_arg[1] */
   int8_t ptrs_arg[2] = {-1,-1};// Invalid values
 
@@ -463,6 +464,10 @@ int main(int argc, char **argv)
         channel_model=ETU;
         break;
 
+      case 'R':
+        channel_model=Rayleigh1;
+        break;
+
       default:
         printf("Unsupported channel model!\n");
         exit(-1);
@@ -512,12 +517,11 @@ int main(int argc, char **argv)
       break;
       */
     case 'x':
-      transmission_mode=atoi(optarg);
+      g_nrOfLayers=atoi(optarg);
 
-      if ((transmission_mode!=1) &&
-          (transmission_mode!=2) &&
-          (transmission_mode!=6)) {
-        printf("Unsupported transmission mode %d\n",transmission_mode);
+      if ((g_nrOfLayers!=1) &&
+          (g_nrOfLayers!=2)) {
+        printf("Unsupported nr Of Layers %d\n",g_nrOfLayers);
         exit(-1);
       }
 
@@ -634,7 +638,7 @@ int main(int argc, char **argv)
       printf("-s Starting SNR, runs from SNR0 to SNR0 + 5 dB.  If n_frames is 1 then just SNR is simulated\n");
       printf("-S Ending SNR, runs from SNR0 to SNR1\n");
       printf("-t Delay spread for multipath channel\n");
-      printf("-g [A,B,C,D,E,F,G] Use 3GPP SCM (A,B,C,D) or 36-101 (E-EPA,F-EVA,G-ETU) models (ignores delay spread and Ricean factor)\n");
+      printf("-g [A,B,C,D,E,F,G,R] Use 3GPP SCM (A,B,C,D) or 36-101 (E-EPA,F-EVA,G-ETU) models or R for MIMO model (ignores delay spread and Ricean factor)\n");
       printf("-y Number of TX antennas used in gNB\n");
       printf("-z Number of RX antennas used in UE\n");
       //printf("-i Relative strength of first intefering gNB (in dB) - cell_id mod 3 = 1\n");
@@ -655,7 +659,7 @@ int main(int argc, char **argv)
       printf("-q Use 2nd MCS table (256 QAM table) for PDSCH\n");
       printf("-t Acceptable effective throughput (in percentage)\n");
       printf("-T Enable PTRS, arguments list L_PTRS{0,1,2} K_PTRS{2,4}, e.g. -T 2 0 2 \n");
-      printf("-U Change DMRS Config, arguments list DMRS TYPE{0=A,1=B} DMRS AddPos{0:2}, e.g. -U 2 0 2 \n");
+      printf("-U Change DMRS Config, arguments list DMRS TYPE{0=A,1=B} DMRS AddPos{0:2} DMRS ConfType{1:2}, e.g. -U 3 0 2 1 \n");
       printf("-P Print DLSCH performances\n");
       printf("-w Write txdata to binary file (one frame)\n");
       printf("-d number of dlsch threads, 0: no dlsch parallelization\n");
@@ -760,7 +764,7 @@ int main(int argc, char **argv)
   fix_scd(scd);
   /* -U option modify DMRS */
   if(modify_dmrs) {
-    update_dmrs_config(secondaryCellGroup, NULL,dmrs_arg);
+    update_dmrs_config(secondaryCellGroup, dmrs_arg);
   }
   /* -T option enable PTRS */
   if(enable_ptrs) {
@@ -894,9 +898,6 @@ int main(int argc, char **argv)
     exit(-1);
   }
 
-  if(modify_dmrs) {
-    update_dmrs_config( NULL,UE,dmrs_arg);
-  }
   init_nr_ue_transport(UE,0);
 
   nr_gold_pbch(UE);
@@ -1138,6 +1139,11 @@ 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
+
         for (i=frame_parms->get_samples_slot_timestamp(slot,frame_parms,0); 
              i<frame_parms->get_samples_slot_timestamp(slot+1,frame_parms,0);
              i++) {
@@ -1148,9 +1154,9 @@ int main(int argc, char **argv)
               // sum up signals from different Tx antennas
               r_re[aa_rx][i] = 0;
               r_im[aa_rx][i] = 0;
-              for (aa=0; aa<n_tx; aa++) {
-                r_re[aa_rx][i] += s_re[aa][i];
-                r_im[aa_rx][i] += s_im[aa][i];
+             for (aa=0; aa<n_tx; aa++) {
+                r_re[aa_rx][i] += s_re[aa][i]*H_awgn_mimo[aa_rx][aa];
+                r_im[aa_rx][i] += s_im[aa][i]*H_awgn_mimo[aa_rx][aa];
               }
             }
             // Add Gaussian noise
@@ -1417,10 +1423,12 @@ void update_ptrs_config(NR_CellGroupConfig_t *secondaryCellGroup, uint16_t *rbSi
   rrc_config_dl_ptrs_params(bwp, ptrsFreqDenst, ptrsTimeDenst, &epre_Ratio, &reOffset);
 }
 
-void update_dmrs_config(NR_CellGroupConfig_t *scg,PHY_VARS_NR_UE *ue, int8_t* dmrs_arg)
+void update_dmrs_config(NR_CellGroupConfig_t *scg, int8_t* dmrs_arg)
 {
   int8_t  mapping_type = typeA;//default value
   int8_t  add_pos = pdsch_dmrs_pos0;//default value
+  int8_t  dmrs_config_type = NFAPI_NR_DMRS_TYPE1;//default value
+
   if(dmrs_arg[0] == 0) {
     mapping_type = typeA;
   }
@@ -1437,60 +1445,68 @@ void update_dmrs_config(NR_CellGroupConfig_t *scg,PHY_VARS_NR_UE *ue, int8_t* dm
     AssertFatal(1==0,"Incorrect Additional Position, valid options 0-pos1, 1-pos1, 2-pos2, 3-pos3\n");
   }
 
-  if(scg != NULL) {
-    NR_BWP_Downlink_t *bwp = scg->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[0];
-
-    AssertFatal((bwp->bwp_Dedicated->pdsch_Config != NULL && bwp->bwp_Dedicated->pdsch_Config->choice.setup != NULL), "Base RRC reconfig structures are not allocated.\n");
-
-    if (bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA == NULL) {
-      bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA = calloc(1,sizeof(*bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA));
-      bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->present= NR_SetupRelease_DMRS_DownlinkConfig_PR_setup;
-      bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup = calloc(1,sizeof(*bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup));
-      bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_Type=NULL;//calloc(1,sizeof(*bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_Type));
-      bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->maxLength=NULL;
-      bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->scramblingID0=NULL;
-      bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->scramblingID1=NULL;
-      bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->phaseTrackingRS=NULL;
-      bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_AdditionalPosition = NULL;
-      printf("DLSIM: Allocated Mapping TypeA in RRC reconfig message\n");
-    } else if (bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeB == NULL) {
-      bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeB = calloc(1,sizeof(*bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeB));
-      bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeB->present= NR_SetupRelease_DMRS_DownlinkConfig_PR_setup;
-      bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeB->choice.setup = calloc(1,sizeof(*bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeB->choice.setup));
-      bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeB->choice.setup->dmrs_Type=NULL;//calloc(1,sizeof(*bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_Type));
-      bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeB->choice.setup->maxLength=NULL;
-      bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeB->choice.setup->scramblingID0=NULL;
-      bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeB->choice.setup->scramblingID1=NULL;
-      bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeB->choice.setup->phaseTrackingRS=NULL;
-      bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeB->choice.setup->dmrs_AdditionalPosition = NULL;
-      printf("DLSIM: Allocated Mapping TypeB in RRC reconfig message\n");
-    }
+  /* DMRS Conf Type 1 or 2 */
+  if(dmrs_arg[2] == 1) {
+    dmrs_config_type = NFAPI_NR_DMRS_TYPE1;
+  } else if(dmrs_arg[2] == 2) {
+    dmrs_config_type = NFAPI_NR_DMRS_TYPE2;
+  }
 
-    struct NR_SetupRelease_DMRS_DownlinkConfig	*dmrs_MappingtypeA = bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA;
-    struct NR_SetupRelease_DMRS_DownlinkConfig	*dmrs_MappingtypeB = bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeB;
+  NR_BWP_Downlink_t *bwp = scg->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[0];
+
+  AssertFatal((bwp->bwp_Dedicated->pdsch_Config != NULL && bwp->bwp_Dedicated->pdsch_Config->choice.setup != NULL), "Base RRC reconfig structures are not allocated.\n");
+
+  if(mapping_type == typeA) {
+    bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA = calloc(1,sizeof(*bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA));
+    bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->present= NR_SetupRelease_DMRS_DownlinkConfig_PR_setup;
+    bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup = calloc(1,sizeof(*bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup));
+    if (dmrs_config_type == NFAPI_NR_DMRS_TYPE2)
+      bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_Type = calloc(1,sizeof(*bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_Type));
+    else
+      bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_Type = NULL;
+    bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->maxLength=NULL;
+    bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->scramblingID0=NULL;
+    bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->scramblingID1=NULL;
+    bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->phaseTrackingRS=NULL;
+    bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_AdditionalPosition = NULL;
+    printf("DLSIM: Allocated Mapping TypeA in RRC reconfig message\n");
+  }
 
+  if(mapping_type == typeB) {
+    bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeB = calloc(1,sizeof(*bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeB));
+    bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeB->present= NR_SetupRelease_DMRS_DownlinkConfig_PR_setup;
+    bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeB->choice.setup = calloc(1,sizeof(*bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeB->choice.setup));
+    if (dmrs_config_type == NFAPI_NR_DMRS_TYPE2)
+      bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeB->choice.setup->dmrs_Type = calloc(1,sizeof(*bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeB->choice.setup->dmrs_Type));
+    else
+      bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeB->choice.setup->dmrs_Type = NULL;
+    bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeB->choice.setup->maxLength=NULL;
+    bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeB->choice.setup->scramblingID0=NULL;
+    bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeB->choice.setup->scramblingID1=NULL;
+    bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeB->choice.setup->phaseTrackingRS=NULL;
+    bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeB->choice.setup->dmrs_AdditionalPosition = NULL;
+    printf("DLSIM: Allocated Mapping TypeB in RRC reconfig message\n");
+  }
 
-    NR_DMRS_DownlinkConfig_t *dmrs_config = (mapping_type == typeA) ? dmrs_MappingtypeA->choice.setup : dmrs_MappingtypeB->choice.setup;
+  struct NR_SetupRelease_DMRS_DownlinkConfig	*dmrs_MappingtypeA = bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA;
+  struct NR_SetupRelease_DMRS_DownlinkConfig	*dmrs_MappingtypeB = bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeB;
 
-    if (add_pos != 2) { // pos0,pos1,pos3
-      if (dmrs_config->dmrs_AdditionalPosition == NULL) {
-        dmrs_config->dmrs_AdditionalPosition = calloc(1,sizeof(*dmrs_MappingtypeA->choice.setup->dmrs_AdditionalPosition));
-      }
-      *dmrs_config->dmrs_AdditionalPosition = add_pos;
-    } else { // if NULL, Value pos2
-      free(dmrs_config->dmrs_AdditionalPosition);
-      dmrs_config->dmrs_AdditionalPosition = NULL;
-    }
 
-    for (int i=0;i<bwp->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.count;i++) {
-      bwp->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.array[i]->mappingType = mapping_type; 
+  NR_DMRS_DownlinkConfig_t *dmrs_config = (mapping_type == typeA) ? dmrs_MappingtypeA->choice.setup : dmrs_MappingtypeB->choice.setup;
+
+  if (add_pos != 2) { // pos0,pos1,pos3
+    if (dmrs_config->dmrs_AdditionalPosition == NULL) {
+      dmrs_config->dmrs_AdditionalPosition = calloc(1,sizeof(*dmrs_MappingtypeA->choice.setup->dmrs_AdditionalPosition));
     }
+    *dmrs_config->dmrs_AdditionalPosition = add_pos;
+  } else { // if NULL, Value pos2
+    free(dmrs_config->dmrs_AdditionalPosition);
+    dmrs_config->dmrs_AdditionalPosition = NULL;
   }
-  if(ue != NULL) {
-    for (int i=0;i<MAX_NR_OF_DL_ALLOCATIONS;i++) {
-      ue->PDSCH_Config.pdsch_TimeDomainResourceAllocation[i]->mappingType = mapping_type;
-    }
-    ue->dmrs_DownlinkConfig.pdsch_dmrs_AdditionalPosition = add_pos;
+
+  for (int i=0;i<bwp->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.count;i++) {
+    bwp->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.array[i]->mappingType = mapping_type;
   }
-  printf("[DLSIM] DMRS Config is modified with Mapping Type %d, Additional Positions %d \n", dmrs_arg[0], dmrs_arg[1] );
+
+  printf("[DLSIM] DMRS Config is modified with Mapping Type %d, Additional Positions %d Config. Type %d \n", mapping_type, add_pos, dmrs_config_type);
 }
diff --git a/openair1/SIMULATION/TOOLS/multipath_tv_channel.c b/openair1/SIMULATION/TOOLS/multipath_tv_channel.c
index c68ce737580b6ec7ae36763e6138adebbb3f82ce..ece1f81335f4af9393b4a4df37cf08b10918d618 100644
--- a/openair1/SIMULATION/TOOLS/multipath_tv_channel.c
+++ b/openair1/SIMULATION/TOOLS/multipath_tv_channel.c
@@ -40,9 +40,9 @@ void multipath_tv_channel(channel_desc_t *desc,
                           uint8_t keep_channel)
 {
 
-  double complex **tx,**rx,***H_t,*rx_temp;//, *tv_H_t;
+  double complex **tx,**rx,***H_t;
   double path_loss = pow(10,desc->path_loss_dB/20);
-  int i,j,k,dd;
+  int i,j,dd;
   dd = abs(desc->channel_offset);
 #ifdef DEBUG_CH
   printf("[TV CHANNEL] keep = %d : path_loss = %g (%f), nb_rx %d, nb_tx %d, dd %d, len %d max_doppler %g\n",keep_channel,path_loss,desc->path_loss_dB,desc->nb_rx,desc->nb_tx,dd,desc->channel_length,
@@ -51,8 +51,6 @@ void multipath_tv_channel(channel_desc_t *desc,
   tx = (double complex **)malloc(desc->nb_tx*sizeof(double complex *));
   rx = (double complex **)malloc(desc->nb_rx*sizeof(double complex *));
   H_t= (double complex ***) malloc(desc->nb_tx*desc->nb_rx*sizeof(double complex **));
-  //  tv_H_t = (double complex *) malloc(length*sizeof(double complex));
-  rx_temp= (double complex *) calloc(length,sizeof(double complex));
 
   for(i=0; i<desc->nb_tx; i++) {
     tx[i] = (double complex *)calloc(length,sizeof(double complex));
@@ -84,11 +82,7 @@ void multipath_tv_channel(channel_desc_t *desc,
 
   for(i=0; i<desc->nb_rx; i++) {
     for(j=0; j<desc->nb_tx; j++) {
-      tv_conv(H_t[i+(j*desc->nb_rx)],tx[j],rx_temp,length,desc->nb_taps,dd);
-
-      for(k=0; k<length; k++) {
-        rx[i][k] += rx_temp[k];
-      }
+      tv_conv(H_t[i+(j*desc->nb_rx)],tx[j],rx[i],length,desc->nb_taps,dd);
     }
   }
 
@@ -99,10 +93,6 @@ void multipath_tv_channel(channel_desc_t *desc,
     }
   }
 
-  /*  for(k=0;k<length;k++) {
-      tv_H_t[k] = H_t[0][k][0];
-      }*/
-
   for(i=0; i<desc->nb_tx; i++) {
     free(tx[i]);
   }
@@ -124,7 +114,6 @@ void multipath_tv_channel(channel_desc_t *desc,
   }
 
   free(H_t);
-  free(rx_temp);
 }
 
 //TODO: make phi_rad a parameter of this function
@@ -177,7 +166,7 @@ void tv_channel(channel_desc_t *desc,double complex ***H,uint32_t length){
             H[i+(j*desc->nb_rx)][k][l] += sqrt(desc->amps[k])*alpha[p]*cexp(I*(2*pi*w_Hz[i+(j*desc->nb_rx)][k][p]*l*(1/(desc->sampling_rate*1e6))+phi_rad[i+(j*desc->nb_rx)][k][p]));
           }
         }
-        //printf("H[tx%d][rx%d][k%d] = %f+j%f \n",j,i,k,creal(H[i+(j*desc->nb_rx)][k][0]),cimag(H[i+(j*desc->nb_rx)][k][0]));
+        //printf("H[tx%d][rx%d][k%d][l%d] = %f+j%f \n",j,i,k,0,creal(H[i+(j*desc->nb_rx)][k][0]),cimag(H[i+(j*desc->nb_rx)][k][0]));
       }
     }
   }
@@ -201,14 +190,12 @@ void tv_channel(channel_desc_t *desc,double complex ***H,uint32_t length){
 }
 
 // time varying convolution
-void tv_conv(double complex **h, double complex *x, double complex *y, uint32_t nb_samples, uint8_t nb_taps, int dd){
-
-  int i,j;
-
-  for(i=0; i<((int)nb_samples-dd); i++) {
-    for(j=0; j<nb_taps; j++) {
-      if(i>j)
-        y[i+dd] += creal(h[j][i])*creal(x[i-j])-cimag(h[j][i])*cimag(x[i-j]) + I*(creal(h[j][i])*cimag(x[i-j])+cimag(h[j][i])*creal(x[i-j]));
+void tv_conv(double complex **h, double complex *x, double complex *y, uint32_t nb_samples, uint8_t nb_taps, int dd)
+{
+  for(int i = 0; i < ((int)nb_samples-dd); i++) {
+    for(int j = 0; j < nb_taps; j++) {
+      if(i >= j)
+        y[i+dd] += h[j][i] * x[i-j];
     }
   }
 }
diff --git a/openair2/COMMON/platform_types.h b/openair2/COMMON/platform_types.h
index d425b9e7d7a895eb8696db1b51b7ddfb8f2c47e0..23b33dd8b13ab1f8249942f2e304c5e800d72dd4 100644
--- a/openair2/COMMON/platform_types.h
+++ b/openair2/COMMON/platform_types.h
@@ -195,21 +195,13 @@ typedef uint8_t            mme_code_t;
 typedef uint32_t           m_tmsi_t;
 
 //Random UE identity length = 40 bits
-#if ! defined(NOT_A_RANDOM_UE_IDENTITY)
   #define NOT_A_RANDOM_UE_IDENTITY (uint64_t)0xFFFFFFFF
-#endif
-#if ! defined(NOT_A_RNTI)
   #define NOT_A_RNTI (rnti_t)0
-#endif
-#if ! defined(M_RNTI)
   #define M_RNTI     (rnti_t)0xFFFD
-#endif
-#if ! defined(P_RNTI)
   #define P_RNTI     (rnti_t)0xFFFE
-#endif
-#if ! defined(SI_RNTI)
   #define SI_RNTI    (rnti_t)0xFFFF
-#endif
+#define CBA_RNTI   (rnti_t)0xfff4
+#define OAI_C_RNTI (rnti_t)0x1234
 typedef enum config_action_e {
   CONFIG_ACTION_NULL              = 0,
   CONFIG_ACTION_ADD               = 1,
diff --git a/openair2/COMMON/rrc_messages_types.h b/openair2/COMMON/rrc_messages_types.h
index 64c42eaf0eb8cc7bb7187ea85dcc310493229bd9..220ef60b3ddd3c66c36ea65dd6bc172dd4ee76df 100644
--- a/openair2/COMMON/rrc_messages_types.h
+++ b/openair2/COMMON/rrc_messages_types.h
@@ -405,6 +405,7 @@ typedef struct NRRrcConfigurationReq_s {
   uint16_t                mcc[PLMN_LIST_MAX_SIZE];
   uint16_t                mnc[PLMN_LIST_MAX_SIZE];
   uint8_t                 mnc_digit_length[PLMN_LIST_MAX_SIZE];
+  uint8_t                 num_plmn;
   NR_ServingCellConfigCommon_t *scc;
   NR_ServingCellConfig_t  *scd;
   int                     ssb_SubcarrierOffset;
diff --git a/openair2/ENB_APP/enb_paramdef.h b/openair2/ENB_APP/enb_paramdef.h
index f26863414cbc26709c1c54300fc065cfc7274629..79e66881b5c00ddd43a9fae3814bd3b5735a8f69 100644
--- a/openair2/ENB_APP/enb_paramdef.h
+++ b/openair2/ENB_APP/enb_paramdef.h
@@ -98,6 +98,7 @@ typedef enum {
 #define CONFIG_STRING_RU_BF_WEIGHTS_LIST          "bf_weights"
 #define CONFIG_STRING_RU_IF_FREQUENCY             "if_freq"
 #define CONFIG_STRING_RU_IF_FREQ_OFFSET           "if_offset"
+#define CONFIG_STRING_RU_DO_PRECODING             "do_precoding"
 
 #define RU_LOCAL_IF_NAME_IDX          0
 #define RU_LOCAL_ADDRESS_IDX          1
@@ -127,7 +128,7 @@ typedef enum {
 #define RU_BF_WEIGHTS_LIST_IDX        25
 #define RU_IF_FREQUENCY               26
 #define RU_IF_FREQ_OFFSET             27
-
+#define RU_DO_PRECODING               28
 /*-----------------------------------------------------------------------------------------------------------------------------------------*/
 /*                                            RU configuration parameters                                                                  */
 /*   optname                                   helpstr   paramflags    XXXptr          defXXXval                   type      numelt        */
@@ -160,7 +161,8 @@ typedef enum {
     {CONFIG_STRING_RU_OTA_SYNC_ENABLE,             NULL,       0,       strptr:NULL,     defstrval:"no",          TYPE_STRING,      0}, \
     {CONFIG_STRING_RU_BF_WEIGHTS_LIST,             NULL,       0,       iptr:NULL,       defintarrayval:DEFBFW,   TYPE_INTARRAY,    0}, \
     {CONFIG_STRING_RU_IF_FREQUENCY,                NULL,       0,       u64ptr:NULL,     defuintval:0,            TYPE_UINT64,      0}, \
-    {CONFIG_STRING_RU_IF_FREQ_OFFSET,              NULL,       0,       iptr:NULL,     defintval:0,             TYPE_INT,         0}, \
+    {CONFIG_STRING_RU_IF_FREQ_OFFSET,              NULL,       0,       iptr:NULL,       defintval:0,             TYPE_INT,         0}, \
+    {CONFIG_STRING_RU_DO_PRECODING,                NULL,       0,       iptr:NULL,       defintval:0,             TYPE_INT,         0}, \
   }
 
 /*---------------------------------------------------------------------------------------------------------------------------------------*/
diff --git a/openair2/F1AP/dummy_enb.c b/openair2/F1AP/dummy_enb.c
index ee98b9ec4687b3bef354773b40207e111cc25ef6..fe6dfb6a06af9f3130cc418a4136ac6f1e487fc6 100644
--- a/openair2/F1AP/dummy_enb.c
+++ b/openair2/F1AP/dummy_enb.c
@@ -20,42 +20,15 @@
  */
 
 #include "COMMON/platform_types.h"
-#include "COMMON/platform_constants.h"
 #include "common/ran_context.h"
-
 #include "common/utils/LOG/log.h"
-#include "common/utils/LOG/vcd_signal_dumper.h"
-
 #include "NR_BCCH-BCH-Message.h"
 #include "NR_ServingCellConfigCommon.h"
-
-#include "LAYER2/NR_MAC_gNB/mac_proto.h"
-#include "SCHED_NR/phy_frame_config_nr.h"
-
 #include "NR_MIB.h"
-#include "LAYER2/NR_MAC_COMMON/nr_mac_common.h"
-#include "../../../../nfapi/oai_integration/vendor_ext.h"
-/* Softmodem params */
-#include "executables/softmodem-common.h"
 
-
-int rrc_mac_config_req_gNB(module_id_t Mod_idP,
-                           int ssb_SubcarrierOffset,
-                           int pdsch_AntennaPorts,
-                           int pusch_AntennaPorts,
-                           NR_ServingCellConfigCommon_t *scc,
-                           int add_ue,
-                           uint32_t rnti,
-                           NR_CellGroupConfig_t *CellGroup){
-abort();
-return 0;
-}
-rlc_op_status_t nr_rrc_rlc_config_asn1_req (const protocol_ctxt_t   * const ctxt_pP,
-    const NR_SRB_ToAddModList_t   * const srb2add_listP,
-    const NR_DRB_ToAddModList_t   * const drb2add_listP,
-    const NR_DRB_ToReleaseList_t  * const drb2release_listP,
-    const LTE_PMCH_InfoList_r9_t * const pmch_InfoList_r9_pP,
-    struct NR_CellGroupConfig__rlc_BearerToAddModList *rlc_bearer2add_list){
+void apply_macrlc_config(gNB_RRC_INST *rrc,
+                         rrc_gNB_ue_context_t         *const ue_context_pP,
+                         const protocol_ctxt_t        *const ctxt_pP ) {
 abort();
-return 0;
 }
+
diff --git a/openair2/F1AP/f1ap_cu_rrc_message_transfer.c b/openair2/F1AP/f1ap_cu_rrc_message_transfer.c
index 03cfcc73298f89361b4198de52c1e1d476765eba..8a5b9785b50f50c95beea62d6f93cbd540db0724 100644
--- a/openair2/F1AP/f1ap_cu_rrc_message_transfer.c
+++ b/openair2/F1AP/f1ap_cu_rrc_message_transfer.c
@@ -38,13 +38,6 @@
 #include "common/ran_context.h"
 #include "openair3/UTILS/conversions.h"
 
-// undefine C_RNTI from
-// openair1/PHY/LTE_TRANSPORT/transport_common.h which
-// replaces in ie->value.choice.C_RNTI, causing
-// a compile error
-#undef C_RNTI 
-
-
 // Bing Kai: create CU and DU context, and put all the information there.
 uint64_t        du_ue_f1ap_id = 0;
 uint32_t        f1ap_assoc_id = 0;
diff --git a/openair2/F1AP/f1ap_cu_ue_context_management.c b/openair2/F1AP/f1ap_cu_ue_context_management.c
index 317f0058b26323696f0462f6fa7c66832b181ce3..da723ba5a38f8612efb899afb1b2532a8be0d0f3 100644
--- a/openair2/F1AP/f1ap_cu_ue_context_management.c
+++ b/openair2/F1AP/f1ap_cu_ue_context_management.c
@@ -39,8 +39,10 @@
 
 #include "rrc_extern.h"
 #include "rrc_eNB_UE_context.h"
+#include "openair2/RRC/NR/rrc_gNB_UE_context.h"
 #include "rrc_eNB_S1AP.h"
 #include "rrc_eNB_GTPV1U.h"
+#include "openair2/RRC/NR/rrc_gNB_NGAP.h"
 
 extern f1ap_setup_req_t *f1ap_du_data_from_du;
 extern f1ap_cudu_inst_t f1ap_cu_inst[MAX_eNB];
@@ -1029,35 +1031,55 @@ int CU_handle_UE_CONTEXT_RELEASE_COMPLETE(instance_t       instance,
     // F1AP_CriticalityDiagnostics_IE_List
   }
 
-  struct rrc_eNB_ue_context_s *ue_context_p =
-      rrc_eNB_get_ue_context(RC.rrc[instance], rnti);
   protocol_ctxt_t ctxt;
   PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, instance, ENB_FLAG_YES, rnti, 0, 0, instance);
 
-  if (ue_context_p) {
-    /* The following is normally done in the function rrc_rx_tx() */
-    rrc_eNB_send_S1AP_UE_CONTEXT_RELEASE_CPLT(instance,
-        ue_context_p->ue_context.eNB_ue_s1ap_id);
-
-    rrc_eNB_send_GTPV1U_ENB_DELETE_TUNNEL_REQ(instance, ue_context_p);
-    // erase data of GTP tunnels in UE context
-    for (int e_rab = 0; e_rab < ue_context_p->ue_context.nb_of_e_rabs; e_rab++) {
-      ue_context_p->ue_context.enb_gtp_teid[e_rab] = 0;
-      memset(&ue_context_p->ue_context.enb_gtp_addrs[e_rab],
-             0, sizeof(ue_context_p->ue_context.enb_gtp_addrs[e_rab]));
-      ue_context_p->ue_context.enb_gtp_ebi[e_rab]  = 0;
-    }
+  if (RC.nrrrc[instance]->node_type == ngran_gNB_CU) {
+    struct rrc_gNB_ue_context_s *ue_context_p =
+        rrc_gNB_get_ue_context(RC.nrrrc[instance], rnti);
 
-    struct rrc_ue_s1ap_ids_s *rrc_ue_s1ap_ids =
-        rrc_eNB_S1AP_get_ue_ids(RC.rrc[instance], 0,
-                                ue_context_p->ue_context.eNB_ue_s1ap_id);
-    if (rrc_ue_s1ap_ids)
-        rrc_eNB_S1AP_remove_ue_ids(RC.rrc[instance], rrc_ue_s1ap_ids);
+    if (ue_context_p) {
+      MessageDef *msg = itti_alloc_new_message(TASK_CU_F1, 0, NGAP_UE_CONTEXT_RELEASE_COMPLETE);
+      NGAP_UE_CONTEXT_RELEASE_COMPLETE(msg).gNB_ue_ngap_id = ue_context_p->ue_context.gNB_ue_ngap_id;
+      itti_send_msg_to_task(TASK_NGAP, instance, msg);
+
+      rrc_gNB_remove_ue_context(&ctxt, RC.nrrrc[instance], ue_context_p);
+    } else {
+      LOG_E(F1AP, "could not find ue_context of UE RNTI %x\n", rnti);
+    }
+#ifdef ITTI_SIM
+    return 0;
+#endif
 
-    /* trigger UE release in RRC */
-    rrc_eNB_remove_ue_context(&ctxt, RC.rrc[instance], ue_context_p);
   } else {
-    LOG_E(F1AP, "could not find ue_context of UE RNTI %x\n", rnti);
+    struct rrc_eNB_ue_context_s *ue_context_p =
+        rrc_eNB_get_ue_context(RC.rrc[instance], rnti);
+
+    if (ue_context_p) {
+      /* The following is normally done in the function rrc_rx_tx() */
+      rrc_eNB_send_S1AP_UE_CONTEXT_RELEASE_CPLT(instance,
+          ue_context_p->ue_context.eNB_ue_s1ap_id);
+
+      rrc_eNB_send_GTPV1U_ENB_DELETE_TUNNEL_REQ(instance, ue_context_p);
+      // erase data of GTP tunnels in UE context
+      for (int e_rab = 0; e_rab < ue_context_p->ue_context.nb_of_e_rabs; e_rab++) {
+        ue_context_p->ue_context.enb_gtp_teid[e_rab] = 0;
+        memset(&ue_context_p->ue_context.enb_gtp_addrs[e_rab],
+              0, sizeof(ue_context_p->ue_context.enb_gtp_addrs[e_rab]));
+        ue_context_p->ue_context.enb_gtp_ebi[e_rab]  = 0;
+      }
+
+      struct rrc_ue_s1ap_ids_s *rrc_ue_s1ap_ids =
+          rrc_eNB_S1AP_get_ue_ids(RC.rrc[instance], 0,
+                                  ue_context_p->ue_context.eNB_ue_s1ap_id);
+      if (rrc_ue_s1ap_ids)
+          rrc_eNB_S1AP_remove_ue_ids(RC.rrc[instance], rrc_ue_s1ap_ids);
+
+      /* trigger UE release in RRC */
+      rrc_eNB_remove_ue_context(&ctxt, RC.rrc[instance], ue_context_p);
+    } else {
+      LOG_E(F1AP, "could not find ue_context of UE RNTI %x\n", rnti);
+    }
   }
 
   pdcp_remove_UE(&ctxt);
diff --git a/openair2/F1AP/f1ap_du_rrc_message_transfer.c b/openair2/F1AP/f1ap_du_rrc_message_transfer.c
index 07df0b4a78748e375394e4f1ac5018cdbf114350..0c8f566fd669fc2e30a189b352cf5e7bc7c8230c 100644
--- a/openair2/F1AP/f1ap_du_rrc_message_transfer.c
+++ b/openair2/F1AP/f1ap_du_rrc_message_transfer.c
@@ -56,13 +56,6 @@
 #include "intertask_interface.h"
 #include "LAYER2/NR_MAC_gNB/mac_proto.h"
 
-// undefine C_RNTI from
-// openair1/PHY/LTE_TRANSPORT/transport_common.h which
-// replaces in ie->value.choice.C_RNTI, causing
-// a compile error
-
-#undef C_RNTI 
-
 extern f1ap_setup_req_t *f1ap_du_data;
 extern RAN_CONTEXT_t RC;
 extern f1ap_cudu_inst_t f1ap_du_inst[MAX_eNB];
@@ -990,135 +983,6 @@ int DU_send_UL_NR_RRC_MESSAGE_TRANSFER(instance_t instance,
                        msg->rrc_container_length);
   ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
 
-  if (msg->srb_id == 1 || msg->srb_id == 2) {
-    struct rrc_gNB_ue_context_s* ue_context_p = rrc_gNB_get_ue_context(RC.nrrrc[instance], rnti);
-
-
-    NR_UL_DCCH_Message_t* ul_dcch_msg=NULL;
-    asn_dec_rval_t dec_rval;
-    dec_rval = uper_decode(NULL,
-         &asn_DEF_NR_UL_DCCH_Message,
-         (void**)&ul_dcch_msg,
-         &ie->value.choice.RRCContainer.buf[1], // buf[0] includes the pdcp header
-         msg->rrc_container_length, 0, 0);
-
-    if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) {
-      LOG_E(F1AP, " Failed to decode UL-DCCH (%zu bytes)\n",dec_rval.consumed);
-      /* for rfsim, because UE send RRCSetupRequest in SRB1 */
-      // NR_UL_CCCH_Message_t *ul_ccch_msg;
-      // dec_rval = uper_decode(NULL,
-      //    &asn_DEF_NR_UL_CCCH_Message,
-      //    (void**)&ul_ccch_msg,
-      //    &ie->value.choice.RRCContainer.buf[1], // buf[0] includes the pdcp header
-      //    msg->rrc_container_length, 0, 0);
-      // if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) {
-      //   LOG_E(F1AP, " Failed to decode UL-CCCH (%zu bytes)\n",dec_rval.consumed);
-      // } else {
-      //   LOG_I(F1AP, "decode UL-CCCH success \n");
-      //   LOG_I(F1AP, "Received message: present %d and c1 present %d\n",
-      //       ul_ccch_msg->message.present, ul_ccch_msg->message.choice.c1->present);
-
-      //   if (ul_ccch_msg->message.present == NR_UL_CCCH_MessageType_PR_c1) {
-      //     if (ul_ccch_msg->message.choice.c1->present == NR_UL_CCCH_MessageType__c1_PR_rrcSetupRequest) {
-      //       LOG_I(F1AP, "[MSG] RRC Setup Request\n");
-
-      //     }
-      //   }
-      // }
-    }
-    else
-      LOG_I(F1AP, "Received message: present %d and c1 present %d\n",
-            ul_dcch_msg->message.present, ul_dcch_msg->message.choice.c1->present);
-
-    if (ul_dcch_msg->message.present == NR_UL_DCCH_MessageType_PR_c1) {
-
-      switch (ul_dcch_msg->message.choice.c1->present) {
-      case NR_UL_DCCH_MessageType__c1_PR_NOTHING:   /* No components present */
-        break;
-
-      case NR_UL_DCCH_MessageType__c1_PR_measurementReport:
-        break;
-
-      case NR_UL_DCCH_MessageType__c1_PR_rrcReconfigurationComplete:
-        LOG_I(F1AP, "[MSG] RRC UL rrcReconfigurationComplete\n");
-
-        /* CDRX: activated when RRC Connection Reconfiguration Complete is received */
-#if(0)
-        int UE_id_mac = find_nr_UE_id(instance, rnti);
-
-        if (UE_id_mac == -1) {
-          LOG_E(F1AP, "Can't find UE_id(MAC) of UE rnti %x\n", rnti);
-          break;
-        }
-
-        UE_sched_ctrl_t *UE_scheduling_control = &(RC.nrmac[instance]->UE_info.UE_sched_ctrl[UE_id_mac]);
-
-        if (UE_scheduling_control->cdrx_waiting_ack == TRUE) {
-          UE_scheduling_control->cdrx_waiting_ack = FALSE;
-          UE_scheduling_control->cdrx_configured = TRUE; // Set to TRUE when RRC Connection Reconfiguration Complete is received
-          LOG_I(F1AP, "CDRX configuration activated after RRC Connection Reconfiguration Complete reception\n");
-        }
-        /* End of CDRX processing */
-#endif
-        break;
-
-      case NR_UL_DCCH_MessageType__c1_PR_rrcSetupComplete:
-        LOG_I(F1AP, "[MSG] RRC UL rrcSetupComplete \n");
-
-        if(!ue_context_p){
-          LOG_E(F1AP, "Did not find the UE context associated with UE RNTOI %x, ue_context_p is NULL\n", rnti);
-
-        } else {
-          LOG_I(F1AP, "Processing RRCSetupComplete UE %x\n", rnti);
-          ue_context_p->ue_context.StatusRrc = NR_RRC_CONNECTED;
-        }
-        break;
-
-      case NR_UL_DCCH_MessageType__c1_PR_rrcReestablishmentComplete:
-        LOG_I(F1AP, "[MSG] RRC ReestablishmentComplete \n");
-        break;
-
-      case NR_UL_DCCH_MessageType__c1_PR_rrcResumeComplete:
-        LOG_I(F1AP, "[MSG] RRC ResumeComplete \n");
-        break;
-
-      case NR_UL_DCCH_MessageType__c1_PR_securityModeComplete:
-        LOG_I(F1AP, "[MSG] RRC securityModeComplete \n");
-        break;
-
-      case NR_UL_DCCH_MessageType__c1_PR_securityModeFailure:
-        LOG_I(F1AP, "[MSG] RRC securityModeFailure \n");
-        break;
-
-      case NR_UL_DCCH_MessageType__c1_PR_ulInformationTransfer:
-        LOG_I(F1AP, "[MSG] RRC UL Information Transfer \n");
-        break;
-
-      case NR_UL_DCCH_MessageType__c1_PR_locationMeasurementIndication:
-        break;
-
-      case NR_UL_DCCH_MessageType__c1_PR_ueCapabilityInformation:
-        LOG_I(F1AP, "[MSG] RRC ueCapabilityInformation \n");
-        break;
-
-      case NR_UL_DCCH_MessageType__c1_PR_ueAssistanceInformation:
-        break;
-
-      case NR_UL_DCCH_MessageType__c1_PR_failureInformation:
-       break;
-
-      case NR_UL_DCCH_MessageType__c1_PR_scgFailureInformation:
-        break;
-
-      case NR_UL_DCCH_MessageType__c1_PR_scgFailureInformationEUTRA:
-       break;
-
-      default:
-        LOG_E(NR_RRC, "Unknown UL DCCH message type, present %d \n", ul_dcch_msg->message.choice.c1->present);
-       break;
-      }
-    }
-  }
     /* encode */
   if (f1ap_encode_pdu(&pdu, &buffer, &len) < 0) {
     LOG_E(F1AP, "Failed to encode F1 UL RRC MESSAGE TRANSFER \n");
@@ -1252,6 +1116,7 @@ int DU_handle_DL_NR_RRC_MESSAGE_TRANSFER(instance_t       instance,
 								     RC.nrrrc[ctxt.module_id],
 								     ctxt.rnti);
 
+  gNB_RRC_INST *rrc = RC.nrrrc[ctxt.module_id];
   if (srb_id == 0) {
     NR_DL_CCCH_Message_t* dl_ccch_msg=NULL;
     asn_dec_rval_t dec_rval;
@@ -1295,47 +1160,17 @@ int DU_handle_DL_NR_RRC_MESSAGE_TRANSFER(instance_t       instance,
 			       rrcSetup_ies->masterCellGroup.size,0,0);
 	AssertFatal(dec_rval.code == RC_OK, "could not decode masterCellGroup\n");
 
-	// configure MAC
-	gNB_RRC_INST *rrc = RC.nrrrc[ctxt.module_id];
-	rrc_mac_config_req_gNB(ctxt.module_id,
-			       rrc->carrier.ssb_SubcarrierOffset,
-			       rrc->carrier.pdsch_AntennaPorts,
-			       rrc->carrier.pusch_AntennaPorts,
-			       NULL,
-			       0,
-			       ue_context_p->ue_context.rnti,
-			       ue_context_p->ue_context.masterCellGroup
-			       );
-
-	// rrc_rlc_config_asn1_req
-	nr_rrc_rlc_config_asn1_req(&ctxt,
-				   ue_context_p->ue_context.SRB_configList,
-				   NULL,
-				   NULL,
-				   NULL,
-				   NULL,
-				   NULL);
-
-      // This should be somewhere in the f1ap_cudu_ue_inst_t
-      /*int macrlc_instance = 0;
-
-      rnti_t rnti = f1ap_get_rnti_by_du_id(&f1ap_du_inst[0], du_ue_f1ap_id);
-      struct rrc_gNB_ue_context_s *ue_context_p = rrc_gNB_get_ue_context(RC.nrrrc[macrlc_instance],rnti);
-      */
-      gNB_RRC_UE_t *ue_p = &ue_context_p->ue_context;
-      AssertFatal(ue_p->Srb0.Active == 1,"SRB0 is not active\n");
+        apply_macrlc_config(rrc,ue_context_p,&ctxt);
 
-      memcpy((void*)ue_p->Srb0.Tx_buffer.Payload,
-             (void*)ie->value.choice.RRCContainer.buf,
-             rrc_dl_sdu_len); // ie->value.choice.RRCContainer.size
+        gNB_RRC_UE_t *ue_p = &ue_context_p->ue_context;
+        AssertFatal(ue_p->Srb0.Active == 1,"SRB0 is not active\n");
 
-      ue_p->Srb0.Tx_buffer.payload_size = rrc_dl_sdu_len;
+        memcpy((void*)ue_p->Srb0.Tx_buffer.Payload,
+               (void*)ie->value.choice.RRCContainer.buf,
+               rrc_dl_sdu_len); // ie->value.choice.RRCContainer.size
 
-      // NR_MAC_CellGroupConfig_t *mac_CellGroupConfig  = NULL;
-      // if (cellGroupConfig->mac_CellGroupConfig)
-      //   mac_CellGroupConfig = cellGroupConfig->mac_CellGroupConfig;
+        ue_p->Srb0.Tx_buffer.payload_size = rrc_dl_sdu_len;
 
-      // rrc_mac_config_req_gNB
           break;
       } // case
 
diff --git a/openair2/F1AP/f1ap_du_ue_context_management.c b/openair2/F1AP/f1ap_du_ue_context_management.c
index b79e9feb588077dd800c2d7791a39ebbbaa6e456..131dbce8efad12aa46f060c12ee2f51b4ba62e8a 100644
--- a/openair2/F1AP/f1ap_du_ue_context_management.c
+++ b/openair2/F1AP/f1ap_du_ue_context_management.c
@@ -38,13 +38,8 @@
 
 #include "rrc_extern.h"
 #include "rrc_eNB_UE_context.h"
-
-// undefine C_RNTI from
-// openair1/PHY/LTE_TRANSPORT/transport_common.h which
-// replaces in ie->value.choice.C_RNTI, causing
-// a compile error
-
-#undef C_RNTI
+#include "openair2/RRC/NR/rrc_gNB_UE_context.h"
+#include "openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h"
 
 extern f1ap_setup_req_t *f1ap_du_data;
 extern f1ap_cudu_inst_t f1ap_du_inst[MAX_eNB];
@@ -664,11 +659,21 @@ int DU_handle_UE_CONTEXT_RELEASE_COMMAND(instance_t       instance,
               rnti, ctxt.rnti);
   int UE_out_of_sync = 0;
 
-  for (int n = 0; n < MAX_MOBILES_PER_ENB; ++n) {
-    if (RC.mac[instance]->UE_info.active[n] == TRUE
-        && rnti == UE_RNTI(instance, n)) {
-      UE_out_of_sync = RC.mac[instance]->UE_info.UE_sched_ctrl[n].ul_out_of_sync;
-      break;
+  if (RC.nrrrc[instance]->node_type == ngran_gNB_DU) {
+    for (int n = 0; n < MAX_MOBILES_PER_GNB; ++n) {
+      if (RC.nrmac[instance]->UE_info.active[n] == TRUE
+          && rnti == RC.nrmac[instance]->UE_info.rnti[n]) {
+        UE_out_of_sync = 0;
+        break;
+      }
+    }
+  } else {
+    for (int n = 0; n < MAX_MOBILES_PER_ENB; ++n) {
+      if (RC.mac[instance]->UE_info.active[n] == TRUE
+          && rnti == UE_RNTI(instance, n)) {
+        UE_out_of_sync = RC.mac[instance]->UE_info.UE_sched_ctrl[n].ul_out_of_sync;
+        break;
+      }
     }
   }
 
@@ -718,6 +723,15 @@ int DU_handle_UE_CONTEXT_RELEASE_COMMAND(instance_t       instance,
     }
   }
 
+  if (RC.nrrrc[instance]->node_type == ngran_gNB_DU) {
+    // struct rrc_gNB_ue_context_s *ue_context_p;
+
+    f1ap_ue_context_release_cplt_t cplt;
+    cplt.rnti = ctxt.rnti;
+    DU_send_UE_CONTEXT_RELEASE_COMPLETE(instance, &cplt);
+    return 0;
+  }
+
   struct rrc_eNB_ue_context_s *ue_context_p;
 
   ue_context_p = rrc_eNB_get_ue_context(RC.rrc[ctxt.module_id], ctxt.rnti);
diff --git a/openair2/GNB_APP/L1_nr_paramdef.h b/openair2/GNB_APP/L1_nr_paramdef.h
index fd22e9273023542aa0376c551078dee85f10be80..fc2bca19d5e25718e1c464e17da62565d353b541 100644
--- a/openair2/GNB_APP/L1_nr_paramdef.h
+++ b/openair2/GNB_APP/L1_nr_paramdef.h
@@ -66,7 +66,7 @@
 {CONFIG_STRING_L1_REMOTE_N_PORTD,                    NULL,      0,         uptr:NULL,           defintval:50031,           TYPE_UINT,     0},         \
 {CONFIG_STRING_L1_PUSCH_PROC_THREADS,                NULL,      0,         uptr:NULL,           defintval:1,               TYPE_UINT,     0},         \
 {CONFIG_STRING_L1_PUCCH0_DTX_THRESHOLD,              NULL,      0,         uptr:NULL,           defintval:100,             TYPE_UINT,     0},         \
-{CONFIG_STRING_L1_PRACH_DTX_THRESHOLD,               NULL,      0,         uptr:NULL,           defintval:200,             TYPE_UINT,     0},         \
+{CONFIG_STRING_L1_PRACH_DTX_THRESHOLD,               NULL,      0,         uptr:NULL,           defintval:150,             TYPE_UINT,     0},         \
 {CONFIG_STRING_L1_PUSCH_DTX_THRESHOLD,               NULL,      0,         uptr:NULL,           defintval:50,              TYPE_UINT,     0}          \
 }
 #define L1_CC_IDX                                          0
diff --git a/openair2/GNB_APP/gnb_app.c b/openair2/GNB_APP/gnb_app.c
index 66302d056bdd75cbdd757e3cb11deb8485cad6b1..b1dc59f2e27bb816df2dd6c053955a2a9952e115 100644
--- a/openair2/GNB_APP/gnb_app.c
+++ b/openair2/GNB_APP/gnb_app.c
@@ -50,6 +50,7 @@
 #include "f1ap_cu_task.h"
 #include "f1ap_du_task.h"
 #include "nfapi/oai_integration/vendor_ext.h"
+#include <openair2/LAYER2/nr_pdcp/nr_pdcp.h>
 extern unsigned char NB_gNB_INST;
 
 extern RAN_CONTEXT_t RC;
diff --git a/openair2/GNB_APP/gnb_config.c b/openair2/GNB_APP/gnb_config.c
index 2a75e5955ee8095700893c23eb12bf6e25ade2b1..6604feca967f1ea9f584f61697cd05e658667273 100644
--- a/openair2/GNB_APP/gnb_config.c
+++ b/openair2/GNB_APP/gnb_config.c
@@ -1051,7 +1051,7 @@ void RCconfig_NRRRC(MessageDef *msg_p, uint32_t i, gNB_RRC_INST *rrc) {
           AssertFatal(0, "The number of PLMN IDs must be in [1,6], but is %d\n",
                       PLMNParamList.numelt);
 
-        RRC_CONFIGURATION_REQ(msg_p).num_plmn = PLMNParamList.numelt;
+        NRRRC_CONFIGURATION_REQ(msg_p).num_plmn = PLMNParamList.numelt;
 
         for (int l = 0; l < PLMNParamList.numelt; ++l) {
 	
diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c
index 93c6c1dbc7e5e0238177a4833d7f82b3fd903769..494f3a83eb2a2ee227ef26451f1913a13dc539f6 100644
--- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c
+++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c
@@ -2502,7 +2502,7 @@ uint8_t get_L_ptrs(uint8_t mcs1, uint8_t mcs2, uint8_t mcs3, uint8_t I_mcs, uint
 *
 * NAME :         get_K_ptrs
 *
-* PARAMETERS :   ptrs_UplinkConfig      PTRS uplink configuration
+* PARAMETERS :   nrb0, nrb1             PTRS uplink configuration
 *                N_RB                   number of RBs scheduled for PUSCH
 *
 * RETURN :       the parameter K_ptrs
diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h
index a6adb47c0a1374650d26f7fd2fd6cb05b9278ef1..d12e5b6f0a8d7d71e60eb8a5d2e9486462f55f8d 100644
--- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h
+++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h
@@ -169,4 +169,9 @@ uint8_t get_transformPrecoding(const NR_BWP_UplinkCommon_t *initialUplinkBWP,
                                int rnti_type,
                                uint8_t configuredGrant);
 
+void nr_mac_gNB_rrc_ul_failure(const module_id_t Mod_instP,
+                            const int CC_idP,
+                            const frame_t frameP,
+                            const sub_frame_t subframeP,
+                            const rnti_t rntiP) ;
 #endif
diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c
index 9e1f9debcd4fd17230680390259de079ca10f564..e7348511bbd8de3e5dc3bfaa626c1bb4515e8990 100644
--- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c
+++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c
@@ -900,7 +900,7 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fr
 							 dlsch_config_pdu_1_1->number_symbols,
                dlsch_config_pdu_1_1->start_symbol,
                mappingtype);
-    dlsch_config_pdu_1_1->dmrsConfigType = mac->DLbwp[dl_bwp_id]->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_Type == NULL ? 0 : 1;
+    dlsch_config_pdu_1_1->dmrsConfigType = mac->DLbwp[dl_bwp_id]->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->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 */
     dlsch_config_pdu_1_1->n_dmrs_cdm_groups = 1;
@@ -997,7 +997,7 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fr
 	dlsch_config_pdu_1_1->dmrs_ports[3]     = table_7_3_2_3_3_2_oneCodeword[dci->antenna_ports.val][4];
 	dlsch_config_pdu_1_1->n_front_load_symb = table_7_3_2_3_3_2_oneCodeword[dci->antenna_ports.val][5];
       }
-      if (n_codewords == 1) {
+      if (n_codewords == 2) {
 	dlsch_config_pdu_1_1->n_dmrs_cdm_groups = table_7_3_2_3_3_2_twoCodeword[dci->antenna_ports.val][0];
 	dlsch_config_pdu_1_1->dmrs_ports[0]     = table_7_3_2_3_3_2_twoCodeword[dci->antenna_ports.val][1];
 	dlsch_config_pdu_1_1->dmrs_ports[1]     = table_7_3_2_3_3_2_twoCodeword[dci->antenna_ports.val][2];
@@ -1019,7 +1019,7 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fr
 	dlsch_config_pdu_1_1->dmrs_ports[2]     = table_7_3_2_3_3_3_oneCodeword[dci->antenna_ports.val][3];
 	dlsch_config_pdu_1_1->dmrs_ports[3]     = table_7_3_2_3_3_3_oneCodeword[dci->antenna_ports.val][4];
       }
-      if (n_codewords == 1) {
+      if (n_codewords == 2) {
 	dlsch_config_pdu_1_1->n_dmrs_cdm_groups = table_7_3_2_3_3_3_twoCodeword[dci->antenna_ports.val][0];
 	dlsch_config_pdu_1_1->dmrs_ports[0]     = table_7_3_2_3_3_3_twoCodeword[dci->antenna_ports.val][1];
 	dlsch_config_pdu_1_1->dmrs_ports[1]     = table_7_3_2_3_3_3_twoCodeword[dci->antenna_ports.val][2];
@@ -1039,7 +1039,7 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fr
 	dlsch_config_pdu_1_1->dmrs_ports[3]     = table_7_3_2_3_3_4_oneCodeword[dci->antenna_ports.val][4];
 	dlsch_config_pdu_1_1->n_front_load_symb = table_7_3_2_3_3_4_oneCodeword[dci->antenna_ports.val][5];
       }
-      if (n_codewords == 1) {
+      if (n_codewords == 2) {
 	dlsch_config_pdu_1_1->n_dmrs_cdm_groups = table_7_3_2_3_3_4_twoCodeword[dci->antenna_ports.val][0];
 	dlsch_config_pdu_1_1->dmrs_ports[0]     = table_7_3_2_3_3_4_twoCodeword[dci->antenna_ports.val][1];
 	dlsch_config_pdu_1_1->dmrs_ports[1]     = table_7_3_2_3_3_4_twoCodeword[dci->antenna_ports.val][2];
@@ -2170,22 +2170,19 @@ uint16_t nr_generate_ulsch_pdu(uint8_t *sdus_payload,
                                     uint16_t buflen) {
 
   NR_MAC_SUBHEADER_FIXED *mac_pdu_ptr = (NR_MAC_SUBHEADER_FIXED *) pdu;
-  unsigned char last_size = 0, i, mac_header_control_elements[16], *ce_ptr, bsr = 0;
-  int mac_ce_size;
-  uint16_t offset = 0;
 
   LOG_D(MAC, "[UE] Generating ULSCH PDU : num_sdus %d\n", num_sdus);
 
   #ifdef DEBUG_HEADER_PARSING
 
-    for (i = 0; i < num_sdus; i++)
+    for (int i = 0; i < num_sdus; i++)
       LOG_D(MAC, "[UE] MAC subPDU %d (lcid %d length %d bytes \n", i, sdu_lcids[i], sdu_lengths[i]);
 
   #endif
 
   // Generating UL MAC subPDUs including MAC SDU and subheader
 
-  for (i = 0; i < num_sdus; i++) {
+  for (int i = 0; i < num_sdus; i++) {
     LOG_D(MAC, "[UE] Generating UL MAC subPDUs for SDU with lenght %d ( num_sdus %d )\n", sdu_lengths[i], num_sdus);
 
     if (sdu_lcids[i] != UL_SCH_LCID_CCCH){
@@ -2194,23 +2191,21 @@ uint16_t nr_generate_ulsch_pdu(uint8_t *sdus_payload,
         ((NR_MAC_SUBHEADER_SHORT *) mac_pdu_ptr)->F = 0;
         ((NR_MAC_SUBHEADER_SHORT *) mac_pdu_ptr)->LCID = sdu_lcids[i];
         ((NR_MAC_SUBHEADER_SHORT *) mac_pdu_ptr)->L = (unsigned char) sdu_lengths[i];
-        last_size = 2;
+        mac_pdu_ptr += sizeof(NR_MAC_SUBHEADER_SHORT);
       } else {
         ((NR_MAC_SUBHEADER_LONG *) mac_pdu_ptr)->R = 0;
         ((NR_MAC_SUBHEADER_LONG *) mac_pdu_ptr)->F = 1;
         ((NR_MAC_SUBHEADER_LONG *) mac_pdu_ptr)->LCID = sdu_lcids[i];
         ((NR_MAC_SUBHEADER_LONG *) mac_pdu_ptr)->L1 = ((unsigned short) sdu_lengths[i] >> 8) & 0x7f;
         ((NR_MAC_SUBHEADER_LONG *) mac_pdu_ptr)->L2 = (unsigned short) sdu_lengths[i] & 0xff;
-        last_size = 3;
+        mac_pdu_ptr += sizeof(NR_MAC_SUBHEADER_LONG);
       }
     } else { // UL CCCH SDU
-      ((NR_MAC_SUBHEADER_FIXED *) mac_pdu_ptr)->R = 0;
-      ((NR_MAC_SUBHEADER_FIXED *) mac_pdu_ptr)->LCID = sdu_lcids[i];
-      last_size = 1;
+      mac_pdu_ptr->R = 0;
+      mac_pdu_ptr->LCID = sdu_lcids[i];
+      mac_pdu_ptr ++;
     }
 
-    mac_pdu_ptr += last_size;
-
     // cycle through SDUs, compute each relevant and place ulsch_buffer in
     memcpy((void *) mac_pdu_ptr, (void *) sdus_payload, sdu_lengths[i]);
     sdus_payload += sdu_lengths[i]; 
@@ -2219,8 +2214,6 @@ uint16_t nr_generate_ulsch_pdu(uint8_t *sdus_payload,
 
   // Generating UL MAC subPDUs including MAC CEs (MAC CE and subheader)
 
-  ce_ptr = &mac_header_control_elements[0];
-
   if (power_headroom) {
     // MAC CE fixed subheader
     mac_pdu_ptr->R = 0;
@@ -2228,17 +2221,11 @@ uint16_t nr_generate_ulsch_pdu(uint8_t *sdus_payload,
     mac_pdu_ptr++;
 
     // PHR MAC CE (1 octet)
-    ((NR_SINGLE_ENTRY_PHR_MAC_CE *) ce_ptr)->PH = power_headroom;
-    ((NR_SINGLE_ENTRY_PHR_MAC_CE *) ce_ptr)->R1 = 0;
-    ((NR_SINGLE_ENTRY_PHR_MAC_CE *) ce_ptr)->PCMAX = 0; // todo
-    ((NR_SINGLE_ENTRY_PHR_MAC_CE *) ce_ptr)->R2 = 0;
-
-    mac_ce_size = sizeof(NR_SINGLE_ENTRY_PHR_MAC_CE);
-
-    // Copying bytes for PHR MAC CEs to the mac pdu pointer
-    memcpy((void *) mac_pdu_ptr, (void *) ce_ptr, mac_ce_size);
-    ce_ptr += mac_ce_size;
-    mac_pdu_ptr += (unsigned char) mac_ce_size;
+    ((NR_SINGLE_ENTRY_PHR_MAC_CE *) mac_pdu_ptr)->PH = power_headroom;
+    ((NR_SINGLE_ENTRY_PHR_MAC_CE *) mac_pdu_ptr)->R1 = 0;
+    ((NR_SINGLE_ENTRY_PHR_MAC_CE *) mac_pdu_ptr)->PCMAX = 0; // todo
+    ((NR_SINGLE_ENTRY_PHR_MAC_CE *) mac_pdu_ptr)->R2 = 0;
+    mac_pdu_ptr += sizeof(NR_SINGLE_ENTRY_PHR_MAC_CE);
   }
 
   if (crnti) {
@@ -2248,13 +2235,8 @@ uint16_t nr_generate_ulsch_pdu(uint8_t *sdus_payload,
     mac_pdu_ptr++;
 
     // C-RNTI MAC CE (2 octets)
-    * (uint16_t *) ce_ptr = crnti;
-    mac_ce_size = sizeof(uint16_t);
-
-    // Copying bytes for CRNTI MAC CE to the mac pdu pointer
-    memcpy((void *) mac_pdu_ptr, (void *) ce_ptr, mac_ce_size);
-    ce_ptr += mac_ce_size;
-    mac_pdu_ptr += (unsigned char) mac_ce_size;
+    * (uint16_t *) mac_pdu_ptr = crnti;
+    mac_pdu_ptr += sizeof(uint16_t);
   }
 
   if (truncated_bsr) {
@@ -2264,11 +2246,9 @@ uint16_t nr_generate_ulsch_pdu(uint8_t *sdus_payload,
     mac_pdu_ptr++;
 
     // Short truncated BSR MAC CE (1 octet)
-    ((NR_BSR_SHORT_TRUNCATED *) ce_ptr)-> Buffer_size = truncated_bsr;
-    ((NR_BSR_SHORT_TRUNCATED *) ce_ptr)-> LcgID = 0; // todo
-    mac_ce_size = sizeof(NR_BSR_SHORT_TRUNCATED);
-
-    bsr = 1 ;
+    ((NR_BSR_SHORT_TRUNCATED *) mac_pdu_ptr)-> Buffer_size = truncated_bsr;
+    ((NR_BSR_SHORT_TRUNCATED *) mac_pdu_ptr)-> LcgID = 0; // todo
+    mac_pdu_ptr+= sizeof(NR_BSR_SHORT_TRUNCATED);
   } else if (short_bsr) {
     // MAC CE fixed subheader
     mac_pdu_ptr->R = 0;
@@ -2276,11 +2256,9 @@ uint16_t nr_generate_ulsch_pdu(uint8_t *sdus_payload,
     mac_pdu_ptr++;
 
     // Short truncated BSR MAC CE (1 octet)
-    ((NR_BSR_SHORT *) ce_ptr)->Buffer_size = short_bsr;
-    ((NR_BSR_SHORT *) ce_ptr)->LcgID = 0; // todo
-    mac_ce_size = sizeof(NR_BSR_SHORT);
-
-    bsr = 1 ;
+    ((NR_BSR_SHORT *) mac_pdu_ptr)->Buffer_size = short_bsr;
+    ((NR_BSR_SHORT *) mac_pdu_ptr)->LcgID = 0; // todo
+     mac_pdu_ptr+= sizeof(NR_BSR_SHORT);
   } else if (long_bsr) {
     // MAC CE variable subheader
     // todo ch 6.1.3.1. TS 38.321
@@ -2296,36 +2274,21 @@ uint16_t nr_generate_ulsch_pdu(uint8_t *sdus_payload,
     // ((NR_BSR_LONG *) ce_ptr)->LCGID0 = 0;
     // mac_ce_size = sizeof(NR_BSR_LONG); // size is variable
   }
-
-  if (bsr){
-    // Copying bytes for BSR MAC CE to the mac pdu pointer
-    memcpy((void *) mac_pdu_ptr, (void *) ce_ptr, mac_ce_size);
-    ce_ptr += mac_ce_size;
-    mac_pdu_ptr += (unsigned char) mac_ce_size;
-  }
-
-  // compute offset before adding padding (if necessary)
-  offset = ((unsigned char *) mac_pdu_ptr - pdu);
-  uint16_t padding_bytes = 0; 
+// compute offset before adding padding (if necessary)
+  int padding_bytes = 0; 
 
   if(buflen > 0) // If the buflen is provided
-    padding_bytes = buflen - offset;
+    padding_bytes = buflen + pdu - (unsigned char *) mac_pdu_ptr;
+
+  AssertFatal(padding_bytes>=0,"");
 
   // Compute final offset for padding
-  if (post_padding > 0 || padding_bytes>0) {
+  if (post_padding || padding_bytes>0) {
     ((NR_MAC_SUBHEADER_FIXED *) mac_pdu_ptr)->R = 0;
     ((NR_MAC_SUBHEADER_FIXED *) mac_pdu_ptr)->LCID = UL_SCH_LCID_PADDING;
     mac_pdu_ptr++;
-  } else {            
-    // no MAC subPDU with padding
-  }
-
-  // compute final offset
-  offset = ((unsigned char *) mac_pdu_ptr - pdu);
-
-  //printf("Offset %d \n", ((unsigned char *) mac_pdu_ptr - pdu));
-
-  return offset;
+  } 
+  return (uint8_t *)mac_pdu_ptr-pdu;
 }
 
 /////////////////////////////////////
diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c
index 9ce3acd08fc49ef6a3da6eebe0b91050fe2095a9..e38d8069d420c45c9d0718709792ea0a515ff1cc 100644
--- a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c
+++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c
@@ -2017,7 +2017,9 @@ nr_ue_get_sdu(module_id_t module_idP, int CC_id, frame_t frameP,
                                 ENB_FLAG_NO,
                                 MBMS_FLAG_NO,
                                 lcid,
-                                buflen_remain,
+                                buflen_remain-MAX_RLC_SDU_SUBHEADER_SIZE,
+                                //Fixme: Laurent I removed MAX_RLC_SDU_SUBHEADER_SIZE because else we get out the buffer silently
+                                // the interface with nr_generate_ulsch_pdu() looks over complex and not CPU optimized
                                 (char *)&ulsch_sdus[sdu_length_total],0,
                                 0);
 
@@ -2037,8 +2039,7 @@ nr_ue_get_sdu(module_id_t module_idP, int CC_id, frame_t frameP,
 
         /* Get updated BO after multiplexing this PDU */
         lcid_buffer_occupancy_new = mac_rlc_get_buffer_occupancy_ind(module_idP,mac->crnti,eNB_index,frameP, subframe, ENB_FLAG_NO, lcid);
-        buflen_remain =
-                  buflen - (total_rlc_pdu_header_len + sdu_length_total + MAX_RLC_SDU_SUBHEADER_SIZE);
+        buflen_remain = buflen - (total_rlc_pdu_header_len + sdu_length_total + MAX_RLC_SDU_SUBHEADER_SIZE);
       }
     }
   }
diff --git a/openair2/LAYER2/NR_MAC_gNB/config.c b/openair2/LAYER2/NR_MAC_gNB/config.c
index 87cc7851ff2261186c6e76261812b999883ebf89..94288530373b0ac80bf4f18b9166192a8ec0daf8 100644
--- a/openair2/LAYER2/NR_MAC_gNB/config.c
+++ b/openair2/LAYER2/NR_MAC_gNB/config.c
@@ -489,12 +489,12 @@ int rrc_mac_config_req_gNB(module_id_t Mod_idP,
       /* FIXME: it seems there is a problem with slot 0/10/slots right after UL:
        * we just get retransmissions. Thus, do not schedule such slots in DL */
       if (slot % nr_slots_period != 0)
-        RC.nrmac[Mod_idP]->dlsch_slot_bitmap[slot / 64] |= ((slot % nr_slots_period) < nr_dlmix_slots) << (slot % 64);
-      RC.nrmac[Mod_idP]->ulsch_slot_bitmap[slot / 64] |= ((slot % nr_slots_period) >= nr_ulstart_slot) << (slot % 64);
+        RC.nrmac[Mod_idP]->dlsch_slot_bitmap[slot / 64] |= (uint64_t)((slot % nr_slots_period) < nr_dlmix_slots) << (slot % 64);
+      RC.nrmac[Mod_idP]->ulsch_slot_bitmap[slot / 64] |= (uint64_t)((slot % nr_slots_period) >= nr_ulstart_slot) << (slot % 64);
       LOG_D(NR_MAC, "slot %d DL %d UL %d\n",
             slot,
-            (RC.nrmac[Mod_idP]->dlsch_slot_bitmap[slot / 64] & (1 << (slot % 64))) != 0,
-            (RC.nrmac[Mod_idP]->ulsch_slot_bitmap[slot / 64] & (1 << (slot % 64))) != 0);
+            (RC.nrmac[Mod_idP]->dlsch_slot_bitmap[slot / 64] & ((uint64_t)1 << (slot % 64))) != 0,
+            (RC.nrmac[Mod_idP]->ulsch_slot_bitmap[slot / 64] & ((uint64_t)1 << (slot % 64))) != 0);
     }
 
     if (get_softmodem_params()->phy_test) {
diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c
index 52b4c5c1739119fd99983c84a35fa494f1b373fc..1d0215bb2aff8b3f64d0d66a17d58258c7f87aaf 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c
@@ -55,33 +55,58 @@
 #include "nfapi/oai_integration/vendor_ext.h"
 #include "executables/nr-softmodem.h"
 
+#include <errno.h>
+#include <string.h>
+
 uint16_t nr_pdcch_order_table[6] = { 31, 31, 511, 2047, 2047, 8191 };
 
 void clear_mac_stats(gNB_MAC_INST *gNB) {
   memset((void*)gNB->UE_info.mac_stats,0,MAX_MOBILES_PER_GNB*sizeof(NR_mac_stats_t));
 }
-
+#define MACSTATSSTRLEN 16384
 void dump_mac_stats(gNB_MAC_INST *gNB)
 {
   NR_UE_info_t *UE_info = &gNB->UE_info;
   int num = 1;
+  FILE *fd=fopen("nrMAC_stats.log","w");
+  AssertFatal(fd!=NULL,"Cannot open nrMAC_stats.log, error %s\n",strerror(errno));
+  char output[MACSTATSSTRLEN];
+  memset(output,0,MACSTATSSTRLEN);
+  int stroff=0;
   for (int UE_id = UE_info->list.head; UE_id >= 0; UE_id = UE_info->list.next[UE_id]) {
+    stroff = sprintf(output,"UE ID %d RNTI %04x (%d/%d)\n", UE_id, UE_info->rnti[UE_id], num++, UE_info->num_UEs);
     LOG_I(NR_MAC, "UE ID %d RNTI %04x (%d/%d) PH %d dB PCMAX %d dBm\n",
-          UE_id,
-          UE_info->rnti[UE_id],
-          num++,
-          UE_info->num_UEs,
-          UE_info->UE_sched_ctrl[UE_id].ph,
-          UE_info->UE_sched_ctrl[UE_id].pcmax);
+      UE_id,
+      UE_info->rnti[UE_id],
+      num++,
+      UE_info->num_UEs,
+      UE_info->UE_sched_ctrl[UE_id].ph,
+      UE_info->UE_sched_ctrl[UE_id].pcmax);
     NR_mac_stats_t *stats = &UE_info->mac_stats[UE_id];
     const int avg_rsrp = stats->num_rsrp_meas > 0 ? stats->cumul_rsrp / stats->num_rsrp_meas : 0;
-    LOG_I(NR_MAC, "UE %d: dlsch_rounds %d/%d/%d/%d, dlsch_errors %d, average RSRP %d (%d meas)\n",
+    stroff+=sprintf(output+stroff,"UE %d: dlsch_rounds %d/%d/%d/%d, dlsch_errors %d, average RSRP %d (%d meas)\n",
           UE_id,
           stats->dlsch_rounds[0], stats->dlsch_rounds[1],
           stats->dlsch_rounds[2], stats->dlsch_rounds[3], stats->dlsch_errors,
           avg_rsrp, stats->num_rsrp_meas);
+    LOG_I(NR_MAC, "UE %d: dlsch_rounds %d/%d/%d/%d, dlsch_errors %d, average RSRP %d (%d meas)\n",
+      UE_id,
+      stats->dlsch_rounds[0], stats->dlsch_rounds[1],
+      stats->dlsch_rounds[2], stats->dlsch_rounds[3], stats->dlsch_errors,
+      avg_rsrp, stats->num_rsrp_meas);
     stats->num_rsrp_meas = 0;
     stats->cumul_rsrp = 0 ;
+    stroff+=sprintf(output+stroff,"UE %d: dlsch_total_bytes %d\n", UE_id, stats->dlsch_total_bytes);
+    stroff+=sprintf(output+stroff,"UE %d: ulsch_rounds %d/%d/%d/%d, ulsch_DTX %d, ulsch_errors %d\n",
+                    UE_id,
+                    stats->ulsch_rounds[0], stats->ulsch_rounds[1],
+                    stats->ulsch_rounds[2], stats->ulsch_rounds[3],
+                    stats->ulsch_DTX,
+                    stats->ulsch_errors);
+    stroff+=sprintf(output+stroff,
+                    "UE %d: ulsch_total_bytes_scheduled %d, ulsch_total_bytes_received %d\n",
+                    UE_id,
+                    stats->ulsch_total_bytes_scheduled, stats->ulsch_total_bytes_rx);
     LOG_I(NR_MAC, "UE %d: dlsch_total_bytes %d\n", UE_id, stats->dlsch_total_bytes);
     LOG_I(NR_MAC, "UE %d: ulsch_rounds %d/%d/%d/%d, ulsch_DTX %d, ulsch_errors %d\n",
           UE_id,
@@ -95,12 +120,16 @@ void dump_mac_stats(gNB_MAC_INST *gNB)
           stats->ulsch_total_bytes_scheduled, stats->ulsch_total_bytes_rx);
     for (int lc_id = 0; lc_id < 63; lc_id++) {
       if (stats->lc_bytes_tx[lc_id] > 0)
+        stroff+=sprintf(output+stroff, "UE %d: LCID %d: %d bytes TX\n", UE_id, lc_id, stats->lc_bytes_tx[lc_id]);
         LOG_D(NR_MAC, "UE %d: LCID %d: %d bytes TX\n", UE_id, lc_id, stats->lc_bytes_tx[lc_id]);
       if (stats->lc_bytes_rx[lc_id] > 0)
+        stroff+=sprintf(output+stroff, "UE %d: LCID %d: %d bytes RX\n", UE_id, lc_id, stats->lc_bytes_rx[lc_id]);
         LOG_D(NR_MAC, "UE %d: LCID %d: %d bytes RX\n", UE_id, lc_id, stats->lc_bytes_rx[lc_id]);
     }
   }
   print_meas(&gNB->eNB_scheduler, "DL & UL scheduling timing stats", NULL, NULL);
+  if (stroff>0) fprintf(fd,"%s",output);
+  fclose(fd);
 }
 
 void clear_nr_nfapi_information(gNB_MAC_INST * gNB,
@@ -311,7 +340,7 @@ void schedule_nr_SRS(module_id_t module_idP, frame_t frameP, sub_frame_t subfram
 
 
 bool is_xlsch_in_slot(uint64_t bitmap, sub_frame_t slot) {
-  if (slot>64) return false; //quickfix for FR2 where there are more than 64 slots (bitmap to be removed)
+  if (slot>=64) return false; //quickfix for FR2 where there are more than 64 slots (bitmap to be removed)
   return (bitmap >> slot) & 0x01;
 }
 
diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c
index d881847990fb9517a5373f9572463d6214d700c0..8158e5fcca2b3c70b967db2c740a88dc9a3d5a2e 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c
@@ -215,7 +215,7 @@ void find_SSB_and_RO_available(module_id_t module_idP) {
   }
 
   cc->total_prach_occasions_per_config_period = total_RA_occasions;
-  for(int i=1; (1 << (i-1)) < max_association_period; i++) {
+  for(int i=1; (1 << (i-1)) <= max_association_period; i++) {
     cc->max_association_period = (1 <<(i-1));
     total_RA_occasions = total_RA_occasions * cc->max_association_period;
     if(total_RA_occasions >= (int) (num_active_ssb/num_ssb_per_RO)) {
@@ -697,28 +697,34 @@ void nr_get_Msg3alloc(module_id_t module_id,
     int mu = ubwp ?
       ubwp->bwp_Common->genericParameters.subcarrierSpacing :
       scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.subcarrierSpacing;
-    int StartSymbolIndex, NrOfSymbols, startSymbolAndLength, temp_slot;
+    int StartSymbolIndex = 0;
+    int NrOfSymbols = 0;
+    int startSymbolAndLength = 0;
+    int temp_slot = 0;
     ra->Msg3_tda_id = 16; // initialization to a value above limit
 
     NR_PUSCH_TimeDomainResourceAllocationList_t *pusch_TimeDomainAllocationList= ubwp ?
       ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList:
       scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList;
 
+    uint8_t k2 = 0;
     for (int i=0; i<pusch_TimeDomainAllocationList->list.count; i++) {
       startSymbolAndLength = pusch_TimeDomainAllocationList->list.array[i]->startSymbolAndLength;
       SLIV2SL(startSymbolAndLength, &StartSymbolIndex, &NrOfSymbols);
       // we want to transmit in the uplink symbols of mixed slot
       if (NrOfSymbols == scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSymbols) {
-        ra->Msg3_tda_id = i;
-        break;
+        k2 = *pusch_TimeDomainAllocationList->list.array[i]->k2;
+        temp_slot = current_slot + k2 + DELTA[mu]; // msg3 slot according to 8.3 in 38.213
+        ra->Msg3_slot = temp_slot%nr_slots_per_frame[mu];
+        if (is_xlsch_in_slot(RC.nrmac[module_id]->ulsch_slot_bitmap[ra->Msg3_slot / 64], ra->Msg3_slot)) {
+          ra->Msg3_tda_id = i;
+          break;
+        }
       }
     }
-    AssertFatal(ra->Msg3_tda_id<16,"Unable to find Msg3 time domain allocation in list\n");
 
-    uint8_t k2 = *pusch_TimeDomainAllocationList->list.array[ra->Msg3_tda_id]->k2;
+    AssertFatal(ra->Msg3_tda_id<16,"Unable to find Msg3 time domain allocation in list\n");
 
-    temp_slot = current_slot + k2 + DELTA[mu]; // msg3 slot according to 8.3 in 38.213
-    ra->Msg3_slot = temp_slot%nr_slots_per_frame[mu];
     if (nr_slots_per_frame[mu]>temp_slot)
       ra->Msg3_frame = current_frame;
     else
diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c
index 8b12742fccef1ad5fc66c4f71ad2d5602ee04433..fbd08f18c48297f04f2e54f2ca4e2aa1de161b81 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c
@@ -157,10 +157,14 @@ void schedule_nr_mib(module_id_t module_idP, frame_t frameP, sub_frame_t slotP)
     dl_req = &dl_tti_request->dl_tti_request_body;
 
     // get MIB every 8 frames
-    if((slotP == 0) && (frameP & 7) == 0) {
+    if(((slotP == 0) && (frameP & 7) == 0) ||
+       gNB->first_MIB) {
 
       mib_sdu_length = mac_rrc_nr_data_req(module_idP, CC_id, frameP, MIBCH, 0, 1, &cc->MIB_pdu.payload[0]);
 
+      // flag to avoid sending an empty MIB in the first frames of execution since gNB doesn't get at the beginning in frame 0 slot 0
+      gNB->first_MIB = false;
+
       LOG_D(MAC,
             "[gNB %d] Frame %d : MIB->BCH  CC_id %d, Received %d bytes\n",
             module_idP,
diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c
index 47614ed8c0743810d4b7eaa9699fdc38c3a2a4d4..93d2e959ddf4857935edd61e98b407aa25fc724e 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c
@@ -551,7 +551,7 @@ bool allocate_dl_retransmission(module_id_t module_id,
 }
 
 float thr_ue[MAX_MOBILES_PER_GNB];
-uint32_t pf_tbs[3][28]; // pre-computed, approximate TBS values for PF coefficient
+uint32_t pf_tbs[3][29]; // pre-computed, approximate TBS values for PF coefficient
 
 void pf_dl(module_id_t module_id,
            frame_t frame,
@@ -573,6 +573,7 @@ void pf_dl(module_id_t module_id,
   for (int UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) {
     if (UE_info->Msg4_ACKed[UE_id] != true) continue;
     NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
+    if (sched_ctrl->ul_failure==1 && get_softmodem_params()->phy_test==0) continue;
     NR_sched_pdsch_t *sched_pdsch = &sched_ctrl->sched_pdsch;
     NR_pdsch_semi_static_t *ps = &sched_ctrl->pdsch_semi_static;
     /* get the PID of a HARQ process awaiting retrnasmission, or -1 otherwise */
@@ -602,6 +603,7 @@ void pf_dl(module_id_t module_id,
 
       /* Calculate coeff */
       sched_pdsch->mcs = 9;
+      sched_pdsch->nrOfLayers = 1;
       uint32_t tbs = pf_tbs[ps->mcsTableIdx][sched_pdsch->mcs];
       coeff_ue[UE_id] = (float) tbs / thr_ue[UE_id];
       LOG_D(NR_MAC,"b %d, thr_ue[%d] %f, tbs %d, coeff_ue[%d] %f\n",
@@ -690,8 +692,7 @@ void pf_dl(module_id_t module_id,
     sched_pdsch->pucch_allocation = alloc;
     uint32_t TBS = 0;
     uint16_t rbSize;
-    const int oh = 2 + (sched_ctrl->num_total_bytes >= 256)
-                 + 2 * (frame == (sched_ctrl->ta_frame + 10) % 1024);
+    const int oh = 3 + 2 * (frame == (sched_ctrl->ta_frame + 10) % 1024);
     nr_find_nb_rb(sched_pdsch->Qm,
                   sched_pdsch->R,
                   ps->nrOfSymbols,
@@ -820,7 +821,7 @@ void nr_schedule_ue_spec(module_id_t module_id,
     const rnti_t rnti = UE_info->rnti[UE_id];
 
     /* POST processing */
-    const int nrOfLayers = 1;
+    const uint8_t nrOfLayers = sched_pdsch->nrOfLayers;
     const uint16_t R = sched_pdsch->R;
     const uint8_t Qm = sched_pdsch->Qm;
     const uint32_t TBS = sched_pdsch->tb_size;
diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c
index 1dda52b56719cd6e0237da0ddd9068ecd423dcbb..50a0b241b66080cab7a4b49099dd53eb55499a64 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c
@@ -146,7 +146,7 @@ void nr_schedule_css_dlsch_phytest(module_id_t   module_idP,
     int startSymbolAndLength=0;
     int StartSymbolIndex=-1,NrOfSymbols=14;
     int StartSymbolIndex_tmp,NrOfSymbols_tmp;
-    int mappingtype_tmp, mappingtype;
+    int mappingtype_tmp, mappingtype=0;
 
     for (int i=0;
 	 i<scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.count;
@@ -262,6 +262,7 @@ void nr_schedule_css_dlsch_phytest(module_id_t   module_idP,
 extern int getNrOfSymbols(NR_BWP_Downlink_t *bwp, int tda);
 extern uint8_t getN_PRB_DMRS(NR_BWP_Downlink_t *bwp, int numDmrsCdmGrpsNoData);
 uint32_t target_dl_mcs = 9;
+uint32_t target_dl_Nl = 1;
 uint32_t target_dl_bw = 50;
 uint64_t dlsch_slot_bitmap = (1<<1);
 /* schedules whole bandwidth for first user, all the time */
@@ -286,6 +287,8 @@ void nr_preprocessor_phytest(module_id_t module_id,
   target_dl_bw = (bwpSize < target_dl_bw) ?bwpSize : target_dl_bw;
   int rbStart = 0;
   int rbSize = 0;
+  if (target_dl_bw>bwpSize)
+    target_dl_bw = bwpSize;
   uint16_t *vrb_map = RC.nrmac[module_id]->common_channels[CC_id].vrb_map;
   /* loop ensures that we allocate exactly target_dl_bw, or return */
   while (true) {
@@ -372,6 +375,7 @@ void nr_preprocessor_phytest(module_id_t module_id,
     nr_set_pdsch_semi_static(
         scc, UE_info->CellGroup[UE_id], sched_ctrl->active_bwp, tda, num_dmrs_cdm_grps_no_data, ps);
 
+  sched_pdsch->nrOfLayers = target_dl_Nl;
   sched_pdsch->mcs = target_dl_mcs;
   sched_pdsch->Qm = nr_get_Qm_dl(sched_pdsch->mcs, ps->mcsTableIdx);
   sched_pdsch->R = nr_get_code_rate_dl(sched_pdsch->mcs, ps->mcsTableIdx);
@@ -382,7 +386,7 @@ void nr_preprocessor_phytest(module_id_t module_id,
                                         ps->N_PRB_DMRS * ps->N_DMRS_SLOT,
                                         0 /* N_PRB_oh, 0 for initialBWP */,
                                         0 /* tb_scaling */,
-                                        1 /* nrOfLayers */)
+                                        sched_pdsch->nrOfLayers)
                          >> 3;
 
   /* get the PID of a HARQ process awaiting retransmission, or -1 otherwise */
@@ -391,6 +395,8 @@ void nr_preprocessor_phytest(module_id_t module_id,
   /* mark the corresponding RBs as used */
   for (int rb = 0; rb < sched_pdsch->rbSize; rb++)
     vrb_map[rb + sched_pdsch->rbStart] = 1;
+
+  if ((frame&127) == 0) LOG_D(MAC,"phytest: %d.%d DL mcs %d, DL rbStart %d, DL rbSize %d\n", frame, slot, sched_pdsch->mcs, rbStart,rbSize);
 }
 
 uint32_t target_ul_mcs = 9;
diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c
index 83e96c9bb945408a4c3d8c06e7e9699216ad4bb0..04ac9ea1f1b0b32eac1ebd4cc902a4b068107013 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c
@@ -600,7 +600,7 @@ 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,
-		              const NR_ServingCellConfigCommon_t *scc,
+                  const NR_ServingCellConfigCommon_t *scc,
                   const nfapi_nr_pusch_pdu_t *pusch_pdu,
                   dci_pdu_rel15_t *dci_pdu_rel15,
                   int dci_format,
@@ -611,6 +611,7 @@ void config_uldci(const NR_BWP_Uplink_t *ubwp,
   const int bw = NRRIV2BW(ubwp ?
 			  ubwp->bwp_Common->genericParameters.locationAndBandwidth :
 			  scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
+
   dci_pdu_rel15->frequency_domain_assignment.val =
       PRBalloc_to_locationandbandwidth0(pusch_pdu->rb_size, pusch_pdu->rb_start, bw);
   dci_pdu_rel15->time_domain_assignment.val = time_domain_assignment;
@@ -673,6 +674,7 @@ int nr_get_default_pucch_res(int pucch_ResourceCommon) {
 
   return(default_pucch_csset[pucch_ResourceCommon]);
 }
+
 void nr_configure_pdcch(nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu,
                         NR_SearchSpace_t *ss,
                         NR_ControlResourceSet_t *coreset,
@@ -739,15 +741,15 @@ void nr_configure_pdcch(nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu,
 
 // This function configures pucch pdu fapi structure
 void nr_configure_pucch(nfapi_nr_pucch_pdu_t* pucch_pdu,
-			                  NR_ServingCellConfigCommon_t *scc,
-			                  NR_CellGroupConfig_t *CellGroup,
-			                  NR_BWP_Uplink_t *bwp,
+                        NR_ServingCellConfigCommon_t *scc,
+                        NR_CellGroupConfig_t *CellGroup,
+                        NR_BWP_Uplink_t *bwp,
                         uint16_t rnti,
                         uint8_t pucch_resource,
                         uint16_t O_csi,
                         uint16_t O_ack,
                         uint8_t O_sr,
-			                  int r_pucch) {
+                        int r_pucch) {
 
   NR_PUCCH_Config_t *pucch_Config;
   NR_PUCCH_Resource_t *pucchres;
diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c
index 3effe300abef5731eddc2198dc4b630e74f55aa8..17c7bb92eba7a683ea431f627a91c3a984809dd0 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c
@@ -144,7 +144,7 @@ void calculate_preferred_ul_tda(module_id_t module_id, const NR_BWP_Uplink_t *ub
   if ((symb_pucch & symb_tda_mi) == 0 && (symb_ulMixed & symb_tda_mi) == symb_tda_mi) {
     tdaMi = 1;
   } else {
-    LOG_E(MAC,
+    LOG_E(NR_MAC,
           "TDA index 1 UL overlaps with PUCCH or is not entirely in mixed slot (symb_pucch %x symb_ulMixed %x symb_tda_mi %x), won't schedule UL mixed slot\n",
           symb_pucch,
           symb_ulMixed,
@@ -168,7 +168,7 @@ void calculate_preferred_ul_tda(module_id_t module_id, const NR_BWP_Uplink_t *ub
   }
 
   if (k2 < tdd->nrofUplinkSlots)
-    LOG_W(MAC,
+    LOG_W(NR_MAC,
           "k2 %d < tdd->nrofUplinkSlots %ld: not all UL slots can be scheduled\n",
           k2,
           tdd->nrofUplinkSlots);
@@ -192,6 +192,10 @@ void nr_process_mac_pdu(module_id_t module_idP,
 
     NR_UE_info_t *UE_info = &RC.nrmac[module_idP]->UE_info;
     NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
+
+    if ( pduP[0] != UL_SCH_LCID_PADDING )
+      trace_NRpdu(DIRECTION_UPLINK, pduP, mac_pdu_len ,UE_id, WS_C_RNTI, UE_info->rnti[UE_id], frameP, 0, 0, 0);
+
     //  For both DL/UL-SCH
     //  Except:
     //   - UL/DL-SCH: fixed-size MAC CE(known by LCID)
@@ -327,7 +331,7 @@ void nr_process_mac_pdu(module_id_t module_idP,
         	  sched_ctrl->ph = PH - 32 + (PH - 54);
         	/* 38.133 Table10.1.18.1-1 */
         	sched_ctrl->pcmax = PCMAX - 29;
-        	LOG_D(MAC, "SINGLE ENTRY PHR R1 %d PH %d (%d dB) R2 %d PCMAX %d (%d dBm)\n",
+        	LOG_D(NR_MAC, "SINGLE ENTRY PHR R1 %d PH %d (%d dB) R2 %d PCMAX %d (%d dBm)\n",
                       phr->R1, PH, sched_ctrl->ph, phr->R2, PCMAX, sched_ctrl->pcmax);
         	break;
 
@@ -371,7 +375,7 @@ void nr_process_mac_pdu(module_id_t module_idP,
             mac_sdu_len = (uint16_t)((NR_MAC_SUBHEADER_SHORT *)pdu_ptr)->L;
             mac_subheader_len = 2;
           }
-          LOG_D(NR_MAC, "[UE %d] Frame %d : ULSCH -> UL-DCCH %d (gNB %d, %d bytes), rnti: %d \n", module_idP, frameP, rx_lcid, module_idP, mac_sdu_len, *UE_info->rnti);
+          LOG_D(NR_MAC, "[UE %d] Frame %d : ULSCH -> UL-DCCH %d (gNB %d, %d bytes), rnti: %d \n", module_idP, frameP, rx_lcid, module_idP, mac_sdu_len, UE_info->rnti[UE_id]);
           mac_rlc_data_ind(module_idP,
                            UE_info->rnti[UE_id],
                            module_idP,
@@ -664,6 +668,7 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP,
       if (UE_info->UE_sched_ctrl[UE_id].pusch_consecutive_dtx_cnt >= pusch_failure_thres) {
          LOG_D(NR_MAC,"Detected UL Failure on PUSCH, stopping scheduling\n");
          UE_info->UE_sched_ctrl[UE_id].ul_failure = 1;
+         nr_mac_gNB_rrc_ul_failure(gnb_mod_idP,CC_idP,frameP,slotP,rntiP);
       }
     }
   } else if(sduP) {
@@ -812,7 +817,7 @@ bool nr_UE_is_to_be_scheduled(module_id_t mod_id, int CC_id, int UE_id, frame_t
    * (3) or we did not schedule it in more than 10 frames */
   const bool has_data = sched_ctrl->estimated_ul_buffer > sched_ctrl->sched_ul_bytes;
   const bool high_inactivity = diff >= nrmac->ulsch_max_slots_inactivity;
-  LOG_D(MAC,
+  LOG_D(NR_MAC,
         "%4d.%2d UL inactivity %d slots has_data %d SR %d\n",
         frame,
         slot,
@@ -842,29 +847,20 @@ bool allocate_ul_retransmission(module_id_t module_id,
   NR_UE_info_t *UE_info = &RC.nrmac[module_id]->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_sched_pusch_t *sched_pusch = &sched_ctrl->sched_pusch;
-
-  // frame/slot in sched_pusch has been set previously. In the following, we
-  // overwrite the information in the retransmission information before storing
-  // as the new scheduling instruction
-  retInfo->frame = sched_ctrl->sched_pusch.frame;
-  retInfo->slot = sched_ctrl->sched_pusch.slot;
-
-  // Get previous PUSCH filed info
-  sched_ctrl->sched_pusch = *retInfo;
 
   NR_BWP_t *genericParameters = sched_ctrl->active_ubwp ? &sched_ctrl->active_ubwp->bwp_Common->genericParameters : &scc->uplinkConfigCommon->initialUplinkBWP->genericParameters;
   int rbStart = sched_ctrl->active_ubwp ? NRRIV2PRBOFFSET(genericParameters->locationAndBandwidth, MAX_BWP_SIZE) : 0;
   const uint16_t bwpSize = NRRIV2BW(genericParameters->locationAndBandwidth, MAX_BWP_SIZE);
 
   const uint8_t num_dmrs_cdm_grps_no_data = sched_ctrl->active_bwp ? 1 : 2;
-  const int tda = sched_ctrl->active_ubwp ? RC.nrmac[module_id]->preferred_ul_tda[sched_ctrl->active_ubwp->bwp_Id][slot] : 1;
+  const int tda = sched_ctrl->active_ubwp ? RC.nrmac[module_id]->preferred_ul_tda[sched_ctrl->active_ubwp->bwp_Id][slot] : 0;
+  LOG_D(NR_MAC,"retInfo->time_domain_allocation = %d, tda = %d\n", retInfo->time_domain_allocation, tda);
   if (tda == retInfo->time_domain_allocation) {
     /* Check the resource is enough for retransmission */
     while (rbStart < bwpSize && !rballoc_mask[rbStart])
       rbStart++;
-    if (rbStart + retInfo->rbSize >= bwpSize) {
-      LOG_D(MAC, "cannot allocate retransmission of UE %d/RNTI %04x: no resources\n", UE_id, UE_info->rnti[UE_id]);
+    if (rbStart + retInfo->rbSize > bwpSize) {
+      LOG_W(NR_MAC, "cannot allocate retransmission of UE %d/RNTI %04x: no resources (rbStart %d, retInfo->rbSize %d, bwpSize %d\n", UE_id, UE_info->rnti[UE_id], rbStart, retInfo->rbSize, bwpSize);
       return false;
     }
     /* check whether we need to switch the TDA allocation since tha last
@@ -876,7 +872,7 @@ 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)
       nr_set_pusch_semi_static(scc, sched_ctrl->active_ubwp, dci_format, tda, num_dmrs_cdm_grps_no_data, ps);
-    LOG_D(MAC, "%s(): retransmission keeping TDA %d and TBS %d\n", __func__, tda, retInfo->tb_size);
+    LOG_D(NR_MAC, "%s(): retransmission keeping TDA %d and TBS %d\n", __func__, tda, retInfo->tb_size);
   } else {
     /* the retransmission will use a different time domain allocation, check
      * that we have enough resources */
@@ -900,10 +896,10 @@ bool allocate_ul_retransmission(module_id_t module_id,
                                  &new_tbs,
                                  &new_rbSize);
     if (!success || new_tbs != retInfo->tb_size) {
-      LOG_D(MAC, "%s(): new TBsize %d of new TDA does not match old TBS %d\n", __func__, new_tbs, retInfo->tb_size);
+      LOG_D(NR_MAC, "%s(): new TBsize %d of new TDA does not match old TBS %d\n", __func__, new_tbs, retInfo->tb_size);
       return false; /* the maximum TBsize we might have is smaller than what we need */
     }
-    LOG_D(MAC, "%s(): retransmission with TDA %d->%d and TBS %d -> %d\n", __func__, retInfo->time_domain_allocation, tda, retInfo->tb_size, new_tbs);
+    LOG_D(NR_MAC, "%s(): retransmission with TDA %d->%d and TBS %d -> %d\n", __func__, retInfo->time_domain_allocation, tda, retInfo->tb_size, new_tbs);
     /* we can allocate it. Overwrite the time_domain_allocation, the number
      * of RBs, and the new TB size. The rest is done below */
     retInfo->tb_size = new_tbs;
@@ -915,11 +911,20 @@ bool allocate_ul_retransmission(module_id_t module_id,
   /* Find free CCE */
   bool freeCCE = find_free_CCE(module_id, slot, UE_id);
   if (!freeCCE) {
-    LOG_D(MAC, "%4d.%2d no free CCE for retransmission UL DCI UE %04x\n", frame, slot, UE_info->rnti[UE_id]);
+    LOG_D(NR_MAC, "%4d.%2d no free CCE for retransmission UL DCI UE %04x\n", frame, slot, UE_info->rnti[UE_id]);
     return false;
   }
 
-  LOG_D(MAC,
+  /* frame/slot in sched_pusch has been set previously. In the following, we
+   * overwrite the information in the retransmission information before storing
+   * as the new scheduling instruction */
+  retInfo->frame = sched_ctrl->sched_pusch.frame;
+  retInfo->slot = sched_ctrl->sched_pusch.slot;
+  /* Get previous PSUCH field info */
+  sched_ctrl->sched_pusch = *retInfo;
+  NR_sched_pusch_t *sched_pusch = &sched_ctrl->sched_pusch;
+
+  LOG_D(NR_MAC,
         "%4d.%2d Allocate UL retransmission UE %d/RNTI %04x sched %4d.%2d (%d RBs)\n",
         frame,
         slot,
@@ -952,7 +957,7 @@ void update_ul_ue_R_Qm(NR_sched_pusch_t *sched_pusch, const NR_pusch_semi_static
 }
 
 float ul_thr_ue[MAX_MOBILES_PER_GNB];
-uint32_t ul_pf_tbs[3][28]; // pre-computed, approximate TBS values for PF coefficient
+uint32_t ul_pf_tbs[3][29]; // pre-computed, approximate TBS values for PF coefficient
 void pf_ul(module_id_t module_id,
            frame_t frame,
            sub_frame_t slot,
@@ -995,7 +1000,7 @@ void pf_ul(module_id_t module_id,
       bool r = allocate_ul_retransmission(
           module_id, frame, slot, rballoc_mask, &n_rb_sched, UE_id, sched_pusch->ul_harq_pid);
       if (!r) {
-        LOG_D(MAC, "%4d.%2d UL retransmission UE RNTI %04x can NOT be allocated\n", frame, slot, UE_info->rnti[UE_id]);
+        LOG_D(NR_MAC, "%4d.%2d UL retransmission UE RNTI %04x can NOT be allocated\n", frame, slot, UE_info->rnti[UE_id]);
         continue;
       }
       /* reduce max_num_ue once we are sure UE can be allocated, i.e., has CCE */
@@ -1026,7 +1031,7 @@ void pf_ul(module_id_t module_id,
       if (max_num_ue < 0)
         return;
 
-      LOG_D(NR_MAC,"Looking for min_rb %d RBs, starting at %d\n", min_rb,rbStart);
+      LOG_D(NR_MAC,"Looking for min_rb %d RBs, starting at %d\n", min_rb, rbStart);
       while (rbStart < bwpSize && !rballoc_mask[rbStart]) rbStart++;
       if (rbStart + min_rb >= bwpSize) {
         LOG_W(NR_MAC, "cannot allocate continuous UL data for UE %d/RNTI %04x: no resources (rbStart %d, min_rb %d, bwpSize %d\n",
@@ -1041,7 +1046,7 @@ void pf_ul(module_id_t module_id,
       const uint8_t num_dmrs_cdm_grps_no_data = sched_ctrl->active_ubwp ? 1 : 2;
       const long f = sched_ctrl->search_space->searchSpaceType->choice.ue_Specific->dci_Formats;
       const int dci_format = sched_ctrl->active_ubwp ? (f ? NR_UL_DCI_FORMAT_0_1 : NR_UL_DCI_FORMAT_0_0) : NR_UL_DCI_FORMAT_0_0;
-      const int tda = sched_ctrl->active_ubwp ? nrmac->preferred_ul_tda[sched_ctrl->active_ubwp->bwp_Id][slot] : 1;
+      const int tda = sched_ctrl->active_ubwp ? nrmac->preferred_ul_tda[sched_ctrl->active_ubwp->bwp_Id][slot] : 0;
       if (ps->time_domain_allocation != tda
           || ps->dci_format != dci_format
           || ps->num_dmrs_cdm_grps_no_data != num_dmrs_cdm_grps_no_data)
@@ -1137,7 +1142,7 @@ void pf_ul(module_id_t module_id,
     const uint8_t num_dmrs_cdm_grps_no_data = sched_ctrl->active_ubwp ? 1 : 2;
     const long f = sched_ctrl->search_space->searchSpaceType->choice.ue_Specific->dci_Formats;
     const int dci_format = sched_ctrl->active_ubwp ? (f ? NR_UL_DCI_FORMAT_0_1 : NR_UL_DCI_FORMAT_0_0) : NR_UL_DCI_FORMAT_0_0;
-    const int tda = sched_ctrl->active_ubwp ? nrmac->preferred_ul_tda[sched_ctrl->active_ubwp->bwp_Id][slot] : 1;
+    const int tda = sched_ctrl->active_ubwp ? nrmac->preferred_ul_tda[sched_ctrl->active_ubwp->bwp_Id][slot] : 0;
     if (ps->time_domain_allocation != tda
         || ps->dci_format != dci_format
         || ps->num_dmrs_cdm_grps_no_data != num_dmrs_cdm_grps_no_data)
@@ -1158,7 +1163,7 @@ void pf_ul(module_id_t module_id,
                   &rbSize);
     sched_pusch->rbSize = rbSize;
     sched_pusch->tb_size = TBS;
-    LOG_D(MAC,"rbSize %d, TBS %d, est buf %d, sched_ul %d, B %d\n",
+    LOG_D(NR_MAC,"rbSize %d, TBS %d, est buf %d, sched_ul %d, B %d\n",
           rbSize, sched_pusch->tb_size, sched_ctrl->estimated_ul_buffer, sched_ctrl->sched_ul_bytes, B);
 
     /* Mark the corresponding RBs as used */
@@ -1187,15 +1192,23 @@ bool nr_fr1_ulsch_preprocessor(module_id_t module_id, frame_t frame, sub_frame_t
    * schedule now (slot + k2 is not UL slot) */
   int UE_id = UE_info->list.head;
   NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
-  const int tda = sched_ctrl->active_ubwp ? nr_mac->preferred_ul_tda[sched_ctrl->active_ubwp->bwp_Id][slot] : 1;
+  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);
   const int sched_frame = frame + (slot + K2 >= nr_slots_per_frame[mu]);
   const int sched_slot = (slot + K2) % nr_slots_per_frame[mu];
+
   if (!is_xlsch_in_slot(nr_mac->ulsch_slot_bitmap[sched_slot / 64], sched_slot))
     return false;
 
+  bool is_mixed_slot = is_xlsch_in_slot(nr_mac->dlsch_slot_bitmap[sched_slot / 64], sched_slot) &&
+                        is_xlsch_in_slot(nr_mac->ulsch_slot_bitmap[sched_slot / 64], sched_slot);
+
+  // FIXME: Avoid mixed slots for initialUplinkBWP
+  if (sched_ctrl->active_ubwp==NULL && is_mixed_slot)
+    return false;
+
   sched_ctrl->sched_pusch.slot = sched_slot;
   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]) {
@@ -1575,7 +1588,7 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot)
       n_ubwp = CellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList->list.count;
 
     config_uldci(sched_ctrl->active_ubwp,
-		             scc,
+                 scc,
                  pusch_pdu,
                  &uldci_payload,
                  ps->dci_format,
diff --git a/openair2/LAYER2/NR_MAC_gNB/main.c b/openair2/LAYER2/NR_MAC_gNB/main.c
index 9974c08a18a94275dcda1bc52ecc9e80467b9a96..117c18ae8da3784749948cc18daed5f6a5ca028f 100644
--- a/openair2/LAYER2/NR_MAC_gNB/main.c
+++ b/openair2/LAYER2/NR_MAC_gNB/main.c
@@ -81,6 +81,8 @@ void mac_top_init_gNB(void)
         
       RC.nrmac[i]->ul_handle = 0;
 
+      RC.nrmac[i]->first_MIB = true;
+
       if (get_softmodem_params()->phy_test) {
         RC.nrmac[i]->pre_processor_dl = nr_preprocessor_phytest;
         RC.nrmac[i]->pre_processor_ul = nr_ul_preprocessor_phytest;
diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h
index 1f9cfff1e8354e0e571fc1f1a5834bc520d1989e..ec98e61060e5b6655ee5ccf50b80454adf93bb37 100644
--- a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h
+++ b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h
@@ -383,6 +383,7 @@ typedef struct NR_sched_pdsch {
   uint8_t mcs;
 
   /// TBS-related info
+  uint8_t nrOfLayers;
   uint16_t R;
   uint8_t Qm;
   uint32_t tb_size;
@@ -747,6 +748,7 @@ typedef struct gNB_MAC_INST_s {
   NR_UE_sched_ctrl_t *sched_ctrlCommon;
   NR_Type0_PDCCH_CSS_config_t type0_PDCCH_CSS_config[64];
 
+  bool first_MIB;
 } gNB_MAC_INST;
 
 #endif /*__LAYER2_NR_MAC_GNB_H__ */
diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c
index 1624c395efc3abc04d4a9604f8ffaf64314c109b..60788826017a44ba2ff0609d04a87c9bb1ebe256 100644
--- a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c
+++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c
@@ -445,7 +445,8 @@ static void deliver_sdu_drb(void *_ue, nr_pdcp_entity_t *entity,
   int rb_id;
   int i;
 
-  if(IS_SOFTMODEM_NOS1){
+  if(IS_SOFTMODEM_NOS1 || UE_NAS_USE_TUN){
+    LOG_D(PDCP, "IP packet received, to be sent to TUN interface");
     len = write(nas_sock_fd[0], buf, size);
     if (len != size) {
       LOG_E(PDCP, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__);
@@ -534,7 +535,7 @@ static void deliver_sdu_srb(void *_ue, nr_pdcp_entity_t *entity,
   int srb_id;
   int i;
 
-  for (i = 0; i < 2; i++) {
+  for (i = 0; i < sizeofArray(ue->srb) ; i++) {
     if (entity == ue->srb[i]) {
       srb_id = i+1;
       goto srb_found;
@@ -577,7 +578,7 @@ static void deliver_pdu_srb(void *_ue, nr_pdcp_entity_t *entity,
   int i;
   mem_block_t *memblock;
 
-  for (i = 0; i < 2; i++) {
+  for (i = 0; i < sizeofArray(ue->srb) ; i++) {
     if (entity == ue->srb[i]) {
       srb_id = i+1;
       goto srb_found;
@@ -896,13 +897,14 @@ boolean_t nr_rrc_pdcp_config_asn1_req(
       //ctxt_pP->configured != 2 ||
       //srb2add_list == NULL ||
       //drb2add_list != NULL ||
-      drb2release_list != NULL ||
+      //drb2release_list != NULL ||
       //security_modeP != 255 ||
       //kRRCenc != NULL ||
       //kRRCint != NULL ||
       //kUPenc != NULL ||
       pmch_InfoList_r9 != NULL /*||
       defaultDRB != NULL */) {
+    LOG_I(PDCP,"Releasing DRBs, oops\n");
     TODO;
   }
 
@@ -926,6 +928,10 @@ boolean_t nr_rrc_pdcp_config_asn1_req(
     /* todo */
   }
 
+  if (drb2release_list != NULL) {
+    // TODO
+  }
+
   free(kRRCenc);
   free(kRRCint);
   free(kUPenc);
@@ -1189,6 +1195,7 @@ static boolean_t pdcp_data_req_drb(
   if (rb == NULL) {
     LOG_E(PDCP, "%s:%d:%s: no DRB found (rnti %d, rb_id %ld)\n",
           __FILE__, __LINE__, __FUNCTION__, rnti, rb_id);
+    nr_pdcp_manager_unlock(nr_pdcp_ue_manager);
     return 0;
   }
 
diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_ue_manager.h b/openair2/LAYER2/nr_pdcp/nr_pdcp_ue_manager.h
index 3329f856b7fb04a1f710b7ee95bc4276130547fa..742e0e84be8c67f0e1a109a95e32879f2884ce9d 100644
--- a/openair2/LAYER2/nr_pdcp/nr_pdcp_ue_manager.h
+++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_ue_manager.h
@@ -28,7 +28,7 @@ typedef void nr_pdcp_ue_manager_t;
 
 typedef struct nr_pdcp_ue_t {
   int rnti;
-  nr_pdcp_entity_t *srb[2];
+  nr_pdcp_entity_t *srb[3];
   nr_pdcp_entity_t *drb[5];
 } nr_pdcp_ue_t;
 
diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_entity_am.c b/openair2/LAYER2/nr_rlc/nr_rlc_entity_am.c
index 000c764e8f1c31b8752aa35d33fa3a67722f2cc2..08f5b11c23197f47587d5f8801cd8c875dd211df 100644
--- a/openair2/LAYER2/nr_rlc/nr_rlc_entity_am.c
+++ b/openair2/LAYER2/nr_rlc/nr_rlc_entity_am.c
@@ -1529,7 +1529,7 @@ static int tx_list_size(nr_rlc_entity_am_t *entity,
 {
   int ret = 0;
 
-  while (l != NULL) {
+  while (l != NULL && ret < maxsize) {
     ret += compute_pdu_header_size(entity, l) + l->size;
     l = l->next;
   }
diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_entity_um.c b/openair2/LAYER2/nr_rlc/nr_rlc_entity_um.c
index 4ef952667dc84be0c6de1b219c5cf5f37833558e..f967c3c5432a9832768ea4ceb22a0083eecbc0ff 100644
--- a/openair2/LAYER2/nr_rlc/nr_rlc_entity_um.c
+++ b/openair2/LAYER2/nr_rlc/nr_rlc_entity_um.c
@@ -497,7 +497,7 @@ static int tx_list_size(nr_rlc_entity_um_t *entity,
 {
   int ret = 0;
 
-  while (l != NULL) {
+  while (l != NULL && ret < maxsize) {
     ret += compute_pdu_header_size(entity, l) + l->size;
     l = l->next;
   }
diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c
index 2a6bcf74aee97651a84b781483eb11269dd420f4..fb657bf5a8889042f0611f1c441bf706b764d4bc 100644
--- a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c
+++ b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c
@@ -38,7 +38,6 @@
 #include "common/ran_context.h"
 #include "NR_UL-CCCH-Message.h"
 
-#undef C_RNTI // C_RNTI is used in F1AP generated code, prevent preprocessor replace
 #include "openair2/F1AP/f1ap_du_rrc_message_transfer.h"
 
 #include "openair2/LAYER2/PROTO_AGENT/proto_agent.h"
@@ -47,6 +46,8 @@ extern RAN_CONTEXT_t RC;
 
 #include <stdint.h>
 
+#include <executables/softmodem-common.h>
+
 static nr_rlc_ue_manager_t *nr_rlc_ue_manager;
 
 /* TODO: handle time a bit more properly */
@@ -324,7 +325,8 @@ rlc_buffer_occupancy_t mac_rlc_get_buffer_occupancy_ind(
      * reports '> 81338368' (table 6.1.3.1-2). Passing 100000000 is thus
      * more than enough.
      */
-    buf_stat = rb->buffer_status(rb, 100000000);
+    // Fixme : Laurent reduced size for CPU saving
+    buf_stat = rb->buffer_status(rb, 10000000);
     ret = buf_stat.status_size
         + buf_stat.retx_size
         + buf_stat.tx_size;
@@ -426,7 +428,7 @@ static void deliver_sdu(void *_ue, nr_rlc_entity_t *entity, char *buf, int size)
   int is_enb;
 
   /* is it SRB? */
-  for (i = 0; i < 2; i++) {
+  for (i = 0; i < sizeofArray(ue->srb); i++) {
     if (entity == ue->srb[i]) {
       is_srb = 1;
       rb_id = i+1;
@@ -435,7 +437,7 @@ static void deliver_sdu(void *_ue, nr_rlc_entity_t *entity, char *buf, int size)
   }
 
   /* maybe DRB? */
-  for (i = 0; i < 5; i++) {
+  for (i = 0; i < sizeofArray(ue->drb) ; i++) {
     if (entity == ue->drb[i]) {
       is_srb = 0;
       rb_id = i+1;
@@ -918,7 +920,7 @@ rlc_op_status_t nr_rrc_rlc_config_asn1_req (const protocol_ctxt_t   * const ctxt
 
   if (drb2release_listP != NULL) {
     LOG_E(RLC, "%s:%d:%s: TODO\n", __FILE__, __LINE__, __FUNCTION__);
-    exit(1);
+    //exit(1);
   }
 
   if (srb2add_listP != NULL) {
diff --git a/openair2/RRC/LTE/L2_interface.c b/openair2/RRC/LTE/L2_interface.c
index 921c1f3bcb84c1bc7a75ec903d6f39da4c368c54..0b767b8ad6efa203c3317cb8c876a35bb7adf803 100644
--- a/openair2/RRC/LTE/L2_interface.c
+++ b/openair2/RRC/LTE/L2_interface.c
@@ -49,8 +49,6 @@
 #include "intertask_interface.h"
 
 #include "flexran_agent_extern.h"
-#undef C_RNTI // C_RNTI is used in F1AP generated code, prevent preprocessor replace
-//#include "f1ap_du_rrc_message_transfer.h"
 #include "openair2/F1AP/f1ap_du_rrc_message_transfer.h"
 
 extern RAN_CONTEXT_t RC;
diff --git a/openair2/RRC/NR/L2_nr_interface.c b/openair2/RRC/NR/L2_nr_interface.c
index 1f4af2a98eff5b81d3598d89868f424a3db1ab07..8a6e16499947323d1928a78f474d9e8e2cdacf21 100644
--- a/openair2/RRC/NR/L2_nr_interface.c
+++ b/openair2/RRC/NR/L2_nr_interface.c
@@ -44,7 +44,9 @@
 #include "NR_MIB.h"
 #include "NR_BCCH-BCH-Message.h"
 #include "rrc_gNB_UE_context.h"
-#include "openair2/RRC/NR/MESSAGES/asn1_msg.h"
+#include <openair2/RRC/NR/MESSAGES/asn1_msg.h>
+#include <openair2/F1AP/f1ap_du_rrc_message_transfer.h>
+
 
 extern RAN_CONTEXT_t RC;
 
@@ -361,4 +363,23 @@ int8_t nr_mac_rrc_data_ind(const module_id_t     module_idP,
   }
 
   return 0;
-}
\ No newline at end of file
+}
+
+void nr_mac_gNB_rrc_ul_failure(const module_id_t Mod_instP,
+                            const int CC_idP,
+                            const frame_t frameP,
+                            const sub_frame_t subframeP,
+                            const rnti_t rntiP) {
+  struct rrc_gNB_ue_context_s *ue_context_p = NULL;
+  ue_context_p = rrc_gNB_get_ue_context(
+                   RC.nrrrc[Mod_instP],
+                   rntiP);
+
+  if (ue_context_p != NULL) {
+    LOG_D(RRC,"Frame %d, Subframe %d: UE %x UL failure, activating timer\n",frameP,subframeP,rntiP);
+    if(ue_context_p->ue_context.ul_failure_timer == 0)
+      ue_context_p->ue_context.ul_failure_timer=1;
+  } else {
+    LOG_D(RRC,"Frame %d, Subframe %d: UL failure: UE %x unknown \n",frameP,subframeP,rntiP);
+  }
+}
diff --git a/openair2/RRC/NR/MESSAGES/asn1_msg.c b/openair2/RRC/NR/MESSAGES/asn1_msg.c
index 789fb84a288e355543262196e2f87fdb373af88e..e36644afb0089375208ded1a1b8834af5b76668e 100755
--- a/openair2/RRC/NR/MESSAGES/asn1_msg.c
+++ b/openair2/RRC/NR/MESSAGES/asn1_msg.c
@@ -1220,47 +1220,6 @@ void fill_initial_cellGroupConfig(rnti_t rnti,
   logicalChannelConfig->ul_SpecificParameters->logicalChannelSR_DelayTimerApplied = 0;
   rlc_BearerConfig->mac_LogicalChannelConfig                       = logicalChannelConfig;
   ASN_SEQUENCE_ADD(&cellGroupConfig->rlc_BearerToAddModList->list, rlc_BearerConfig);
-
-  /*
-  // SRB2
-  NR_RLC_BearerConfig_t *rlc_BearerConfig2 = NULL;
-  NR_RLC_Config_t *rlc_Config2 = NULL;
-  NR_LogicalChannelConfig_t *logicalChannelConfig2= NULL;
-  long *logicalChannelGroup2 = NULL;
-  rlc_BearerConfig2                                                 = calloc(1, sizeof(NR_RLC_BearerConfig_t));
-  rlc_BearerConfig2->logicalChannelIdentity                         = 2;
-  rlc_BearerConfig2->servedRadioBearer                              = calloc(1, sizeof(*rlc_BearerConfig2->servedRadioBearer));
-  rlc_BearerConfig2->servedRadioBearer->present                     = NR_RLC_BearerConfig__servedRadioBearer_PR_srb_Identity;
-  rlc_BearerConfig2->servedRadioBearer->choice.srb_Identity         = 2;
-  rlc_BearerConfig2->reestablishRLC                                 = NULL;
-  rlc_Config2 = calloc(1, sizeof(NR_RLC_Config_t));
-  rlc_Config2->present                                              = NR_RLC_Config_PR_am;
-  rlc_Config2->choice.am                                            = calloc(1, sizeof(*rlc_Config2->choice.am));
-  rlc_Config2->choice.am->dl_AM_RLC.sn_FieldLength                  = calloc(1, sizeof(NR_SN_FieldLengthAM_t));
-  *(rlc_Config2->choice.am->dl_AM_RLC.sn_FieldLength)               = NR_SN_FieldLengthAM_size12;
-  rlc_Config2->choice.am->dl_AM_RLC.t_Reassembly                    = NR_T_Reassembly_ms35;
-  rlc_Config2->choice.am->dl_AM_RLC.t_StatusProhibit                = NR_T_StatusProhibit_ms0;
-  rlc_Config2->choice.am->ul_AM_RLC.sn_FieldLength                  = calloc(1, sizeof(NR_SN_FieldLengthAM_t));
-  *(rlc_Config2->choice.am->ul_AM_RLC.sn_FieldLength)               = NR_SN_FieldLengthAM_size12;
-  rlc_Config2->choice.am->ul_AM_RLC.t_PollRetransmit                = NR_T_PollRetransmit_ms45;
-  rlc_Config2->choice.am->ul_AM_RLC.pollPDU                         = NR_PollPDU_infinity;
-  rlc_Config2->choice.am->ul_AM_RLC.pollByte                        = NR_PollByte_infinity;
-  rlc_Config2->choice.am->ul_AM_RLC.maxRetxThreshold                = NR_UL_AM_RLC__maxRetxThreshold_t8;
-  rlc_BearerConfig2->rlc_Config                                     = rlc_Config2;
-  logicalChannelConfig2                                             = calloc(1, sizeof(NR_LogicalChannelConfig_t));
-  logicalChannelConfig2->ul_SpecificParameters                      = calloc(1, sizeof(*logicalChannelConfig2->ul_SpecificParameters));
-  logicalChannelConfig2->ul_SpecificParameters->priority            = 1;
-  logicalChannelConfig2->ul_SpecificParameters->prioritisedBitRate  = NR_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_infinity;
-  logicalChannelGroup2                                              = CALLOC(1, sizeof(long));
-  *logicalChannelGroup2                                             = 0;
-  logicalChannelConfig2->ul_SpecificParameters->logicalChannelGroup = logicalChannelGroup2;
-  logicalChannelConfig2->ul_SpecificParameters->schedulingRequestID = CALLOC(1, sizeof(*logicalChannelConfig2->ul_SpecificParameters->schedulingRequestID));
-  *logicalChannelConfig2->ul_SpecificParameters->schedulingRequestID = 0;
-  logicalChannelConfig2->ul_SpecificParameters->logicalChannelSR_Mask = 0;
-  logicalChannelConfig2->ul_SpecificParameters->logicalChannelSR_DelayTimerApplied = 0;
-  rlc_BearerConfig2->mac_LogicalChannelConfig                       = logicalChannelConfig2;
-  ASN_SEQUENCE_ADD(&cellGroupConfig->rlc_BearerToAddModList->list, rlc_BearerConfig2);
-  */
   
   cellGroupConfig->rlc_BearerToReleaseList = NULL;
   
@@ -1653,13 +1612,14 @@ int16_t do_RRCReconfiguration(
     // *security_config->keyToUse = NR_SecurityConfig__keyToUse_master;
 
     ie = calloc(1, sizeof(NR_RRCReconfiguration_IEs_t));
-    ie->radioBearerConfig = calloc(1, sizeof(NR_RadioBearerConfig_t));
-    ie->radioBearerConfig->srb_ToAddModList  = SRB_configList;
-    ie->radioBearerConfig->drb_ToAddModList  = DRB_configList;
-    ie->radioBearerConfig->securityConfig    = security_config;
-    ie->radioBearerConfig->srb3_ToRelease    = NULL;
-    ie->radioBearerConfig->drb_ToReleaseList = DRB_releaseList;
-
+    if (SRB_configList || DRB_configList) {
+      ie->radioBearerConfig = calloc(1, sizeof(NR_RadioBearerConfig_t));
+      ie->radioBearerConfig->srb_ToAddModList  = SRB_configList;
+      ie->radioBearerConfig->drb_ToAddModList  = DRB_configList;
+      ie->radioBearerConfig->securityConfig    = security_config;
+      ie->radioBearerConfig->srb3_ToRelease    = NULL;
+      ie->radioBearerConfig->drb_ToReleaseList = DRB_releaseList;
+    }
     /******************** Secondary Cell Group ********************/
     // rrc_gNB_carrier_data_t *carrier = &(gnb_rrc_inst->carrier);
     // fill_default_secondaryCellGroup( carrier->servingcellconfigcommon,
diff --git a/openair2/RRC/NR/nr_rrc_defs.h b/openair2/RRC/NR/nr_rrc_defs.h
index 5efb2e1e644edebd75fd9463680af8ff3aeee4f1..5fd9b5d638076623cc2b3c93737094a0724fbd90 100644
--- a/openair2/RRC/NR/nr_rrc_defs.h
+++ b/openair2/RRC/NR/nr_rrc_defs.h
@@ -356,7 +356,7 @@ typedef struct gNB_RRC_UE_s {
   /* list of e_rab to be setup by RRC layers */
   /* list of pdu session to be setup by RRC layers */
   e_rab_param_t                      e_rab[NB_RB_MAX];//[S1AP_MAX_E_RAB];
-  pdu_session_param_t                pdusession[NR_NB_RB_MAX];//[NGAP_MAX_PDU_SESSION];
+  pdu_session_param_t                pduSession[NR_NB_RB_MAX];//[NGAP_MAX_PDU_SESSION];
   //release e_rabs
   uint8_t                            nb_release_of_e_rabs;
   e_rab_failed_t                     e_rabs_release_failed[S1AP_MAX_E_RAB];
@@ -381,6 +381,7 @@ typedef struct gNB_RRC_UE_s {
   uint32_t                           ue_reestablishment_timer_thres;
   uint8_t                            e_rab_release_command_flag;
   uint8_t                            pdu_session_release_command_flag;
+  uint8_t                            established_pdu_sessions_flag;
   uint32_t                           ue_rrc_inactivity_timer;
   int8_t                             reestablishment_xid;
   //------------------------------------------------------------------------------//
diff --git a/openair2/RRC/NR/nr_rrc_proto.h b/openair2/RRC/NR/nr_rrc_proto.h
index ff7547832e5bf28a1f66791eac1896e5dbe7fc0e..20656deff4ca246a049bedb8ef2512592cd770c6 100644
--- a/openair2/RRC/NR/nr_rrc_proto.h
+++ b/openair2/RRC/NR/nr_rrc_proto.h
@@ -106,6 +106,13 @@ int generate_CG_Config(gNB_RRC_INST *rrc,
 		       NR_RRCReconfiguration_t *reconfig,
 		       NR_RadioBearerConfig_t *rbconfig);
 
+void apply_macrlc_config(gNB_RRC_INST *rrc,
+                         rrc_gNB_ue_context_t         *const ue_context_pP,
+                         const protocol_ctxt_t        *const ctxt_pP );
+
+void apply_pdcp_config(rrc_gNB_ue_context_t         *const ue_context_pP,
+                       const protocol_ctxt_t        *const ctxt_pP );
+
 void
 rrc_gNB_generate_RRCSetup(
     const protocol_ctxt_t        *const ctxt_pP,
diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c
index 23e3391c853b824e22e081770ede83baee7ba1d2..8ad6b5c8e600aafe95bad7088a542205a0e739d5 100755
--- a/openair2/RRC/NR/rrc_gNB.c
+++ b/openair2/RRC/NR/rrc_gNB.c
@@ -378,6 +378,46 @@ rrc_gNB_get_next_transaction_identifier(
   return nr_rrc_transaction_identifier[gnb_mod_idP];
 }
 
+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,
+                             NULL,
+                             0,
+                             ue_context_pP->ue_context.rnti,
+                             get_softmodem_params()->sa ? ue_context_pP->ue_context.masterCellGroup : (NR_CellGroupConfig_t *)NULL);
+
+      nr_rrc_rlc_config_asn1_req(ctxt_pP,
+                                 ue_context_pP->ue_context.SRB_configList,
+                                 NULL,
+                                 NULL,
+                                 NULL,
+                                 get_softmodem_params()->sa ? ue_context_pP->ue_context.masterCellGroup->rlc_BearerToAddModList : NULL);
+
+}
+
+void apply_pdcp_config(rrc_gNB_ue_context_t         *const ue_context_pP,
+                       const protocol_ctxt_t        *const ctxt_pP ) {
+
+      nr_rrc_pdcp_config_asn1_req(ctxt_pP,
+                                  ue_context_pP->ue_context.SRB_configList,
+                                  NULL,
+                                  NULL,
+                                  0xff,
+                                  NULL,
+                                  NULL,
+                                  NULL,
+                                  NULL,
+                                  NULL,
+                                  NULL,
+                                  get_softmodem_params()->sa ? ue_context_pP->ue_context.masterCellGroup->rlc_BearerToAddModList : NULL);
+
+}
+
 //-----------------------------------------------------------------------------
 void
 rrc_gNB_generate_RRCSetup(
@@ -487,34 +527,9 @@ rrc_gNB_generate_RRCSetup(
       //   ue_context_pP->ue_context.ue_rrc_inactivity_timer = 0;
 
       // configure MAC
-      rrc_mac_config_req_gNB(rrc->module_id,
-                             rrc->carrier.ssb_SubcarrierOffset,
-                             rrc->carrier.pdsch_AntennaPorts,
-                             rrc->carrier.pusch_AntennaPorts,
-                             NULL,
-                             0,
-                             ue_context_pP->ue_context.rnti,
-                             get_softmodem_params()->sa ? ue_context_pP->ue_context.masterCellGroup : (NR_CellGroupConfig_t *)NULL);
-
-      nr_rrc_rlc_config_asn1_req(ctxt_pP,
-                                 ue_context_pP->ue_context.SRB_configList,
-                                 NULL,
-                                 NULL,
-                                 NULL,
-                                 get_softmodem_params()->sa ? ue_context_pP->ue_context.masterCellGroup->rlc_BearerToAddModList : NULL);
+      apply_macrlc_config(rrc,ue_context_pP,ctxt_pP);
 
-      nr_rrc_pdcp_config_asn1_req(ctxt_pP,
-                                  ue_context_pP->ue_context.SRB_configList,
-                                  NULL,
-                                  NULL,
-                                  0xff,
-                                  NULL,
-                                  NULL,
-                                  NULL,
-                                  NULL,
-                                  NULL,
-                                  NULL,
-                                  get_softmodem_params()->sa ? ue_context_pP->ue_context.masterCellGroup->rlc_BearerToAddModList : NULL);
+      apply_pdcp_config(ue_context_pP,ctxt_pP);
 #endif
     }
     break;
@@ -784,6 +799,22 @@ rrc_gNB_generate_defaultRRCReconfiguration(
 
   dedicatedNAS_MessageList = CALLOC(1, sizeof(struct NR_RRCReconfiguration_v1530_IEs__dedicatedNAS_MessageList));
 
+  /* Add all NAS PDUs to the list */
+  for (int i = 0; i < ue_context_pP->ue_context.nb_of_pdusessions; i++) {
+    if (ue_context_pP->ue_context.pduSession[i].param.nas_pdu.buffer != NULL) {
+      dedicatedNAS_Message = CALLOC(1, sizeof(NR_DedicatedNAS_Message_t));
+      memset(dedicatedNAS_Message, 0, sizeof(OCTET_STRING_t));
+      OCTET_STRING_fromBuf(dedicatedNAS_Message,
+                            (char *)ue_context_pP->ue_context.pduSession[i].param.nas_pdu.buffer,
+                            ue_context_pP->ue_context.pduSession[i].param.nas_pdu.length);
+      ASN_SEQUENCE_ADD(&dedicatedNAS_MessageList->list, dedicatedNAS_Message);
+    }
+
+    ue_context_pP->ue_context.pduSession[i].status = PDU_SESSION_STATUS_DONE;
+    LOG_D(NR_RRC, "setting the status for the default DRB (index %d) to (%d,%s)\n",
+          i, ue_context_pP->ue_context.pduSession[i].status, "PDU_SESSION_STATUS_DONE");
+  }
+
   if (ue_context_pP->ue_context.nas_pdu_flag == 1) {
     dedicatedNAS_Message = CALLOC(1, sizeof(NR_DedicatedNAS_Message_t));
     memset(dedicatedNAS_Message, 0, sizeof(OCTET_STRING_t));
@@ -815,6 +846,15 @@ rrc_gNB_generate_defaultRRCReconfiguration(
   free(ue_context_pP->ue_context.nas_pdu.buffer);
 
   LOG_DUMPMSG(NR_RRC, DEBUG_RRC,(char *)buffer, size, "[MSG] RRC Reconfiguration\n");
+
+  /* Free all NAS PDUs */
+  for (int i = 0; i < ue_context_pP->ue_context.nb_of_pdusessions; i++) {
+    if (ue_context_pP->ue_context.pduSession[i].param.nas_pdu.buffer != NULL) {
+      free(ue_context_pP->ue_context.pduSession[i].param.nas_pdu.buffer);
+      ue_context_pP->ue_context.pduSession[i].param.nas_pdu.buffer = NULL;
+    }
+  }
+
   LOG_I(NR_RRC, "[gNB %d] Frame %d, Logical Channel DL-DCCH, Generate NR_RRCReconfiguration (bytes %d, UE id %x)\n",
           ctxt_pP->module_id,
           ctxt_pP->frame,
@@ -916,15 +956,14 @@ rrc_gNB_generate_dedicatedRRCReconfiguration(
 
   /* Configure SRB2 */
   SRB_configList2 = &ue_context_pP->ue_context.SRB_configList2[xid];
-  if (*SRB_configList2) {
-    free(*SRB_configList2);
+  if (*SRB_configList2 == NULL) {
+    *SRB_configList2 = CALLOC(1, sizeof(**SRB_configList2));
+    memset(*SRB_configList2, 0, sizeof(**SRB_configList2));
+    SRB2_config = CALLOC(1, sizeof(*SRB2_config));
+    SRB2_config->srb_Identity = 2;
+    ASN_SEQUENCE_ADD(&(*SRB_configList2)->list, SRB2_config);
+    ASN_SEQUENCE_ADD(&SRB_configList->list, SRB2_config);
   }
-  *SRB_configList2 = CALLOC(1, sizeof(**SRB_configList2));
-  memset(*SRB_configList2, 0, sizeof(**SRB_configList2));
-  SRB2_config = CALLOC(1, sizeof(*SRB2_config));
-  SRB2_config->srb_Identity = 2;
-  ASN_SEQUENCE_ADD(&(*SRB_configList2)->list, SRB2_config);
-  ASN_SEQUENCE_ADD(&SRB_configList->list, SRB2_config);
 
   DRB_configList = &ue_context_pP->ue_context.DRB_configList;
   if (*DRB_configList) {
@@ -947,7 +986,7 @@ rrc_gNB_generate_dedicatedRRCReconfiguration(
       break;
     }
 
-    if (ue_context_pP->ue_context.pdusession[i].status >= PDU_SESSION_STATUS_DONE) {
+    if (ue_context_pP->ue_context.pduSession[i].status >= PDU_SESSION_STATUS_DONE) {
       continue;
     }
 
@@ -958,15 +997,15 @@ rrc_gNB_generate_dedicatedRRCReconfiguration(
     // sdap_Config
     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->pdu_Session = ue_context_pP->ue_context.pduSession[i].param.pdusession_id;
     sdap_config->sdap_HeaderDL = NR_SDAP_Config__sdap_HeaderDL_absent;
-    sdap_config->sdap_HeaderUL = NR_SDAP_Config__sdap_HeaderUL_present;
+    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;
+    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);
     }
     sdap_config->mappedQoS_FlowsToRelease = NULL;
@@ -996,8 +1035,8 @@ rrc_gNB_generate_dedicatedRRCReconfiguration(
     DRB_config->pdcp_Config->ext1 = NULL;
 
     // Reference TS23501 Table 5.7.4-1: Standardized 5QI to QoS characteristics mapping
-    for (qos_flow_index = 0; qos_flow_index < ue_context_pP->ue_context.pdusession[i].param.nb_qos; qos_flow_index++) {
-      switch (ue_context_pP->ue_context.pdusession[i].param.qos[qos_flow_index].fiveQI) {
+    for (qos_flow_index = 0; qos_flow_index < ue_context_pP->ue_context.pduSession[i].param.nb_qos; qos_flow_index++) {
+      switch (ue_context_pP->ue_context.pduSession[i].param.qos[qos_flow_index].fiveQI) {
         case 1: //100ms
         case 2: //150ms
         case 3: //50ms
@@ -1011,9 +1050,9 @@ rrc_gNB_generate_dedicatedRRCReconfiguration(
           break;
 
         default:
-          LOG_E(NR_RRC,"not supported 5qi %lu\n", ue_context_pP->ue_context.pdusession[i].param.qos[qos_flow_index].fiveQI);
-          ue_context_pP->ue_context.pdusession[i].status = PDU_SESSION_STATUS_FAILED;
-          ue_context_pP->ue_context.pdusession[i].xid = xid;
+          LOG_E(NR_RRC,"not supported 5qi %lu\n", ue_context_pP->ue_context.pduSession[i].param.qos[qos_flow_index].fiveQI);
+          ue_context_pP->ue_context.pduSession[i].status = PDU_SESSION_STATUS_FAILED;
+          ue_context_pP->ue_context.pduSession[i].xid = xid;
           pdu_sessions_done++;
           free(DRB_config);
           continue;
@@ -1023,18 +1062,18 @@ rrc_gNB_generate_dedicatedRRCReconfiguration(
     ASN_SEQUENCE_ADD(&(*DRB_configList)->list, DRB_config);
     ASN_SEQUENCE_ADD(&(*DRB_configList2)->list, DRB_config);
 
-    ue_context_pP->ue_context.pdusession[i].status = PDU_SESSION_STATUS_DONE;
-    ue_context_pP->ue_context.pdusession[i].xid = xid;
+    ue_context_pP->ue_context.pduSession[i].status = PDU_SESSION_STATUS_DONE;
+    ue_context_pP->ue_context.pduSession[i].xid = xid;
 
-    if (ue_context_pP->ue_context.pdusession[i].param.nas_pdu.buffer != NULL) {
+    if (ue_context_pP->ue_context.pduSession[i].param.nas_pdu.buffer != NULL) {
       dedicatedNAS_Message = CALLOC(1, sizeof(NR_DedicatedNAS_Message_t));
       memset(dedicatedNAS_Message, 0, sizeof(OCTET_STRING_t));
       OCTET_STRING_fromBuf(dedicatedNAS_Message,
-                            (char *)ue_context_pP->ue_context.pdusession[i].param.nas_pdu.buffer,
-                            ue_context_pP->ue_context.pdusession[i].param.nas_pdu.length);
+                            (char *)ue_context_pP->ue_context.pduSession[i].param.nas_pdu.buffer,
+                            ue_context_pP->ue_context.pduSession[i].param.nas_pdu.length);
       ASN_SEQUENCE_ADD(&dedicatedNAS_MessageList->list, dedicatedNAS_Message);
 
-      LOG_I(NR_RRC,"add NAS info with size %d (pdusession id %d)\n",ue_context_pP->ue_context.pdusession[i].param.nas_pdu.length, i);
+      LOG_I(NR_RRC,"add NAS info with size %d (pdusession id %d)\n",ue_context_pP->ue_context.pduSession[i].param.nas_pdu.length, i);
     } else {
       // TODO
       LOG_E(NR_RRC,"no NAS info (pdusession id %d)\n", i);
@@ -1065,10 +1104,10 @@ rrc_gNB_generate_dedicatedRRCReconfiguration(
 
   /* Free all NAS PDUs */
   for (i = 0; i < ue_context_pP->ue_context.nb_of_pdusessions; i++) {
-    if (ue_context_pP->ue_context.pdusession[i].param.nas_pdu.buffer != NULL) {
+    if (ue_context_pP->ue_context.pduSession[i].param.nas_pdu.buffer != NULL) {
       /* Free the NAS PDU buffer and invalidate it */
-      free(ue_context_pP->ue_context.pdusession[i].param.nas_pdu.buffer);
-      ue_context_pP->ue_context.pdusession[i].param.nas_pdu.buffer = NULL;
+      free(ue_context_pP->ue_context.pduSession[i].param.nas_pdu.buffer);
+      ue_context_pP->ue_context.pduSession[i].param.nas_pdu.buffer = NULL;
     }
   }
 
@@ -1137,7 +1176,7 @@ rrc_gNB_generate_dedicatedRRCReconfiguration_release(
 
   *DRB_Release_configList2 = CALLOC(1, sizeof(**DRB_Release_configList2));
   for(i = 0; i < NB_RB_MAX; i++) {
-    if((ue_context_pP->ue_context.pdusession[i].status == PDU_SESSION_STATUS_TORELEASE) && ue_context_pP->ue_context.pdusession[i].xid == xid) {
+    if((ue_context_pP->ue_context.pduSession[i].status == PDU_SESSION_STATUS_TORELEASE) && ue_context_pP->ue_context.pduSession[i].xid == xid) {
       DRB_release = CALLOC(1, sizeof(NR_DRB_Identity_t));
       *DRB_release = i+1;
       ASN_SEQUENCE_ADD(&(*DRB_Release_configList2)->list, DRB_release);
@@ -1238,6 +1277,7 @@ rrc_gNB_process_RRCReconfigurationComplete(
   NR_DRB_ToReleaseList_t             *DRB_Release_configList2 = ue_context_pP->ue_context.DRB_Release_configList2[xid];
   NR_DRB_Identity_t                  *drb_id_p      = NULL;
 //  uint8_t                             nr_DRB2LCHAN[8];
+  gNB_RRC_INST *rrc = RC.nrrrc[ctxt_pP->module_id];
 
   ue_context_pP->ue_context.ue_reestablishment_timer = 0;
 
@@ -1268,7 +1308,7 @@ rrc_gNB_process_RRCReconfigurationComplete(
                               SRB_configList, // NULL,
                               DRB_configList,
                               DRB_Release_configList2,
-                              0xff, // already configured during the securitymodecommand
+                              0, // already configured during the securitymodecommand
                               kRRCenc,
                               kRRCint,
                               kUPenc,
@@ -1278,6 +1318,15 @@ rrc_gNB_process_RRCReconfigurationComplete(
                               get_softmodem_params()->sa ? ue_context_pP->ue_context.masterCellGroup->rlc_BearerToAddModList : NULL);
   /* Refresh SRBs/DRBs */
   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,
+                           NULL,
+                           0,
+                           ue_context_pP->ue_context.rnti,
+                           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,
@@ -1592,13 +1641,13 @@ rrc_gNB_process_RRCConnectionReestablishmentComplete(
     memset(&create_tunnel_req, 0, sizeof(create_tunnel_req));
 
     for ( j = 0, i = 0; i < NB_RB_MAX; i++) {
-      if (ue_context_pP->ue_context.pdusession[i].status == PDU_SESSION_STATUS_ESTABLISHED || ue_context_pP->ue_context.pdusession[i].status == PDU_SESSION_STATUS_DONE) {
-        create_tunnel_req.pdusession_id[j]   = ue_context_pP->ue_context.pdusession[i].param.pdusession_id;
-        create_tunnel_req.upf_NGu_teid[j]  = ue_context_pP->ue_context.pdusession[i].param.gtp_teid;
+      if (ue_context_pP->ue_context.pduSession[i].status == PDU_SESSION_STATUS_ESTABLISHED || ue_context_pP->ue_context.pduSession[i].status == PDU_SESSION_STATUS_DONE) {
+        create_tunnel_req.pdusession_id[j]   = ue_context_pP->ue_context.pduSession[i].param.pdusession_id;
+        create_tunnel_req.upf_NGu_teid[j]  = ue_context_pP->ue_context.pduSession[i].param.gtp_teid;
         memcpy(create_tunnel_req.upf_addr[j].buffer,
-               ue_context_pP->ue_context.pdusession[i].param.upf_addr.buffer,
+               ue_context_pP->ue_context.pduSession[i].param.upf_addr.buffer,
                 sizeof(uint8_t)*20);
-        create_tunnel_req.upf_addr[j].length = ue_context_pP->ue_context.pdusession[i].param.upf_addr.length;
+        create_tunnel_req.upf_addr[j].length = ue_context_pP->ue_context.pduSession[i].param.upf_addr.length;
         j++;
       }
     }
@@ -1658,10 +1707,10 @@ rrc_gNB_process_RRCConnectionReestablishmentComplete(
 
     /* TODO parameters yet to process ... */
     /* TODO should test if pdu session are Ok before! */
-    ue_context_pP->ue_context.pdusession[i].status = PDU_SESSION_STATUS_DONE;
-    ue_context_pP->ue_context.pdusession[i].xid    = xid;
+    ue_context_pP->ue_context.pduSession[i].status = PDU_SESSION_STATUS_DONE;
+    ue_context_pP->ue_context.pduSession[i].xid    = xid;
     LOG_D(NR_RRC, "setting the status for the default DRB (index %d) to (%d,%s)\n",
-          i, ue_context_pP->ue_context.pdusession[i].status, "PDU_SESSION_STATUS_DONE");
+          i, ue_context_pP->ue_context.pduSession[i].status, "PDU_SESSION_STATUS_DONE");
   }
 
   memset(buffer, 0, RRC_BUF_SIZE);
@@ -1682,10 +1731,10 @@ rrc_gNB_process_RRCConnectionReestablishmentComplete(
 
   /* Free all NAS PDUs */
   for (i = 0; i < ue_context_pP->ue_context.nb_of_pdusessions; i++) {
-    if (ue_context_pP->ue_context.pdusession[i].param.nas_pdu.buffer != NULL) {
+    if (ue_context_pP->ue_context.pduSession[i].param.nas_pdu.buffer != NULL) {
       /* Free the NAS PDU buffer and invalidate it */
-      free(ue_context_pP->ue_context.pdusession[i].param.nas_pdu.buffer);
-      ue_context_pP->ue_context.pdusession[i].param.nas_pdu.buffer = NULL;
+      free(ue_context_pP->ue_context.pduSession[i].param.nas_pdu.buffer);
+      ue_context_pP->ue_context.pduSession[i].param.nas_pdu.buffer = NULL;
     }
   }
 
@@ -2015,10 +2064,10 @@ int nr_rrc_gNB_decode_ccch(protocol_ctxt_t    *const ctxt_pP,
                 ue_context_p->ue_context.reestablishment_xid);
 
             for (uint8_t pdusessionid = 0; pdusessionid < ue_context_p->ue_context.nb_of_pdusessions; pdusessionid++) {
-              if (ue_context_p->ue_context.pdusession[pdusessionid].status == PDU_SESSION_STATUS_DONE) {
-                ue_context_p->ue_context.pdusession[pdusessionid].status = PDU_SESSION_STATUS_ESTABLISHED;
+              if (ue_context_p->ue_context.pduSession[pdusessionid].status == PDU_SESSION_STATUS_DONE) {
+                ue_context_p->ue_context.pduSession[pdusessionid].status = PDU_SESSION_STATUS_ESTABLISHED;
               } else {
-                ue_context_p->ue_context.pdusession[pdusessionid].status = PDU_SESSION_STATUS_FAILED;
+                ue_context_p->ue_context.pduSession[pdusessionid].status = PDU_SESSION_STATUS_FAILED;
               }
             }
           }
@@ -2264,7 +2313,7 @@ rrc_gNB_decode_dcch(
             GTPV1U_GNB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).rnti = ue_context_p->ue_context.rnti;
 
             for(i = 0; i < NB_RB_MAX; i++) {
-              if(xid == ue_context_p->ue_context.pdusession[i].xid) {
+              if(xid == ue_context_p->ue_context.pduSession[i].xid) {
                 GTPV1U_GNB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).pdusession_id[GTPV1U_GNB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).num_pdusession++] =
                   ue_context_p->ue_context.gnb_gtp_psi[i];
                 ue_context_p->ue_context.gnb_gtp_teid[i] = 0;
@@ -2276,13 +2325,14 @@ rrc_gNB_decode_dcch(
             itti_send_msg_to_task(TASK_GTPV1_U, ctxt_pP->instance, msg_delete_tunnels_p);
             //NGAP_PDUSESSION_RELEASE_RESPONSE
             rrc_gNB_send_NGAP_PDUSESSION_RELEASE_RESPONSE(ctxt_pP, ue_context_p, xid);
-          } else {
-            rrc_gNB_send_NGAP_PDUSESSION_SETUP_RESP(ctxt_pP,
-                                               ue_context_p,
-                                               ul_dcch_msg->message.choice.c1->choice.rrcReconfigurationComplete->rrc_TransactionIdentifier);
+          } else if (ue_context_p->ue_context.established_pdu_sessions_flag != 1) {
+            if (ue_context_p->ue_context.setup_pdu_sessions > 0) {
+              rrc_gNB_send_NGAP_PDUSESSION_SETUP_RESP(ctxt_pP,
+                ue_context_p,
+                ul_dcch_msg->message.choice.c1->choice.rrcReconfigurationComplete->rrc_TransactionIdentifier);
+            }
           }
         }
-
         if (first_rrcreconfiguration == 0){
           first_rrcreconfiguration = 1;
           rrc_gNB_send_NGAP_INITIAL_CONTEXT_SETUP_RESP(ctxt_pP, ue_context_p);
@@ -2563,7 +2613,13 @@ rrc_gNB_decode_dcch(
                                     ue_context_p,
                                     ul_dcch_msg);
       }
-      rrc_gNB_generate_defaultRRCReconfiguration(ctxt_pP, ue_context_p);
+
+      if (ue_context_p->ue_context.established_pdu_sessions_flag == 1) {
+        rrc_gNB_generate_dedicatedRRCReconfiguration(ctxt_pP, ue_context_p);
+      } else {
+        rrc_gNB_generate_defaultRRCReconfiguration(ctxt_pP, ue_context_p);
+      }
+
       break;
 
             case NR_UL_DCCH_MessageType__c1_PR_rrcReestablishmentComplete:
@@ -2771,8 +2827,290 @@ void rrc_gNB_process_dc_overall_timeout(const module_id_t gnb_mod_idP, x2ap_ENDC
   rrc_remove_nsa_user(rrc, m->rnti);
 }
 
+unsigned int mask_flip(unsigned int x) {
+  return((((x>>8) + (x<<8))&0xffff)>>6);
+}
+
+unsigned int get_dl_bw_mask(gNB_RRC_INST *rrc,NR_UE_NR_Capability_t *cap) {
+
+
+  int common_band = *rrc->carrier.servingcellconfigcommon->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0];
+  int common_scs  = rrc->carrier.servingcellconfigcommon->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing;
+  for (int i=0;i<cap->rf_Parameters.supportedBandListNR.list.count;i++) {
+     NR_BandNR_t *bandNRinfo = cap->rf_Parameters.supportedBandListNR.list.array[i];
+     if (bandNRinfo->bandNR == common_band) {
+       if (common_band < 257) { // FR1
+          switch (common_scs) {
+            case NR_SubcarrierSpacing_kHz15 :
+               if (bandNRinfo->channelBWs_DL &&
+                   bandNRinfo->channelBWs_DL->choice.fr1 &&
+                   bandNRinfo->channelBWs_DL->choice.fr1->scs_15kHz)
+                     return(mask_flip((unsigned int)*(uint16_t*)bandNRinfo->channelBWs_DL->choice.fr1->scs_15kHz->buf));
+ 	      break;
+            case NR_SubcarrierSpacing_kHz30 :
+               if (bandNRinfo->channelBWs_DL &&
+                   bandNRinfo->channelBWs_DL->choice.fr1 &&
+                   bandNRinfo->channelBWs_DL->choice.fr1->scs_30kHz)
+                     return(mask_flip((unsigned int)*(uint16_t*)bandNRinfo->channelBWs_DL->choice.fr1->scs_30kHz->buf));
+              break;
+            case NR_SubcarrierSpacing_kHz60 :
+               if (bandNRinfo->channelBWs_DL &&
+                   bandNRinfo->channelBWs_DL->choice.fr1 &&
+                   bandNRinfo->channelBWs_DL->choice.fr1->scs_60kHz)
+                     return(mask_flip((unsigned int)*(uint16_t*)bandNRinfo->channelBWs_DL->choice.fr1->scs_60kHz->buf));
+              break;
+          }
+       }
+       else {
+          switch (common_scs) {
+            case NR_SubcarrierSpacing_kHz60 :
+               if (bandNRinfo->channelBWs_DL &&
+                   bandNRinfo->channelBWs_DL->choice.fr2 &&
+                   bandNRinfo->channelBWs_DL->choice.fr2->scs_60kHz)
+                     return(mask_flip((unsigned int)*(uint16_t*)bandNRinfo->channelBWs_DL->choice.fr2->scs_60kHz->buf));
+              break;
+            case NR_SubcarrierSpacing_kHz120 :
+               if (bandNRinfo->channelBWs_DL &&
+                   bandNRinfo->channelBWs_DL->choice.fr2 &&
+                   bandNRinfo->channelBWs_DL->choice.fr2->scs_120kHz)
+                     return(mask_flip((unsigned int)*(uint16_t*)bandNRinfo->channelBWs_DL->choice.fr2->scs_120kHz->buf));
+              break;
+       }
+     }
+   }
+  }
+  return(0);
+}
+
+unsigned int get_ul_bw_mask(gNB_RRC_INST *rrc,NR_UE_NR_Capability_t *cap) {
+
+
+  int common_band = *rrc->carrier.servingcellconfigcommon->uplinkConfigCommon->frequencyInfoUL->frequencyBandList->list.array[0];
+  int common_scs  = rrc->carrier.servingcellconfigcommon->uplinkConfigCommon->frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing;
+  for (int i=0;i<cap->rf_Parameters.supportedBandListNR.list.count;i++) {
+     NR_BandNR_t *bandNRinfo = cap->rf_Parameters.supportedBandListNR.list.array[i];
+     if (bandNRinfo->bandNR == common_band) {
+       if (common_band < 257) { // FR1
+          switch (common_scs) {
+            case NR_SubcarrierSpacing_kHz15 :
+               if (bandNRinfo->channelBWs_UL &&
+                   bandNRinfo->channelBWs_UL->choice.fr1 &&
+                   bandNRinfo->channelBWs_UL->choice.fr1->scs_15kHz)
+                     return(mask_flip((unsigned int)*(uint16_t*)bandNRinfo->channelBWs_UL->choice.fr1->scs_15kHz->buf));
+ 	      break;
+            case NR_SubcarrierSpacing_kHz30 :
+               if (bandNRinfo->channelBWs_UL &&
+                   bandNRinfo->channelBWs_UL->choice.fr1 &&
+                   bandNRinfo->channelBWs_UL->choice.fr1->scs_30kHz)
+                     return(mask_flip((unsigned int)*(uint16_t*)bandNRinfo->channelBWs_UL->choice.fr1->scs_30kHz->buf));
+              break;
+            case NR_SubcarrierSpacing_kHz60 :
+               if (bandNRinfo->channelBWs_UL &&
+                   bandNRinfo->channelBWs_UL->choice.fr1 &&
+                   bandNRinfo->channelBWs_UL->choice.fr1->scs_60kHz)
+                     return(mask_flip((unsigned int)*(uint16_t*)bandNRinfo->channelBWs_UL->choice.fr1->scs_60kHz->buf));
+              break;
+          }
+       }
+       else {
+          switch (common_scs) {
+            case NR_SubcarrierSpacing_kHz60 :
+               if (bandNRinfo->channelBWs_UL &&
+                   bandNRinfo->channelBWs_UL->choice.fr2 &&
+                   bandNRinfo->channelBWs_UL->choice.fr2->scs_60kHz)
+                     return(mask_flip((unsigned int)*(uint16_t*)bandNRinfo->channelBWs_UL->choice.fr2->scs_60kHz->buf));
+              break;
+            case NR_SubcarrierSpacing_kHz120 :
+               if (bandNRinfo->channelBWs_UL &&
+                   bandNRinfo->channelBWs_UL->choice.fr2 &&
+                   bandNRinfo->channelBWs_UL->choice.fr2->scs_120kHz)
+                     return(mask_flip((unsigned int)*(uint16_t*)bandNRinfo->channelBWs_UL->choice.fr2->scs_120kHz->buf));
+              break;
+       }
+     }
+   }
+  }
+  return(0);
+}
+
+int is_dl_256QAM_supported(gNB_RRC_INST *rrc,NR_UE_NR_Capability_t *cap) {
+  int common_band = *rrc->carrier.servingcellconfigcommon->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0];
+  int common_scs  = rrc->carrier.servingcellconfigcommon->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing;
+  if (common_band>256) {
+    for (int i=0;i<cap->rf_Parameters.supportedBandListNR.list.count;i++) {
+       NR_BandNR_t *bandNRinfo = cap->rf_Parameters.supportedBandListNR.list.array[i];
+       if (bandNRinfo->bandNR == common_band && !bandNRinfo->pdsch_256QAM_FR2) return (0);
+    }
+  }
+  else if (cap->phy_Parameters.phy_ParametersFR1 && !cap->phy_Parameters.phy_ParametersFR1->pdsch_256QAM_FR1) return(0);
+
+  // check featureSet
+  NR_FeatureSets_t *fs=cap->featureSets;
+  if (fs) {
+    // go through DL feature sets and look for one with current SCS
+    for (int i=0;i<fs->featureSetsDownlinkPerCC->list.count;i++) {
+       if (fs->featureSetsDownlinkPerCC->list.array[i]->supportedSubcarrierSpacingDL == common_scs &&
+           fs->featureSetsDownlinkPerCC->list.array[i]->supportedModulationOrderDL &&
+           *fs->featureSetsDownlinkPerCC->list.array[i]->supportedModulationOrderDL == NR_ModulationOrder_qam256) return(1);
+    }
+  }
+  return(0);
+}
+
+int is_ul_256QAM_supported(gNB_RRC_INST *rrc,NR_UE_NR_Capability_t *cap) {
+  int common_band = *rrc->carrier.servingcellconfigcommon->uplinkConfigCommon->frequencyInfoUL->frequencyBandList->list.array[0];
+  int common_scs  = rrc->carrier.servingcellconfigcommon->uplinkConfigCommon->frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing;
+  for (int i=0;i<cap->rf_Parameters.supportedBandListNR.list.count;i++) {
+       NR_BandNR_t *bandNRinfo = cap->rf_Parameters.supportedBandListNR.list.array[i];
+       if (bandNRinfo->bandNR == common_band && !bandNRinfo->pusch_256QAM) return (0);
+  }
+
+  // check featureSet
+  NR_FeatureSets_t *fs=cap->featureSets;
+  if (fs) {
+    // go through UL feature sets and look for one with current SCS
+    for (int i=0;i<fs->featureSetsUplinkPerCC->list.count;i++) {
+       if (fs->featureSetsUplinkPerCC->list.array[i]->supportedSubcarrierSpacingUL == common_scs &&
+           fs->featureSetsUplinkPerCC->list.array[i]->supportedModulationOrderUL &&
+           *fs->featureSetsUplinkPerCC->list.array[i]->supportedModulationOrderUL == NR_ModulationOrder_qam256) return(1);
+    }
+  }
+  return(0);
+}
+
+int get_ul_mimo_layersCB(gNB_RRC_INST *rrc,NR_UE_NR_Capability_t *cap) {
+  int common_scs  = rrc->carrier.servingcellconfigcommon->uplinkConfigCommon->frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing;
+
+  // check featureSet
+  NR_FeatureSets_t *fs=cap->featureSets;
+  if (fs) {
+    // go through UL feature sets and look for one with current SCS
+    for (int i=0;i<fs->featureSetsUplinkPerCC->list.count;i++) {
+       if (fs->featureSetsUplinkPerCC->list.array[i]->supportedSubcarrierSpacingUL == common_scs &&
+           fs->featureSetsUplinkPerCC->list.array[i]->mimo_CB_PUSCH &&
+           fs->featureSetsUplinkPerCC->list.array[i]->mimo_CB_PUSCH->maxNumberMIMO_LayersCB_PUSCH)
+           return(1<<*fs->featureSetsUplinkPerCC->list.array[i]->mimo_CB_PUSCH->maxNumberMIMO_LayersCB_PUSCH);
+    }
+  }
+  return(1);
+}
+
+int get_ul_mimo_layers(gNB_RRC_INST *rrc,NR_UE_NR_Capability_t *cap) {
+  int common_scs  = rrc->carrier.servingcellconfigcommon->uplinkConfigCommon->frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing;
+
+  // check featureSet
+  NR_FeatureSets_t *fs=cap->featureSets;
+  if (fs) {
+    // go through UL feature sets and look for one with current SCS
+    for (int i=0;i<fs->featureSetsUplinkPerCC->list.count;i++) {
+       if (fs->featureSetsUplinkPerCC->list.array[i]->supportedSubcarrierSpacingUL == common_scs &&
+           fs->featureSetsUplinkPerCC->list.array[i]->maxNumberMIMO_LayersNonCB_PUSCH)
+           return(1<<*fs->featureSetsUplinkPerCC->list.array[i]->maxNumberMIMO_LayersNonCB_PUSCH);
+    }
+  }
+  return(1);
+}
+
+int get_dl_mimo_layers(gNB_RRC_INST *rrc,NR_UE_NR_Capability_t *cap) {
+  int common_scs  = rrc->carrier.servingcellconfigcommon->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing;
+
+  // check featureSet
+  NR_FeatureSets_t *fs=cap->featureSets;
+  if (fs) {
+    // go through UL feature sets and look for one with current SCS
+    for (int i=0;i<fs->featureSetsDownlinkPerCC->list.count;i++) {
+       if (fs->featureSetsUplinkPerCC->list.array[i]->supportedSubcarrierSpacingUL == common_scs &&
+           fs->featureSetsDownlinkPerCC->list.array[i]->maxNumberMIMO_LayersPDSCH)
+           return(2<<*fs->featureSetsDownlinkPerCC->list.array[i]->maxNumberMIMO_LayersPDSCH);
+    }
+  }
+  return(1);
+}
 void nr_rrc_subframe_process(protocol_ctxt_t *const ctxt_pP, const int CC_id) {
+
   MessageDef *msg;
+  rrc_gNB_ue_context_t *ue_context_p = NULL;
+  FILE *fd=NULL;//fopen("nrRRCstats.log","w");
+  RB_FOREACH(ue_context_p, rrc_nr_ue_tree_s, &(RC.nrrrc[ctxt_pP->module_id]->rrc_ue_head)) {
+    ctxt_pP->rnti = ue_context_p->ue_id_rnti;
+
+     if (fd) {
+        if (ue_context_p->ue_context.Initialue_identity_5g_s_TMSI.presence == TRUE) {
+          fprintf(fd,"NR RRC UE rnti %x: S-TMSI %x failure timer %d/8\n",
+                ue_context_p->ue_id_rnti,
+                ue_context_p->ue_context.Initialue_identity_5g_s_TMSI.fiveg_tmsi,
+                ue_context_p->ue_context.ul_failure_timer);
+        } else {
+          fprintf(fd,"NR RRC UE rnti %x failure timer %d/8\n",
+                ue_context_p->ue_id_rnti,
+                ue_context_p->ue_context.ul_failure_timer);
+        }
+
+        if (ue_context_p->ue_context.UE_Capability_nr) {
+          fprintf(fd,"NR RRC UE cap: BW DL %x. BW UL %x, 256 QAM DL %s, 256 QAM UL %s, DL MIMO Layers %d UL MIMO Layers (CB) %d UL MIMO Layers (nonCB) %d\n",
+                get_dl_bw_mask(RC.nrrrc[0],ue_context_p->ue_context.UE_Capability_nr),
+                get_ul_bw_mask(RC.nrrrc[0],ue_context_p->ue_context.UE_Capability_nr),
+                is_dl_256QAM_supported(RC.nrrrc[0],ue_context_p->ue_context.UE_Capability_nr) == 1 ? "yes" : "no",
+                is_ul_256QAM_supported(RC.nrrrc[0],ue_context_p->ue_context.UE_Capability_nr) == 1 ? "yes" : "no",
+                get_dl_mimo_layers(RC.nrrrc[0],ue_context_p->ue_context.UE_Capability_nr),
+                get_ul_mimo_layersCB(RC.nrrrc[0],ue_context_p->ue_context.UE_Capability_nr),
+                get_ul_mimo_layers(RC.nrrrc[0],ue_context_p->ue_context.UE_Capability_nr));
+        }
+    }
+    if (ue_context_p->ue_context.ul_failure_timer > 0) {
+      ue_context_p->ue_context.ul_failure_timer++;
+
+      if (ue_context_p->ue_context.ul_failure_timer >= 20000) {
+        // remove UE after 20 seconds after MAC (or else) has indicated UL failure
+        LOG_I(RRC, "Removing UE %x instance, because of uplink failure timer timeout\n",
+              ue_context_p->ue_context.rnti);
+        if(ue_context_p->ue_context.StatusRrc >= NR_RRC_CONNECTED){
+          rrc_gNB_send_NGAP_UE_CONTEXT_RELEASE_REQ(
+                   ctxt_pP->module_id,
+                   ue_context_p,
+                   NGAP_CAUSE_RADIO_NETWORK,
+                   30);
+        }else{
+          mac_remove_nr_ue(ctxt_pP->module_id, ctxt_pP->rnti);
+          rrc_rlc_remove_ue(ctxt_pP);
+          pdcp_remove_UE(ctxt_pP);
+
+          /* remove RRC UE Context */
+          ue_context_p = rrc_gNB_get_ue_context(RC.nrrrc[ctxt_pP->module_id], ctxt_pP->rnti);
+          if (ue_context_p) {
+            rrc_gNB_remove_ue_context(ctxt_pP, RC.nrrrc[ctxt_pP->module_id], ue_context_p);
+            LOG_I(NR_RRC, "remove UE %x \n", ctxt_pP->rnti);
+          }
+        }
+        break; // break RB_FOREACH
+      }
+    }
+
+    if (ue_context_p->ue_context.ue_release_timer_rrc > 0) {
+      ue_context_p->ue_context.ue_release_timer_rrc++;
+
+      if (ue_context_p->ue_context.ue_release_timer_rrc >= ue_context_p->ue_context.ue_release_timer_thres_rrc) {
+        LOG_I(NR_RRC, "Removing UE %x instance after UE_CONTEXT_RELEASE_Complete (ue_release_timer_rrc timeout)\n",
+              ue_context_p->ue_context.rnti);
+        ue_context_p->ue_context.ue_release_timer_rrc = 0;
+
+        mac_remove_nr_ue(ctxt_pP->module_id, ctxt_pP->rnti);
+        rrc_rlc_remove_ue(ctxt_pP);
+        pdcp_remove_UE(ctxt_pP);
+
+        /* remove RRC UE Context */
+        ue_context_p = rrc_gNB_get_ue_context(RC.nrrrc[ctxt_pP->module_id], ctxt_pP->rnti);
+        if (ue_context_p) {
+          rrc_gNB_remove_ue_context(ctxt_pP, RC.nrrrc[ctxt_pP->module_id], ue_context_p);
+          LOG_I(NR_RRC, "remove UE %x \n", ctxt_pP->rnti);
+        }
+
+        break; // break RB_FOREACH
+      }
+    }
+  }
+
+  if (fd) fclose(fd);
 
   /* send a tick to x2ap */
   if (is_x2ap_enabled()){
@@ -2790,7 +3128,6 @@ void *rrc_gnb_task(void *args_p) {
   int                                result;
   //SRB_INFO                           *srb_info_p;
   //int                                CC_id;
-
   protocol_ctxt_t ctxt={.module_id=0,
                         .enb_flag=1,
                         .instance=0,
@@ -2801,7 +3138,6 @@ void *rrc_gnb_task(void *args_p) {
                         .configured=true,
                         .brOption=false
                        };
-
   itti_mark_task_ready(TASK_RRC_GNB);
   LOG_I(NR_RRC,"Entering main loop of NR_RRC message task\n");
 
@@ -3242,11 +3578,13 @@ rrc_gNB_generate_RRCRelease(
     itti_send_msg_to_task (TASK_RRC_UE_SIM, ctxt_pP->instance, message_p);
 #else
   if (NODE_IS_CU(RC.nrrrc[ctxt_pP->module_id]->node_type)) {
+    uint8_t *message_buffer = itti_malloc (TASK_RRC_GNB, TASK_CU_F1, size);
+    memcpy (message_buffer, buffer, size);
     MessageDef *m = itti_alloc_new_message(TASK_RRC_GNB, 0, F1AP_UE_CONTEXT_RELEASE_CMD);
     F1AP_UE_CONTEXT_RELEASE_CMD(m).rnti = ctxt_pP->rnti;
     F1AP_UE_CONTEXT_RELEASE_CMD(m).cause = F1AP_CAUSE_RADIO_NETWORK;
     F1AP_UE_CONTEXT_RELEASE_CMD(m).cause_value = 10; // 10 = F1AP_CauseRadioNetwork_normal_release
-    F1AP_UE_CONTEXT_RELEASE_CMD(m).rrc_container = buffer;
+    F1AP_UE_CONTEXT_RELEASE_CMD(m).rrc_container = message_buffer;
     F1AP_UE_CONTEXT_RELEASE_CMD(m).rrc_container_length = size;
     itti_send_msg_to_task(TASK_CU_F1, ctxt_pP->module_id, m);
   } else {
@@ -3257,6 +3595,9 @@ rrc_gNB_generate_RRCRelease(
                  size,
                  buffer,
                  PDCP_TRANSMISSION_MODE_CONTROL);
+
+    rrc_gNB_send_NGAP_UE_CONTEXT_RELEASE_COMPLETE(ctxt_pP->instance, ue_context_pP->ue_context.gNB_ue_ngap_id);
+    ue_context_pP->ue_context.ue_release_timer_rrc = 1;
   }
 #endif
 }
diff --git a/openair2/RRC/NR/rrc_gNB_NGAP.c b/openair2/RRC/NR/rrc_gNB_NGAP.c
index 619880da59821a7eb364475715be46ed314b8b97..b7f9d2c671f9653de39bf1c4dd4a6ce5a12d0021 100644
--- a/openair2/RRC/NR/rrc_gNB_NGAP.c
+++ b/openair2/RRC/NR/rrc_gNB_NGAP.c
@@ -57,6 +57,8 @@
 #include "RRC/NR/MESSAGES/asn1_msg.h"
 #include "NR_UERadioAccessCapabilityInformation.h"
 #include "NR_UE-CapabilityRAT-ContainerList.h"
+#include "NGAP_Cause.h"
+#include "NGAP_CauseRadioNetwork.h"
 #include "f1ap_messages_types.h"
 
 extern RAN_CONTEXT_t RC;
@@ -352,8 +354,8 @@ nr_rrc_pdcp_config_security(
     if (print_keys == 1 ) {
       print_keys =0;
       LOG_DUMPMSG(NR_RRC, DEBUG_SECURITY, ue_context_pP->ue_context.kgnb, 32,"\nKgNB:" );
-      LOG_DUMPMSG(NR_RRC, DEBUG_SECURITY, kRRCenc, 32,"\nKRRCenc:" );
-      LOG_DUMPMSG(NR_RRC, DEBUG_SECURITY, kRRCint, 32,"\nKRRCint:" );
+      LOG_DUMPMSG(NR_RRC, DEBUG_SECURITY, kRRCenc, 16,"\nKRRCenc:" );
+      LOG_DUMPMSG(NR_RRC, DEBUG_SECURITY, kRRCint, 16,"\nKRRCint:" );
     }
   }
 
@@ -504,6 +506,10 @@ rrc_gNB_process_NGAP_INITIAL_CONTEXT_SETUP_REQ(
     rrc_gNB_ue_context_t            *ue_context_p = NULL;
     protocol_ctxt_t                 ctxt;
     uint8_t                         pdu_sessions_done = 0;
+    gtpv1u_gnb_create_tunnel_req_t  create_tunnel_req;
+    gtpv1u_gnb_create_tunnel_resp_t create_tunnel_resp;
+    uint8_t                         inde_list[NR_NB_RB_MAX - 3]= {0};
+    int                             ret = 0;
 
     ue_initial_id  = NGAP_INITIAL_CONTEXT_SETUP_REQ(msg_p).ue_initial_id;
     gNB_ue_ngap_id = NGAP_INITIAL_CONTEXT_SETUP_REQ(msg_p).gNB_ue_ngap_id;
@@ -527,28 +533,64 @@ rrc_gNB_process_NGAP_INITIAL_CONTEXT_SETUP_REQ(
       ue_context_p->ue_context.amf_ue_ngap_id = NGAP_INITIAL_CONTEXT_SETUP_REQ (msg_p).amf_ue_ngap_id;
       ue_context_p->ue_context.nas_pdu_flag = NGAP_INITIAL_CONTEXT_SETUP_REQ (msg_p).nas_pdu_flag;
 
-      if (NGAP_INITIAL_CONTEXT_SETUP_REQ(msg_p).nb_of_pdusessions != 0) {
-        ue_context_p->ue_context.nb_of_pdusessions = NGAP_INITIAL_CONTEXT_SETUP_REQ(msg_p).nb_of_pdusessions;
+      uint8_t nb_pdusessions_tosetup = NGAP_INITIAL_CONTEXT_SETUP_REQ (msg_p).nb_of_pdusessions;
+      if (nb_pdusessions_tosetup != 0) {
+        memset(&create_tunnel_req, 0, sizeof(gtpv1u_gnb_create_tunnel_req_t));
         for (int i = 0; i < NR_NB_RB_MAX - 3; i++) {
-          if(ue_context_p->ue_context.pdusession[i].status >= PDU_SESSION_STATUS_DONE)
-              continue;
-            ue_context_p->ue_context.pdusession[i].status = PDU_SESSION_STATUS_NEW;
-            ue_context_p->ue_context.pdusession[i].param  = NGAP_INITIAL_CONTEXT_SETUP_REQ (msg_p).pdusession_param[pdu_sessions_done];
-            pdu_sessions_done++;
+          if(ue_context_p->ue_context.pduSession[i].status >= PDU_SESSION_STATUS_DONE)
+            continue;
+          ue_context_p->ue_context.pduSession[i].status        = PDU_SESSION_STATUS_NEW;
+          ue_context_p->ue_context.pduSession[i].param         = NGAP_INITIAL_CONTEXT_SETUP_REQ (msg_p).pdusession_param[pdu_sessions_done];
+          create_tunnel_req.pdusession_id[pdu_sessions_done]   = NGAP_INITIAL_CONTEXT_SETUP_REQ (msg_p).pdusession_param[pdu_sessions_done].pdusession_id;
+          create_tunnel_req.upf_NGu_teid[pdu_sessions_done]    = NGAP_INITIAL_CONTEXT_SETUP_REQ (msg_p).pdusession_param[pdu_sessions_done].gtp_teid;
+          create_tunnel_req.upf_addr[pdu_sessions_done].length = NGAP_INITIAL_CONTEXT_SETUP_REQ (msg_p).pdusession_param[pdu_sessions_done].upf_addr.length;
+          memcpy(create_tunnel_req.upf_addr[pdu_sessions_done].buffer,
+                  NGAP_INITIAL_CONTEXT_SETUP_REQ (msg_p).pdusession_param[pdu_sessions_done].upf_addr.buffer,
+                  sizeof(uint8_t)*20);
+          LOG_I(NR_RRC, "PDUSESSION SETUP: local index %d teid %u, pdusession id %d \n",
+                i,
+                create_tunnel_req.upf_NGu_teid[pdu_sessions_done],
+                create_tunnel_req.pdusession_id[pdu_sessions_done]);
+          inde_list[pdu_sessions_done] = i;
+          pdu_sessions_done++;
+
+          if(pdu_sessions_done >= nb_pdusessions_tosetup) {
+            break;
+          }
+        }
 
-            // TODO establish PDU SESSION
+        ue_context_p->ue_context.nb_of_pdusessions = NGAP_INITIAL_CONTEXT_SETUP_REQ (msg_p).nb_of_pdusessions;
+        create_tunnel_req.rnti                     = ue_context_p->ue_context.rnti;
+        create_tunnel_req.num_tunnels              = pdu_sessions_done;
 
-            if(pdu_sessions_done >= NGAP_INITIAL_CONTEXT_SETUP_REQ(msg_p).nb_of_pdusessions) {
-              break;
-            }
+        ret = gtpv1u_create_ngu_tunnel(
+                instance,
+                &create_tunnel_req,
+                &create_tunnel_resp);
+        if (ret != 0) {
+          LOG_E(NR_RRC,"rrc_gNB_process_NGAP_INITIAL_CONTEXT_SETUP_REQ : gtpv1u_create_ngu_tunnel failed,start to release UE %x\n",ue_context_p->ue_context.rnti);
+          ue_context_p->ue_context.ue_release_timer_ng = 1;
+          ue_context_p->ue_context.ue_release_timer_thres_ng = 100;
+          ue_context_p->ue_context.ue_release_timer = 0;
+          ue_context_p->ue_context.ue_reestablishment_timer = 0;
+          ue_context_p->ue_context.ul_failure_timer = 20000;
+          ue_context_p->ue_context.ul_failure_timer = 0;
+          return (0);
         }
+
+        nr_rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP(
+          &ctxt,
+          &create_tunnel_resp,
+          &inde_list[0]);
+        ue_context_p->ue_context.setup_pdu_sessions += nb_pdusessions_tosetup;
+        ue_context_p->ue_context.established_pdu_sessions_flag = 1;
       }
 
       /* NAS PDU */
-      ue_context_p->ue_context.nas_pdu_flag = NGAP_INITIAL_CONTEXT_SETUP_REQ(msg_p).nas_pdu_flag;
-      if (ue_context_p->ue_context.nas_pdu_flag == 1) {
-          ue_context_p->ue_context.nas_pdu.length = NGAP_INITIAL_CONTEXT_SETUP_REQ(msg_p).nas_pdu.length;
-          ue_context_p->ue_context.nas_pdu.buffer = NGAP_INITIAL_CONTEXT_SETUP_REQ(msg_p).nas_pdu.buffer;
+      if (NGAP_INITIAL_CONTEXT_SETUP_REQ(msg_p).nas_pdu_flag == 1) {
+        ue_context_p->ue_context.nas_pdu_flag   = NGAP_INITIAL_CONTEXT_SETUP_REQ(msg_p).nas_pdu_flag;
+        ue_context_p->ue_context.nas_pdu.length = NGAP_INITIAL_CONTEXT_SETUP_REQ(msg_p).nas_pdu.length;
+        ue_context_p->ue_context.nas_pdu.buffer = NGAP_INITIAL_CONTEXT_SETUP_REQ(msg_p).nas_pdu.buffer;
       }
         
       /* security */
@@ -598,25 +640,34 @@ rrc_gNB_send_NGAP_INITIAL_CONTEXT_SETUP_RESP(
 {
   MessageDef      *msg_p         = NULL;
   int pdusession;
-  int e_rabs_done = 0;
-  int e_rabs_failed = 0;
+  int pdu_sessions_done = 0;
+  int pdu_sessions_failed = 0;
+  int qos_flow_index = 0;
   msg_p = itti_alloc_new_message (TASK_RRC_ENB, 0, NGAP_INITIAL_CONTEXT_SETUP_RESP);
   NGAP_INITIAL_CONTEXT_SETUP_RESP (msg_p).gNB_ue_ngap_id = ue_context_pP->ue_context.gNB_ue_ngap_id;
 
   for (pdusession = 0; pdusession < ue_context_pP->ue_context.nb_of_pdusessions; pdusession++) {
-    if (ue_context_pP->ue_context.pdusession[pdusession].status == E_RAB_STATUS_DONE) {
-      e_rabs_done++;
-      NGAP_INITIAL_CONTEXT_SETUP_RESP (msg_p).pdusessions[pdusession].pdusession_id = ue_context_pP->ue_context.pdusession[pdusession].param.pdusession_id;
+    if (ue_context_pP->ue_context.pduSession[pdusession].status == PDU_SESSION_STATUS_DONE) {
+      pdu_sessions_done++;
+      NGAP_INITIAL_CONTEXT_SETUP_RESP (msg_p).pdusessions[pdusession].pdusession_id = ue_context_pP->ue_context.pduSession[pdusession].param.pdusession_id;
       // TODO add other information from S1-U when it will be integrated
       NGAP_INITIAL_CONTEXT_SETUP_RESP (msg_p).pdusessions[pdusession].gtp_teid = ue_context_pP->ue_context.gnb_gtp_teid[pdusession];
       memcpy(NGAP_INITIAL_CONTEXT_SETUP_RESP (msg_p).pdusessions[pdusession].gNB_addr.buffer , ue_context_pP->ue_context.gnb_gtp_addrs[pdusession].buffer, 20);
       NGAP_INITIAL_CONTEXT_SETUP_RESP (msg_p).pdusessions[pdusession].gNB_addr.length = 4;
-      ue_context_pP->ue_context.pdusession[pdusession].status = E_RAB_STATUS_ESTABLISHED;
+      ue_context_pP->ue_context.pduSession[pdusession].status = PDU_SESSION_STATUS_ESTABLISHED;
+      NGAP_INITIAL_CONTEXT_SETUP_RESP (msg_p).pdusessions[pdusession].nb_of_qos_flow = ue_context_pP->ue_context.pduSession[pdusession].param.nb_qos;
+      for (qos_flow_index = 0; qos_flow_index < ue_context_pP->ue_context.pduSession[pdusession].param.nb_qos; qos_flow_index++) {
+        NGAP_INITIAL_CONTEXT_SETUP_RESP (msg_p).pdusessions[pdusession].associated_qos_flows[qos_flow_index].qfi =
+            ue_context_pP->ue_context.pduSession[pdusession].param.qos[qos_flow_index].qfi;
+        NGAP_INITIAL_CONTEXT_SETUP_RESP (msg_p).pdusessions[pdusession].associated_qos_flows[qos_flow_index].qos_flow_mapping_ind = QOSFLOW_MAPPING_INDICATION_DL;
+      }
     } else {
-      e_rabs_failed++;
-      ue_context_pP->ue_context.pdusession[pdusession].status = E_RAB_STATUS_FAILED;
-      NGAP_INITIAL_CONTEXT_SETUP_RESP (msg_p).pdusessions_failed[pdusession].pdusession_id = ue_context_pP->ue_context.pdusession[pdusession].param.pdusession_id;
+      pdu_sessions_failed++;
+      ue_context_pP->ue_context.pduSession[pdusession].status = PDU_SESSION_STATUS_FAILED;
+      NGAP_INITIAL_CONTEXT_SETUP_RESP (msg_p).pdusessions_failed[pdusession].pdusession_id = ue_context_pP->ue_context.pduSession[pdusession].param.pdusession_id;
       // TODO add cause when it will be integrated
+      NGAP_INITIAL_CONTEXT_SETUP_RESP (msg_p).pdusessions_failed[pdusession].cause = NGAP_Cause_PR_radioNetwork;
+      NGAP_INITIAL_CONTEXT_SETUP_RESP (msg_p).pdusessions_failed[pdusession].cause_value = NGAP_CauseRadioNetwork_unknown_PDU_session_ID;
     }
   }
 
@@ -629,9 +680,9 @@ rrc_gNB_send_NGAP_INITIAL_CONTEXT_SETUP_RESP(
     MSC_AS_TIME_ARGS(ctxt_pP),
     ue_context_pP->ue_id_rnti,
     NGAP_INITIAL_CONTEXT_SETUP_RESP (msg_p).gNB_ue_ngap_id,
-    e_rabs_done, e_rabs_failed);
-  NGAP_INITIAL_CONTEXT_SETUP_RESP (msg_p).nb_of_pdusessions = e_rabs_done;
-  NGAP_INITIAL_CONTEXT_SETUP_RESP (msg_p).nb_of_pdusessions_failed = e_rabs_failed;
+    pdu_sessions_done, pdu_sessions_failed);
+  NGAP_INITIAL_CONTEXT_SETUP_RESP (msg_p).nb_of_pdusessions = pdu_sessions_done;
+  NGAP_INITIAL_CONTEXT_SETUP_RESP (msg_p).nb_of_pdusessions_failed = pdu_sessions_failed;
   itti_send_msg_to_task (TASK_NGAP, ctxt_pP->instance, msg_p);
 }
 
@@ -902,10 +953,10 @@ rrc_gNB_send_NGAP_PDUSESSION_SETUP_RESP(
 
   for (pdusession = 0; pdusession < ue_context_pP->ue_context.setup_pdu_sessions; pdusession++) {
     // if (xid == ue_context_pP->ue_context.pdusession[pdusession].xid) {
-      if (ue_context_pP->ue_context.pdusession[pdusession].status == PDU_SESSION_STATUS_DONE) {
-        NGAP_PDUSESSION_SETUP_RESP(msg_p).pdusessions[pdusession].pdusession_id = ue_context_pP->ue_context.pdusession[pdusession].param.pdusession_id;
+      if (ue_context_pP->ue_context.pduSession[pdusession].status == PDU_SESSION_STATUS_DONE) {
+        NGAP_PDUSESSION_SETUP_RESP(msg_p).pdusessions[pdusession].pdusession_id = ue_context_pP->ue_context.pduSession[pdusession].param.pdusession_id;
         // NGAP_PDUSESSION_SETUP_RESP(msg_p).pdusessions[pdusession].pdusession_id = 1;
-        NGAP_PDUSESSION_SETUP_RESP(msg_p).pdusessions[pdusession].nb_of_qos_flow = ue_context_pP->ue_context.pdusession[pdusession].param.nb_qos;
+        NGAP_PDUSESSION_SETUP_RESP(msg_p).pdusessions[pdusession].nb_of_qos_flow = ue_context_pP->ue_context.pduSession[pdusession].param.nb_qos;
         NGAP_PDUSESSION_SETUP_RESP(msg_p).pdusessions[pdusession].gtp_teid = ue_context_pP->ue_context.gnb_gtp_teid[pdusession];
         NGAP_PDUSESSION_SETUP_RESP(msg_p).pdusessions[pdusession].gNB_addr.pdu_session_type = PDUSessionType_ipv4;
         NGAP_PDUSESSION_SETUP_RESP(msg_p).pdusessions[pdusession].gNB_addr.length = ue_context_pP->ue_context.gnb_gtp_addrs[pdusession].length;
@@ -913,13 +964,13 @@ rrc_gNB_send_NGAP_PDUSESSION_SETUP_RESP(
                 ue_context_pP->ue_context.gnb_gtp_addrs[pdusession].buffer, sizeof(uint8_t)*20);
         for (qos_flow_index = 0; qos_flow_index < NGAP_PDUSESSION_SETUP_RESP(msg_p).pdusessions[pdusession].nb_of_qos_flow; qos_flow_index++) {
           NGAP_PDUSESSION_SETUP_RESP(msg_p).pdusessions[pdusession].associated_qos_flows[qos_flow_index].qfi =
-            ue_context_pP->ue_context.pdusession[pdusession].param.qos[qos_flow_index].qfi;
+            ue_context_pP->ue_context.pduSession[pdusession].param.qos[qos_flow_index].qfi;
           NGAP_PDUSESSION_SETUP_RESP(msg_p).pdusessions[pdusession].associated_qos_flows[qos_flow_index].qos_flow_mapping_ind = QOSFLOW_MAPPING_INDICATION_DL;
         }
 
-        ue_context_pP->ue_context.pdusession[pdusession].status = PDU_SESSION_STATUS_ESTABLISHED;
+        ue_context_pP->ue_context.pduSession[pdusession].status = PDU_SESSION_STATUS_ESTABLISHED;
         LOG_I (NR_RRC,"gnb_gtp_addr (msg index %d, pdu_sessions index %d, status %d, xid %d): nb_of_pdusessions %d,  pdusession_id %d, teid: %u, addr: %d.%d.%d.%d \n ",
-               pdu_sessions_done, pdusession, ue_context_pP->ue_context.pdusession[pdusession].status, xid,
+               pdu_sessions_done, pdusession, ue_context_pP->ue_context.pduSession[pdusession].status, xid,
                ue_context_pP->ue_context.nb_of_pdusessions,
                NGAP_PDUSESSION_SETUP_RESP (msg_p).pdusessions[pdu_sessions_done].pdusession_id,
                NGAP_PDUSESSION_SETUP_RESP (msg_p).pdusessions[pdu_sessions_done].gtp_teid,
@@ -928,12 +979,12 @@ rrc_gNB_send_NGAP_PDUSESSION_SETUP_RESP(
                NGAP_PDUSESSION_SETUP_RESP (msg_p).pdusessions[pdu_sessions_done].gNB_addr.buffer[2],
                NGAP_PDUSESSION_SETUP_RESP (msg_p).pdusessions[pdu_sessions_done].gNB_addr.buffer[3]);
         pdu_sessions_done++;
-      } else if ((ue_context_pP->ue_context.pdusession[pdusession].status == PDU_SESSION_STATUS_NEW) ||
-                 (ue_context_pP->ue_context.pdusession[pdusession].status == PDU_SESSION_STATUS_ESTABLISHED)) {
+      } else if ((ue_context_pP->ue_context.pduSession[pdusession].status == PDU_SESSION_STATUS_NEW) ||
+                 (ue_context_pP->ue_context.pduSession[pdusession].status == PDU_SESSION_STATUS_ESTABLISHED)) {
         LOG_D (NR_RRC,"PDU-SESSION is NEW or already ESTABLISHED\n");
       } else { /* to be improved */
-        ue_context_pP->ue_context.pdusession[pdusession].status = PDU_SESSION_STATUS_FAILED;
-        NGAP_PDUSESSION_SETUP_RESP (msg_p).pdusessions_failed[pdu_sessions_failed].pdusession_id = ue_context_pP->ue_context.pdusession[pdusession].param.pdusession_id;
+        ue_context_pP->ue_context.pduSession[pdusession].status = PDU_SESSION_STATUS_FAILED;
+        NGAP_PDUSESSION_SETUP_RESP (msg_p).pdusessions_failed[pdu_sessions_failed].pdusession_id = ue_context_pP->ue_context.pduSession[pdusession].param.pdusession_id;
         pdu_sessions_failed++;
         // TODO add cause when it will be integrated
       }
@@ -962,7 +1013,7 @@ rrc_gNB_send_NGAP_PDUSESSION_SETUP_RESP(
   }
 
   for(int i = 0; i < NB_RB_MAX; i++) {
-    ue_context_pP->ue_context.pdusession[i].xid = -1;
+    ue_context_pP->ue_context.pduSession[i].xid = -1;
   }
 
   return;
@@ -1008,20 +1059,20 @@ rrc_gNB_process_NGAP_PDUSESSION_SETUP_REQ(
 
     PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, GNB_FLAG_YES, ue_context_p->ue_context.rnti, 0, 0);
     for (int i = 0; i < NR_NB_RB_MAX - 3; i++) {
-      if(ue_context_p->ue_context.pdusession[i].status >= PDU_SESSION_STATUS_DONE)
+      if(ue_context_p->ue_context.pduSession[i].status >= PDU_SESSION_STATUS_DONE)
         continue;
-      ue_context_p->ue_context.pdusession[i].status      = PDU_SESSION_STATUS_NEW;
-      ue_context_p->ue_context.pdusession[i].param       = NGAP_PDUSESSION_SETUP_REQ(msg_p).pdusession_setup_params[pdu_sessions_done];
+      ue_context_p->ue_context.pduSession[i].status      = PDU_SESSION_STATUS_NEW;
+      ue_context_p->ue_context.pduSession[i].param       = NGAP_PDUSESSION_SETUP_REQ(msg_p).pdusession_setup_params[pdu_sessions_done];
       create_tunnel_req.pdusession_id[pdu_sessions_done] = NGAP_PDUSESSION_SETUP_REQ(msg_p).pdusession_setup_params[pdu_sessions_done].pdusession_id;
       create_tunnel_req.upf_NGu_teid[pdu_sessions_done]  = NGAP_PDUSESSION_SETUP_REQ(msg_p).pdusession_setup_params[pdu_sessions_done].gtp_teid;
       memcpy(create_tunnel_req.upf_addr[pdu_sessions_done].buffer,
-              NGAP_PDUSESSION_SETUP_REQ(msg_p).pdusession_setup_params[i].upf_addr.buffer,
+              NGAP_PDUSESSION_SETUP_REQ(msg_p).pdusession_setup_params[pdu_sessions_done].upf_addr.buffer,
               sizeof(uint8_t)*20);
-      create_tunnel_req.upf_addr[pdu_sessions_done].length = NGAP_PDUSESSION_SETUP_REQ(msg_p).pdusession_setup_params[i].upf_addr.length;
+      create_tunnel_req.upf_addr[pdu_sessions_done].length = NGAP_PDUSESSION_SETUP_REQ(msg_p).pdusession_setup_params[pdu_sessions_done].upf_addr.length;
       LOG_I(NR_RRC,"NGAP PDUSESSION SETUP REQ: local index %d teid %u, pdusession id %d \n",
             i,
-            create_tunnel_req.upf_NGu_teid[i],
-            create_tunnel_req.pdusession_id[i]);
+            create_tunnel_req.upf_NGu_teid[pdu_sessions_done],
+            create_tunnel_req.pdusession_id[pdu_sessions_done]);
       inde_list[pdu_sessions_done] = i;
       pdu_sessions_done++;
 
@@ -1089,7 +1140,7 @@ rrc_gNB_send_NGAP_UE_CONTEXT_RELEASE_REQ(
     NGAP_UE_CONTEXT_RELEASE_REQ(msg_context_release_req_p).cause_value       = cause_valueP;
     NGAP_UE_CONTEXT_RELEASE_REQ(msg_context_release_req_p).nb_of_pdusessions = ue_context_pP->ue_context.setup_pdu_sessions;
     for (int pdusession = 0; pdusession < ue_context_pP->ue_context.setup_pdu_sessions; pdusession++) {
-      NGAP_UE_CONTEXT_RELEASE_REQ(msg_context_release_req_p).pdusessions[pdusession].pdusession_id = ue_context_pP->ue_context.pdusession[pdusession].param.pdusession_id;
+      NGAP_UE_CONTEXT_RELEASE_REQ(msg_context_release_req_p).pdusessions[pdusession].pdusession_id = ue_context_pP->ue_context.pduSession[pdusession].param.pdusession_id;
     }
     itti_send_msg_to_task(TASK_NGAP, GNB_MODULE_ID_TO_INSTANCE(gnb_mod_idP), msg_context_release_req_p);
   }
@@ -1174,11 +1225,25 @@ rrc_gNB_process_NGAP_UE_CONTEXT_RELEASE_COMMAND(
     return -1;
   } else {
     ue_context_p->ue_context.ue_release_timer_ng = 0;
+    ue_context_p->ue_context.ue_release_timer_thres_rrc = 1000;
     PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, GNB_FLAG_YES, ue_context_p->ue_context.rnti, 0, 0);
+    ctxt.eNB_index = 0;
     rrc_gNB_generate_RRCRelease(&ctxt, ue_context_p);
     return 0;
   }
 }
+
+void rrc_gNB_send_NGAP_UE_CONTEXT_RELEASE_COMPLETE(
+  instance_t instance,
+  uint32_t   gNB_ue_ngap_id) {
+  MSC_LOG_TX_MESSAGE(MSC_RRC_GNB, MSC_NGAP_GNB, NULL, 0,
+                     "0 NGAP_UE_CONTEXT_RELEASE_COMPLETE gNB_ue_ngap_id 0x%06"PRIX32" ",
+                     gNB_ue_ngap_id);
+  MessageDef *msg = itti_alloc_new_message(TASK_RRC_GNB, 0, NGAP_UE_CONTEXT_RELEASE_COMPLETE);
+  NGAP_UE_CONTEXT_RELEASE_COMPLETE(msg).gNB_ue_ngap_id = gNB_ue_ngap_id;
+  itti_send_msg_to_task(TASK_NGAP, instance, msg);
+}
+
 //------------------------------------------------------------------------------
 /*
 * Remove UE ids (ue_initial_id and ng_id) from hashtables.
@@ -1288,12 +1353,12 @@ rrc_gNB_send_NGAP_PDUSESSION_RELEASE_RESPONSE(
   NGAP_PDUSESSION_RELEASE_RESPONSE (msg_p).gNB_ue_ngap_id = ue_context_pP->ue_context.gNB_ue_ngap_id;
 
   for (int i = 0;  i < NB_RB_MAX; i++) {
-    if (xid == ue_context_pP->ue_context.pdusession[i].xid) {
+    if (xid == ue_context_pP->ue_context.pduSession[i].xid) {
       NGAP_PDUSESSION_RELEASE_RESPONSE (msg_p).pdusession_release[pdu_sessions_released].pdusession_id =
-          ue_context_pP->ue_context.pdusession[i].param.pdusession_id;
+          ue_context_pP->ue_context.pduSession[i].param.pdusession_id;
       pdu_sessions_released++;
       //clear
-      memset(&ue_context_pP->ue_context.pdusession[i], 0, sizeof(pdu_session_param_t));
+      memset(&ue_context_pP->ue_context.pduSession[i], 0, sizeof(pdu_session_param_t));
     }
   }
 
@@ -1309,7 +1374,7 @@ rrc_gNB_send_NGAP_PDUSESSION_RELEASE_RESPONSE(
 
   //clear xid
   for(int i = 0; i < NB_RB_MAX; i++) {
-    ue_context_pP->ue_context.pdusession[i].xid = -1;
+    ue_context_pP->ue_context.pduSession[i].xid = -1;
   }
 
   //clear release pdusessions
@@ -1370,7 +1435,7 @@ rrc_gNB_process_NGAP_PDUSESSION_RELEASE_COMMAND(
       }
 
       for (i = 0;  i < NR_NB_RB_MAX; i++) {
-        if (pdusession_release_params[pdusession].pdusession_id == ue_context_p->ue_context.pdusession[i].param.pdusession_id) {
+        if (pdusession_release_params[pdusession].pdusession_id == ue_context_p->ue_context.pduSession[i].param.pdusession_id) {
           b_existed = 1;
           break;
         }
@@ -1384,13 +1449,13 @@ rrc_gNB_process_NGAP_PDUSESSION_RELEASE_COMMAND(
         ue_context_p->ue_context.pdusessions_release_failed[ue_context_p->ue_context.nb_release_of_pdusessions].cause_value = 30;
         ue_context_p->ue_context.nb_release_of_pdusessions++;
       } else {
-        if(ue_context_p->ue_context.pdusession[i].status == PDU_SESSION_STATUS_FAILED) {
-          ue_context_p->ue_context.pdusession[i].xid = xid;
+        if(ue_context_p->ue_context.pduSession[i].status == PDU_SESSION_STATUS_FAILED) {
+          ue_context_p->ue_context.pduSession[i].xid = xid;
           continue;
-        } else if(ue_context_p->ue_context.pdusession[i].status == PDU_SESSION_STATUS_ESTABLISHED) {
-          LOG_I(NR_RRC, "RELEASE pdusession %d \n", ue_context_p->ue_context.pdusession[i].param.pdusession_id);
-          ue_context_p->ue_context.pdusession[i].status = PDU_SESSION_STATUS_TORELEASE;
-          ue_context_p->ue_context.pdusession[i].xid = xid;
+        } else if(ue_context_p->ue_context.pduSession[i].status == PDU_SESSION_STATUS_ESTABLISHED) {
+          LOG_I(NR_RRC, "RELEASE pdusession %d \n", ue_context_p->ue_context.pduSession[i].param.pdusession_id);
+          ue_context_p->ue_context.pduSession[i].status = PDU_SESSION_STATUS_TORELEASE;
+          ue_context_p->ue_context.pduSession[i].xid = xid;
           pdusession_release_drb++;
         } else {
           // pdusession_id status NG
@@ -1414,7 +1479,7 @@ rrc_gNB_process_NGAP_PDUSESSION_RELEASE_COMMAND(
       GTPV1U_GNB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).rnti = ue_context_p->ue_context.rnti;
 
       for(i = 0; i < NB_RB_MAX; i++) {
-        if(xid == ue_context_p->ue_context.pdusession[i].xid) {
+        if(xid == ue_context_p->ue_context.pduSession[i].xid) {
           GTPV1U_GNB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).pdusession_id[GTPV1U_GNB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).num_pdusession++] = ue_context_p->ue_context.gnb_gtp_psi[i];
           ue_context_p->ue_context.gnb_gtp_teid[i] = 0;
           memset(&ue_context_p->ue_context.gnb_gtp_addrs[i], 0, sizeof(ue_context_p->ue_context.gnb_gtp_addrs[i]));
diff --git a/openair2/RRC/NR/rrc_gNB_NGAP.h b/openair2/RRC/NR/rrc_gNB_NGAP.h
index f13c468f94f7141b28866725f9b2ae9aa67b4c80..8779d62ff6b37d9ff7a9464ea87eb1245a2a97a3 100644
--- a/openair2/RRC/NR/rrc_gNB_NGAP.h
+++ b/openair2/RRC/NR/rrc_gNB_NGAP.h
@@ -129,6 +129,10 @@ rrc_gNB_process_NGAP_UE_CONTEXT_RELEASE_COMMAND(
   instance_t instance
 );
 
+void rrc_gNB_send_NGAP_UE_CONTEXT_RELEASE_COMPLETE(
+  instance_t instance,
+  uint32_t   gNB_ue_ngap_id);
+
 void
 rrc_gNB_NGAP_remove_ue_ids(
   gNB_RRC_INST *const rrc_instance_pP,
diff --git a/openair2/RRC/NR/rrc_gNB_UE_context.c b/openair2/RRC/NR/rrc_gNB_UE_context.c
index 988db09cc1e2573cd14c3b8cec6a436ab837cf7d..eb7559f69d8c63fa27565df050e5f6114fdb022c 100644
--- a/openair2/RRC/NR/rrc_gNB_UE_context.c
+++ b/openair2/RRC/NR/rrc_gNB_UE_context.c
@@ -135,7 +135,7 @@ rrc_gNB_allocate_new_UE_context(
 
   for(int i = 0; i < NB_RB_MAX; i++) {
     new_p->ue_context.e_rab[i].xid = -1;
-    new_p->ue_context.pdusession[i].xid = -1;
+    new_p->ue_context.pduSession[i].xid = -1;
     new_p->ue_context.modify_e_rab[i].xid = -1;
   }
 
diff --git a/openair2/RRC/NR/rrc_gNB_reconfig.c b/openair2/RRC/NR/rrc_gNB_reconfig.c
index 3736ed52444b96d08cde297566d031aaf56b8aa8..64db21c967833746f4db88bd4293aca515ee3eb6 100644
--- a/openair2/RRC/NR/rrc_gNB_reconfig.c
+++ b/openair2/RRC/NR/rrc_gNB_reconfig.c
@@ -61,8 +61,15 @@ void fill_default_coresetZero(NR_ControlResourceSet_t *coreset0, NR_ServingCellC
 
   // frequencyDomainResources '11111111 00000000 00000000 00000000 00000000 00000'B,
   if(coreset0->frequencyDomainResources.buf == NULL) coreset0->frequencyDomainResources.buf = calloc(1,6);
-  coreset0->frequencyDomainResources.buf[0] = 0xff;
-  coreset0->frequencyDomainResources.buf[1] = 0;
+  int curr_bwp = NRRIV2BW(servingcellconfigcommon->downlinkConfigCommon->initialDownlinkBWP->genericParameters.locationAndBandwidth, 275);
+  if (curr_bwp < 48)
+    coreset0->frequencyDomainResources.buf[0] = 0xf0;
+  else
+    coreset0->frequencyDomainResources.buf[0] = 0xff;
+  if (curr_bwp < 96)
+    coreset0->frequencyDomainResources.buf[1] = 0;
+  else
+    coreset0->frequencyDomainResources.buf[1] = 0xff;
   coreset0->frequencyDomainResources.buf[2] = 0;
   coreset0->frequencyDomainResources.buf[3] = 0;
   coreset0->frequencyDomainResources.buf[4] = 0;
@@ -633,7 +640,10 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco
  }
  bwp->bwp_Dedicated->pdsch_Config->choice.setup->dataScramblingIdentityPDSCH = NULL;
 
- bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_Type=NULL;//calloc(1,sizeof(*bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_Type));
+ if (n_physical_antenna_ports > 1)// for MIMO, we use DMRS Config Type 2
+   bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_Type=calloc(1,sizeof(*bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_Type));
+ else
+   bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_Type=NULL;
  bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->maxLength=NULL;
  bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->scramblingID0=NULL;
  bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->scramblingID1=NULL;
diff --git a/openair2/RRC/NR_UE/rrc_UE.c b/openair2/RRC/NR_UE/rrc_UE.c
index cb8eca950495ae383867e4c4a52796c0a0325664..c988ec9b80202555d485462b95e2b9c84e58a340 100644
--- a/openair2/RRC/NR_UE/rrc_UE.c
+++ b/openair2/RRC/NR_UE/rrc_UE.c
@@ -69,9 +69,7 @@
 #include "SIMULATION/TOOLS/sim.h" // for taus
 #include <executables/softmodem-common.h>
 
-#if defined(ITTI_SIM) || defined(RFSIM_NAS)
 #include "nr_nas_msg_sim.h"
-#endif
 
 NR_UE_RRC_INST_t *NR_UE_rrc_inst;
 /* NAS Attach request with IMSI */
@@ -1267,16 +1265,34 @@ nr_rrc_ue_process_masterCellGroup(
     // NSA procedures
   }
 
+  if(NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config == NULL){
+    NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config = calloc(1,sizeof(NR_CellGroupConfig_t));
+  }
+
   if( cellGroupConfig->rlc_BearerToReleaseList != NULL){
     //TODO (perform RLC bearer release as specified in 5.3.5.5.3)
   }
 
   if( cellGroupConfig->rlc_BearerToAddModList != NULL){
     //TODO (perform the RLC bearer addition/modification as specified in 5.3.5.5.4)
+    if(NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config->rlc_BearerToAddModList != NULL){
+      free(NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config->rlc_BearerToAddModList);
+    }
+    NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config->rlc_BearerToAddModList = calloc(1, sizeof(struct NR_CellGroupConfig__rlc_BearerToAddModList));
+    memcpy(NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config->rlc_BearerToAddModList,cellGroupConfig->rlc_BearerToAddModList,
+                 sizeof(struct NR_CellGroupConfig__rlc_BearerToAddModList));
   }
 
   if( cellGroupConfig->mac_CellGroupConfig != NULL){
     //TODO (configure the MAC entity of this cell group as specified in 5.3.5.5.5)
+    LOG_I(RRC, "Received mac_CellGroupConfig from gNB\n");
+    if(NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config->mac_CellGroupConfig != NULL){
+      LOG_E(RRC, "UE RRC instance already contains mac CellGroupConfig which will be overwritten\n");
+      free(NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config->mac_CellGroupConfig);
+    }
+    NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config->mac_CellGroupConfig = malloc(sizeof(struct NR_MAC_CellGroupConfig));
+    memcpy(NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config->mac_CellGroupConfig,cellGroupConfig->mac_CellGroupConfig,
+                     sizeof(struct NR_MAC_CellGroupConfig));
   }
 
   if( cellGroupConfig->sCellToReleaseList != NULL){
@@ -1332,14 +1348,21 @@ static void rrc_ue_generate_RRCSetupComplete(
     AssertFatal(1==0,"2 > csi_MeasConfig is not null\n");
 
  if (AMF_MODE_ENABLED) {
-#if defined(ITTI_SIM) || defined(RFSIM_NAS)
+#if defined(ITTI_SIM)
     as_nas_info_t initialNasMsg;
-    generateRegistrationRequest(&initialNasMsg);
+    generateRegistrationRequest(&initialNasMsg, ctxt_pP->module_id);
     nas_msg = (char*)initialNasMsg.data;
     nas_msg_length = initialNasMsg.length;
 #else
-    nas_msg         = (char *) NR_UE_rrc_inst[ctxt_pP->module_id].initialNasMsg.data;
-    nas_msg_length  = NR_UE_rrc_inst[ctxt_pP->module_id].initialNasMsg.length;
+    if (get_softmodem_params()->sa) {
+      as_nas_info_t initialNasMsg;
+      generateRegistrationRequest(&initialNasMsg, ctxt_pP->module_id);
+      nas_msg = (char*)initialNasMsg.data;
+      nas_msg_length = initialNasMsg.length;
+    } else {
+      nas_msg         = (char *) NR_UE_rrc_inst[ctxt_pP->module_id].initialNasMsg.data;
+      nas_msg_length  = NR_UE_rrc_inst[ctxt_pP->module_id].initialNasMsg.length;
+    }
 #endif
   } else {
     nas_msg         = nr_nas_attach_req_imsi;
@@ -2115,28 +2138,27 @@ nr_rrc_ue_establish_srb2(
 	 (NR_UE_rrc_inst[ctxt_pP->module_id].integrityProtAlgorithm << 4));
 
        // Refresh DRBs
-       // nr_rrc_pdcp_config_asn1_req(ctxt_pP,
-       //                             NULL,
-       //                             radioBearerConfig->drb_ToAddModList,
-       //                             NULL,
-       //                             NR_UE_rrc_inst[ctxt_pP->module_id].cipheringAlgorithm |
-       //                             (NR_UE_rrc_inst[ctxt_pP->module_id].integrityProtAlgorithm << 4),
-       //                             NULL,
-       //                             NULL,
-       //                             kUPenc,
-       //                             NULL,
-       //                             NULL,
-       //                             NR_UE_rrc_inst[ctxt_pP->module_id].defaultDRB,
-       //                             NULL);
+        nr_rrc_pdcp_config_asn1_req(ctxt_pP,
+                                    NULL,
+                                    radioBearerConfig->drb_ToAddModList,
+                                    NULL,
+                                    0,
+                                    NULL,
+                                    NULL,
+                                    kUPenc,
+                                    NULL,
+                                    NULL,
+                                    NR_UE_rrc_inst[ctxt_pP->module_id].defaultDRB,
+                                    NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config->rlc_BearerToAddModList);
        // Refresh DRBs
-       // nr_rrc_rlc_config_asn1_req(ctxt_pP,
-       //                             NULL,
-       //                             radioBearerConfig->drb_ToAddModList,
-       //                             NULL,
-       //                             NULL,
-       //                             NULL
-       //                             );
-   } // drb_ToAddModList
+        nr_rrc_rlc_config_asn1_req(ctxt_pP,
+                                    NULL,
+                                    radioBearerConfig->drb_ToAddModList,
+                                    NULL,
+                                    NULL,
+                                    NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config->rlc_BearerToAddModList
+                                    );
+   } // drb_ToAddModList //
 
    if (radioBearerConfig->drb_ToReleaseList != NULL) {
      for (i = 0; i < radioBearerConfig->drb_ToReleaseList->list.count; i++) {
@@ -2171,9 +2193,16 @@ nr_rrc_ue_establish_srb2(
  //      nr_rrc_ue_process_measConfig(ctxt_pP, gNB_index, ie->measConfig);
      }
 
+     if(ie->nonCriticalExtension->masterCellGroup!=NULL) {
+       nr_rrc_ue_process_masterCellGroup(
+           ctxt_pP,
+           gNB_index,
+           ie->nonCriticalExtension->masterCellGroup);
+     }
+
      if (ie->radioBearerConfig != NULL) {
        LOG_I(NR_RRC, "radio Bearer Configuration is present\n");
- //      nr_sa_rrc_ue_process_radioBearerConfig(ctxt_pP, gNB_index, ie->radioBearerConfig);
+       nr_sa_rrc_ue_process_radioBearerConfig(ctxt_pP, gNB_index, ie->radioBearerConfig);
      }
 
      /* Check if there is dedicated NAS information to forward to NAS */
@@ -2255,8 +2284,7 @@ nr_rrc_ue_establish_srb2(
 
    if (Srb_id != 1) {
      LOG_E(NR_RRC,"[UE %d] Frame %d: Received message on DL-DCCH (SRB%ld), should not have ...\n",
-	 ctxt_pP->module_id, ctxt_pP->frame, Srb_id);
-     return -1;
+           ctxt_pP->module_id, ctxt_pP->frame, Srb_id);
    } else {
      LOG_D(NR_RRC, "Received message on SRB%ld\n", Srb_id);
    }
diff --git a/openair2/UTIL/OPT/README.txt b/openair2/UTIL/OPT/README.txt
index 2ac68f83fdbf1057f414e88a7559e6eb0c7345db..13ec727fd5a5b41c3cc4f0d58e6e543db92e0422 100644
--- a/openair2/UTIL/OPT/README.txt
+++ b/openair2/UTIL/OPT/README.txt
@@ -1,13 +1,14 @@
 
-How to configure wireshark for dissecting LTE protocols:
+How to configure wireshark for dissecting LTE/NR protocols:
 - start the wireshark as a sudoers
   - goto analyze->enabled prototols
-  => enable mac_lte_udp and rlc_lte_udp
+  => enable mac_xxx_udp and rlc_xxx_udp (xxx is lte or nr)
   - goto edit/preferences and expand Protocols
   - select UDP and check "try heuristic sub-dissectors first"
-  - select MAC-LTE, and check all the options (checkboxes), and set the "which layer info to show in info column" to "MAC info"
-    - select RLC-LTE, and check all the options except the "May see RLC headers only", and
+  - select MAC-LTE (or MAC-NR), and check all the options (checkboxes), and set the "which layer info to show in info column" to "MAC info"
+  - select RLC-LTE (or NR), and check all the options except the "May see RLC headers only", and
     set the "call PDCP dissector for DRB PDUs" to "12-bit SN". Optionally you may select the sequence analysis for RLC AM/UM.
+  - select PDCP-LTE (or NR)
 
     How to use
     - start eNB or UE with option --opt.type wireshark
diff --git a/openair2/UTIL/OPT/opt.h b/openair2/UTIL/OPT/opt.h
index ab591d3a6572c7c114149baa78e8509ee97b9ab7..ae6a3eb2a65fb4e8dac6eabaa69942381afbc445 100644
--- a/openair2/UTIL/OPT/opt.h
+++ b/openair2/UTIL/OPT/opt.h
@@ -59,7 +59,8 @@ typedef uint16_t guint16;
 typedef uint32_t guint32;
 typedef guint8   gboolean;
 
-#include "packet-mac-lte.h"
+#include <openair2/UTIL/OPT/wireshark_headers.h>
+
 #include "mac_pcap.h"
 
 /* OPT parameters definitions */
@@ -107,9 +108,10 @@ typedef enum radio_type_e {
 */
 
 extern int opt_enabled;
-#define trace_pdu(x...) if (opt_enabled) trace_pdu_implementation(x)
+#define trace_pdu(x...) if (opt_enabled) trace_pdu_implementation(0, x)
+#define trace_NRpdu(x...) if (opt_enabled) trace_pdu_implementation(1, x)
 
-void trace_pdu_implementation(int direction, uint8_t *pdu_buffer, unsigned int pdu_buffer_size,
+void trace_pdu_implementation(int nr, int direction, uint8_t *pdu_buffer, unsigned int pdu_buffer_size,
                               int ueid, int rntiType, int rnti, uint16_t sysFrame, uint8_t subframe,
                               int oob_event, int oob_event_value);
 
diff --git a/openair2/UTIL/OPT/packet-mac-lte.h b/openair2/UTIL/OPT/packet-mac-lte.h
deleted file mode 100644
index 2d36e02df4d580af33f9fa5423dc984480f2d47f..0000000000000000000000000000000000000000
--- a/openair2/UTIL/OPT/packet-mac-lte.h
+++ /dev/null
@@ -1,382 +0,0 @@
-/* packet-mac-lte.h
- *
- * Martin Mathieson
- *
- * Wireshark - Network traffic analyzer
- * By Gerald Combs <gerald@wireshark.org>
- * Copyright 1998 Gerald Combs
- *
- * SPDX-License-Identifier: GPL-2.0-or-later
- *
- * This header file may also be distributed under
- * the terms of the BSD Licence as follows:
- *
- * Copyright (C) 2009 Martin Mathieson. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-2-Clause
- */
- 
- /* 
- this is wireshark, commit: commit eda834b6e29c36e05a63a6056afa98390ff79357 
- Date:   Wed Aug 22 14:36:20 2018 +0200
- modified to be used in OpenAir to create the LTE MAC/RLC encapsulated in UDP as per Wireshark feature 
- */
-
-#ifndef __UTIL_OPT_PACKET_MAC_LTE__H__
-#define __UTIL_OPT_PACKET_MAC_LTE__H__
-
-#include "ws_symbol_export.h"
-
-/** data structure to hold time values with nanosecond resolution*/
-typedef struct {
-	time_t	secs;
-	int	nsecs;
-} nstime_t;
-
-
-/* radioType */
-#define FDD_RADIO 1
-#define TDD_RADIO 2
-
-/* Direction */
-#define DIRECTION_UPLINK   0
-#define DIRECTION_DOWNLINK 1
-
-/* rntiType */
-#define WS_NO_RNTI     0
-#define WS_P_RNTI      1
-#define WS_RA_RNTI     2
-#define WS_C_RNTI      3
-#define WS_SI_RNTI     4
-#define WS_SPS_RNTI    5
-#define WS_M_RNTI      6
-#define WS_SL_BCH_RNTI 7
-#define WS_SL_RNTI     8
-#define WS_SC_RNTI     9
-#define WS_G_RNTI      10
-
-typedef enum mac_lte_oob_event {
-    ltemac_send_preamble,
-    ltemac_send_sr,
-    ltemac_sr_failure
-} mac_lte_oob_event;
-
-typedef enum mac_lte_dl_retx {
-    dl_retx_no,
-    dl_retx_yes,
-    dl_retx_unknown
-} mac_lte_dl_retx;
-
-typedef enum mac_lte_crc_status {
-    crc_fail = 0,
-    crc_success = 1,
-    crc_high_code_rate = 2,
-    crc_pdsch_lost = 3,
-    crc_duplicate_nonzero_rv = 4,
-    crc_false_dci = 5
-} mac_lte_crc_status;
-
-/* N.B. for SCellIndex-r13 extends to 31 */
-typedef enum mac_lte_carrier_id {
-    carrier_id_primary,
-    carrier_id_secondary_1,
-    carrier_id_secondary_2,
-    carrier_id_secondary_3,
-    carrier_id_secondary_4,
-    carrier_id_secondary_5,
-    carrier_id_secondary_6,
-    carrier_id_secondary_7
-} mac_lte_carrier_id;
-
-typedef enum mac_lte_ce_mode {
-    no_ce_mode = 0,
-    ce_mode_a = 1,
-    ce_mode_b = 2
-} mac_lte_ce_mode;
-
-typedef enum mac_lte_nb_mode {
-    no_nb_mode = 0,
-    nb_mode = 1
-} mac_lte_nb_mode;
-
-/* Context info attached to each LTE MAC frame */
-typedef struct mac_lte_info
-{
-    /* Needed for decode */
-    guint8          radioType;
-    guint8          direction;
-    guint8          rntiType;
-
-    /* Extra info to display */
-    guint16         rnti;
-    guint16         ueid;
-
-    /* Timing info */
-    guint16         sysframeNumber;
-    guint16         subframeNumber;
-
-    /* Optional field. More interesting for TDD (FDD is always -4 subframeNumber) */
-    gboolean        subframeNumberOfGrantPresent;
-    guint16         subframeNumberOfGrant;
-
-    /* Flag set only if doing PHY-level data test - i.e. there may not be a
-       well-formed MAC PDU so just show as raw data */
-    gboolean        isPredefinedData;
-
-    /* Length of DL PDU or UL grant size in bytes */
-    guint16         length;
-
-    /* 0=newTx, 1=first-retx, etc */
-    guint8          reTxCount;
-    guint8          isPHICHNACK; /* FALSE=PDCCH retx grant, TRUE=PHICH NACK */
-
-    /* UL only.  Indicates if the R10 extendedBSR-Sizes parameter is set */
-    gboolean        isExtendedBSRSizes;
-
-    /* UL only.  Indicates if the R10 simultaneousPUCCH-PUSCH parameter is set for PCell */
-    gboolean        isSimultPUCCHPUSCHPCell;
-
-    /* UL only.  Indicates if the R10 extendedBSR-Sizes parameter is set for PSCell */
-    gboolean        isSimultPUCCHPUSCHPSCell;
-
-    /* Status of CRC check. For UE it is DL only. For eNodeB it is UL
-       only. For an analyzer, it is present for both DL and UL. */
-    gboolean        crcStatusValid;
-    mac_lte_crc_status crcStatus;
-
-    /* Carrier ID */
-    mac_lte_carrier_id   carrierId;
-
-    /* DL only.  Is this known to be a retransmission? */
-    mac_lte_dl_retx dl_retx;
-
-    /* DL only. CE mode to be used for RAR decoding */
-    mac_lte_ce_mode ceMode;
-
-    /* DL and UL. NB-IoT mode of the UE */
-    mac_lte_nb_mode nbMode;
-
-    /* UL only, for now used for CE mode A RAR decoding */
-    guint8          nUlRb;
-
-    /* More Physical layer info (see direction above for which side of union to use) */
-    union {
-        struct mac_lte_ul_phy_info
-        {
-            guint8 present;  /* Remaining UL fields are present and should be displayed */
-            guint8 modulation_type;
-            guint8 tbs_index;
-            guint8 resource_block_length;
-            guint8 resource_block_start;
-            guint8 harq_id;
-            gboolean ndi;
-        } ul_info;
-        struct mac_lte_dl_phy_info
-        {
-            guint8 present; /* Remaining DL fields are present and should be displayed */
-            guint8 dci_format;
-            guint8 resource_allocation_type;
-            guint8 aggregation_level;
-            guint8 mcs_index;
-            guint8 redundancy_version_index;
-            guint8 resource_block_length;
-            guint8 harq_id;
-            gboolean ndi;
-            guint8   transport_block;  /* 0..1 */
-        } dl_info;
-    } detailed_phy_info;
-
-    /* Relating to out-of-band events */
-    /* N.B. dissector will only look to these fields if length is 0... */
-    mac_lte_oob_event  oob_event;
-    guint8             rapid;
-    guint8             rach_attempt_number;
-    #define MAX_SRs 20
-    guint16            number_of_srs;
-    guint16            oob_ueid[MAX_SRs];
-    guint16            oob_rnti[MAX_SRs];
-} mac_lte_info;
-
-
-typedef struct mac_lte_tap_info {
-    /* Info from context */
-    guint16  rnti;
-    guint16  ueid;
-    guint8   rntiType;
-    guint8   isPredefinedData;
-    gboolean crcStatusValid;
-    mac_lte_crc_status   crcStatus;
-    guint8   direction;
-
-    guint8   isPHYRetx;
-    guint16  ueInTTI;
-
-    nstime_t mac_lte_time;
-
-    /* Number of bytes (which part is used depends upon context settings) */
-    guint32  single_number_of_bytes;
-    guint32  bytes_for_lcid[11];
-    guint32  sdus_for_lcid[11];
-    guint8   number_of_rars;
-    guint8   number_of_paging_ids;
-
-    /* Number of padding bytes includes padding subheaders and trailing padding */
-    guint16  padding_bytes;
-    guint16  raw_length;
-} mac_lte_tap_info;
-
-
-
-/*****************************************************************/
-/* UDP framing format                                            */
-/* -----------------------                                       */
-/* Several people have asked about dissecting MAC by framing     */
-/* PDUs over IP.  A suggested format over UDP has been created   */
-/* and implemented by this dissector, using the definitions      */
-/* below. A link to an example program showing you how to encode */
-/* these headers and send LTE MAC PDUs on a UDP socket is        */
-/* provided at https://wiki.wireshark.org/MAC-LTE                */
-/*                                                               */
-/* A heuristic dissector (enabled by a preference) will          */
-/* recognise a signature at the beginning of these frames.       */
-/*****************************************************************/
-
-
-/* Signature.  Rather than try to define a port for this, or make the
-   port number a preference, frames will start with this string (with no
-   terminating NULL */
-#define MAC_LTE_START_STRING "mac-lte"
-
-/* Fixed fields.  This is followed by the following 3 mandatory fields:
-   - radioType (1 byte)
-   - direction (1 byte)
-   - rntiType (1 byte)
-   (where the allowed values are defined above */
-
-/* Optional fields. Attaching this info to frames will allow you
-   to show you display/filter/plot/add-custom-columns on these fields, so should
-   be added if available.
-   The format is to have the tag, followed by the value (there is no length field,
-   it's implicit from the tag) */
-
-#define MAC_LTE_RNTI_TAG            0x02
-/* 2 bytes, network order */
-
-#define MAC_LTE_UEID_TAG            0x03
-/* 2 bytes, network order */
-
-#define MAC_LTE_FRAME_SUBFRAME_TAG  0x04
-/* 2 bytes, network order, SFN is stored in 12 MSB and SF in 4 LSB */
-
-#define MAC_LTE_PREDEFINED_DATA_TAG 0x05
-/* 1 byte */
-
-#define MAC_LTE_RETX_TAG            0x06
-/* 1 byte */
-
-#define MAC_LTE_CRC_STATUS_TAG      0x07
-/* 1 byte */
-
-#define MAC_LTE_EXT_BSR_SIZES_TAG   0x08
-/* 0 byte */
-
-#define MAC_LTE_SEND_PREAMBLE_TAG   0x09
-/* 2 bytes, RAPID value (1 byte) followed by RACH attempt number (1 byte) */
-
-#define MAC_LTE_CARRIER_ID_TAG      0x0A
-/* 1 byte */
-
-#define MAC_LTE_PHY_TAG             0x0B
-/* variable length, length (1 byte) then depending on direction
-   in UL: modulation type (1 byte), TBS index (1 byte), RB length (1 byte),
-          RB start (1 byte), HARQ id (1 byte), NDI (1 byte)
-   in DL: DCI format (1 byte), resource allocation type (1 byte), aggregation level (1 byte),
-          MCS index (1 byte), redundancy version (1 byte), resource block length (1 byte),
-          HARQ id (1 byte), NDI (1 byte), TB (1 byte), DL reTx (1 byte) */
-
-#define MAC_LTE_SIMULT_PUCCH_PUSCH_PCELL_TAG  0x0C
-/* 0 byte */
-
-#define MAC_LTE_SIMULT_PUCCH_PUSCH_PSCELL_TAG 0x0D
-/* 0 byte */
-
-#define MAC_LTE_CE_MODE_TAG         0x0E
-/* 1 byte containing mac_lte_ce_mode enum value */
-
-#define MAC_LTE_NB_MODE_TAG         0x0F
-/* 1 byte containing mac_lte_nb_mode enum value */
-
-#define MAC_LTE_N_UL_RB_TAG         0x10
-/* 1 byte containing the number of UL resource blocks: 6, 15, 25, 50, 75 or 100 */
-
-#define MAC_LTE_SR_TAG              0x11
-/* 2 bytes for the number of items, followed by that number of ueid, rnti (2 bytes each) */
-
-
-/* MAC PDU. Following this tag comes the actual MAC PDU (there is no length, the PDU
-   continues until the end of the frame) */
-#define MAC_LTE_PAYLOAD_TAG 0x01
-
-
-/* Type to store parameters for configuring LCID->RLC channel settings for DRB */
-/* Some are optional, and may not be seen (e.g. on reestablishment) */
-typedef struct drb_mapping_t
-{
-    guint16    ueid;                /* Mandatory */
-    guint8     drbid;               /* Mandatory */
-    gboolean   lcid_present;
-    guint8     lcid;                /* Part of LogicalChannelConfig - optional */
-    gboolean   rlcMode_present;
-    guint8     rlcMode;             /* Part of RLC config - optional */
-    gboolean   rlc_ul_ext_li_field; /* Part of RLC config - optional */
-    gboolean   rlc_dl_ext_li_field; /* Part of RLC config - optional */
-    gboolean   rlc_ul_ext_am_sn;    /* Part of RLC config - optional */
-    gboolean   rlc_dl_ext_am_sn;    /* Part of RLC config - optional */
-    gboolean   um_sn_length_present;
-    guint8     um_sn_length;        /* Part of RLC config - optional */
-    gboolean   ul_priority_present;
-    guint8     ul_priority;         /* Part of LogicalChannelConfig - optional */
-    gboolean   pdcp_sn_size_present;
-    guint8     pdcp_sn_size;        /* Part of pdcp-Config - optional */
-} drb_mapping_t;
-
-
-
-/* Dedicated DRX config. Used to verify that a sensible config is given.
-   Also, beginning to configure MAC with this config and (optionally) show
-   DRX config and state (cycles/timers) attached to each UL/DL PDU! */
-typedef struct drx_config_t {
-    gboolean    configured;
-    guint32     frameNum;
-    guint32     previousFrameNum;
-
-    guint32     onDurationTimer;
-    guint32     inactivityTimer;
-    guint32     retransmissionTimer;
-    guint32     longCycle;
-    guint32     cycleOffset;
-    /* Optional Short cycle */
-    gboolean    shortCycleConfigured;
-    guint32     shortCycle;
-    guint32     shortCycleTimer;
-} drx_config_t;
-
-/* RRC can indicate whether simultaneous PUCCH/PUSCH is used */
-typedef enum {
-    SIMULT_PUCCH_PUSCH_PCELL = 0,
-    SIMULT_PUCCH_PUSCH_PSCELL
-} simult_pucch_pusch_cell_type;
-/*
- * Editor modelines  -  http://www.wireshark.org/tools/modelines.html
- *
- * Local variables:
- * c-basic-offset: 4
- * tab-width: 8
- * indent-tabs-mode: nil
- * End:
- *
- * vi: set shiftwidth=4 tabstop=8 expandtab:
- * :indentSize=4:tabSize=8:noTabs=true:
- */
-
-#endif
diff --git a/openair2/UTIL/OPT/packet-rohc.h b/openair2/UTIL/OPT/packet-rohc.h
new file mode 100644
index 0000000000000000000000000000000000000000..c6c807f6872d139768f916bd3f166e45933705ce
--- /dev/null
+++ b/openair2/UTIL/OPT/packet-rohc.h
@@ -0,0 +1,72 @@
+/* packet-rohc.h
+ * Routines for RObust Header Compression (ROHC) dissection.
+ *
+ * Copyright 2011, Anders Broman <anders.broman[at]ericsson.com>
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ *
+ * Ref:
+ * http://www.ietf.org/rfc/rfc3095.txt         RObust Header Compression (ROHC): Framework and four profiles: RTP, UDP, ESP, and uncompressed
+ * http://datatracker.ietf.org/doc/rfc4815/    RObust Header Compression (ROHC): Corrections and Clarifications to RFC 3095
+ * http://datatracker.ietf.org/doc/rfc5225/    RObust Header Compression Version 2 (ROHCv2): Profiles for RTP, UDP, IP, ESP and UDP-Lite
+ */
+
+#ifndef PACKET_ROHC_H
+#define PACKET_ROHC_H
+
+#define MAX_CID      15
+
+ /* ROHC Profiles */
+#define ROHC_PROFILE_UNCOMPRESSED   0
+#define ROHC_PROFILE_RTP            1
+#define ROHC_PROFILE_UDP            2
+#define ROHC_PROFILE_IP             4
+#define ROHC_PROFILE_UNKNOWN        0xFFFF
+
+enum rohc_mode
+{
+  MODE_NOT_SET = 0,
+  UNIDIRECTIONAL = 1,
+  OPTIMISTIC_BIDIRECTIONAL = 2,
+  RELIABLE_BIDIRECTIONAL = 3
+};
+
+enum rohc_d_mode
+{
+  NO_CONTEXT = 1,
+  STATIC_CONTEXT = 2,
+  FULL_CONTEXT = 3
+};
+typedef struct rohc_info
+{
+    gboolean           rohc_compression;
+    guint8             rohc_ip_version;
+    gboolean           cid_inclusion_info;
+    gboolean           large_cid_present;
+    enum rohc_mode     mode;
+    gboolean           rnd;
+    gboolean           udp_checksum_present;
+    guint16            profile;
+    proto_item         *last_created_item;
+} rohc_info;
+
+
+typedef struct rohc_context
+{
+    guint8             rohc_ip_version[MAX_CID+1];
+    gboolean           large_cid_present[MAX_CID+1];
+    enum rohc_mode     mode[MAX_CID+1];
+    enum rohc_d_mode   d_mode[MAX_CID+1];
+    gboolean           rnd[MAX_CID+1];
+    gboolean           udp_checkum_present[MAX_CID+1];
+    guint16            profile[MAX_CID+1];
+	gboolean           rohc_context_init[MAX_CID+1];
+	gint               ir_frame_number[MAX_CID+1];        /* The frame number of the last IR packet seen */
+
+} rohc_context;
+
+#endif /* PACKET_ROHC_H */
diff --git a/openair2/UTIL/OPT/probe.c b/openair2/UTIL/OPT/probe.c
index 3f416c92553d97bfa1cc3a6a09d12255ed804e76..e64f7724c6399833723a6f84dd5176cd31b6b6f0 100644
--- a/openair2/UTIL/OPT/probe.c
+++ b/openair2/UTIL/OPT/probe.c
@@ -128,12 +128,6 @@ typedef struct {
 
 opt_listener_t opt_listener;
 
-static void SendFrame(guint8 radioType, guint8 direction, guint8 rntiType,
-                      guint16 rnti, guint16 ueid, guint16 sysframeNumber,
-                      guint8 isPredefinedData, guint8 retx, guint8 crcStatus,
-                      guint8 oob_event, guint8 oob_event_value,
-                      uint8_t *pdu_buffer, unsigned int pdu_buffer_size);
-
 unsigned short checksum(unsigned short *ptr, int length) {
   int sum = 0;
   u_short answer = 0;
@@ -152,7 +146,7 @@ unsigned short checksum(unsigned short *ptr, int length) {
 }
 
 /* Write an individual PDU (PCAP packet header + mac-context + mac-pdu) */
-static int MAC_LTE_PCAP_WritePDU(const uint8_t *PDU,
+static int PCAP_WritePDU(const uint8_t *PDU,
                                  unsigned int length) {
   pcaprec_hdr_t packet_header;
   // IPv4 header
@@ -288,7 +282,7 @@ int opt_create_listener_socket(char *ip_address, uint16_t port) {
  */
 /* Add framing header to MAC PDU and send. */
 static void SendFrame(guint8 radioType, guint8 direction, guint8 rntiType,
-                      guint16 rnti, guint16 ueid, guint16 sfnSf,
+                      guint16 rnti, guint16 ueid, guint16 frame, guint16 subframe,
                       guint8 isPredefinedData, guint8 retx, guint8 crcStatus,
                       guint8 oob_event, guint8 oob_event_value,
                       uint8_t *pdu_buffer, unsigned int pdu_buffer_size) {
@@ -317,9 +311,9 @@ static void SendFrame(guint8 radioType, guint8 direction, guint8 rntiType,
   tmp16 = htons(ueid);
   memcpy(frameBuffer+frameOffset, &tmp16, 2);
   frameOffset += 2;
-  /* Subframe number */
+  /* Subframe number */ 
   frameBuffer[frameOffset++] = MAC_LTE_FRAME_SUBFRAME_TAG;
-  tmp16 = htons(sfnSf); // frame counter : this will give an expert info as wireshark expects SF and not F
+  tmp16 = htons((frame<<4)+subframe); // frame counter : this will give an expert info as wireshark expects SF and not F
   memcpy(frameBuffer+frameOffset, &tmp16, 2);
   frameOffset += 2;
   frameBuffer[frameOffset++] = MAC_LTE_CRC_STATUS_TAG;
@@ -400,7 +394,76 @@ static void SendFrame(guint8 radioType, guint8 direction, guint8 rntiType,
     bytesSent = sendto(g_socksd, frameBuffer, frameOffset, 0,
                        (const struct sockaddr *)&g_serv_addr, sizeof(g_serv_addr));
   else
-    bytesSent = MAC_LTE_PCAP_WritePDU(frameBuffer, frameOffset);
+    bytesSent = PCAP_WritePDU(frameBuffer, frameOffset);
+
+  if (bytesSent != frameOffset) {
+    LOG_W(OPT, "trace_pdu expected %d bytes, got %ld (errno=%d)\n",
+          frameOffset, bytesSent, errno);
+    //exit(1);
+  }
+}
+
+static void SendFrameNR(guint8 radioType, guint8 direction, guint8 rntiType,
+			guint16 rnti, guint16 ueid,  guint16 frame, guint16 subframe,
+			guint8 isPredefinedData, guint8 retx, guint8 crcStatus,
+			guint8 oob_event, guint8 oob_event_value,
+			uint8_t *pdu_buffer, unsigned int pdu_buffer_size) {
+  unsigned char frameBuffer[9000];
+  unsigned int frameOffset;
+  ssize_t bytesSent;
+  frameOffset = 0;
+  uint16_t tmp16;
+  memcpy(frameBuffer+frameOffset, MAC_NR_START_STRING,
+         strlen(MAC_NR_START_STRING));
+  frameOffset += strlen(MAC_NR_START_STRING);
+  /******************************************************************************/
+  /* Now write out fixed fields (the mandatory elements of struct mac_lte_info) */
+  frameBuffer[frameOffset++] = radioType;
+  frameBuffer[frameOffset++] = direction;
+  frameBuffer[frameOffset++] = rntiType;
+  /*************************************/
+  /* Now optional fields               */
+  /* RNTI */
+  frameBuffer[frameOffset++] = MAC_NR_RNTI_TAG;
+  tmp16 = htons(rnti);
+  memcpy(frameBuffer+frameOffset, &tmp16, 2);
+  frameOffset += 2;
+  /* UEId */
+  frameBuffer[frameOffset++] = MAC_NR_UEID_TAG;
+  tmp16 = htons(ueid);
+  memcpy(frameBuffer+frameOffset, &tmp16, 2);
+  frameOffset += 2;
+  /* Subframe number */
+  frameBuffer[frameOffset++] = MAC_NR_FRAME_SLOT_TAG;
+  tmp16 = htons(frame); // frame counter : this will give an expert info as wireshark expects SF and not F
+  memcpy(frameBuffer+frameOffset, &tmp16, 2);
+  frameOffset += 2;
+  tmp16 = htons(subframe); // frame counter : this will give an expert info as wireshark expects SF and not F
+  memcpy(frameBuffer+frameOffset, &tmp16, 2);
+  frameOffset += 2;
+  if (direction == 0 ) { //ulink
+    frameBuffer[frameOffset++] = MAC_NR_PHR_TYPE2_OTHERCELL_TAG;
+    frameBuffer[frameOffset++] = 0;
+  }
+  
+  /***************************************/
+  /* Now write the MAC PDU               */
+  frameBuffer[frameOffset++] = MAC_NR_PAYLOAD_TAG;
+
+  /* Append actual PDU  */
+  //memcpy(frameBuffer+frameOffset, g_PDUBuffer, g_PDUOffset);
+  //frameOffset += g_PDUOffset;
+  if (pdu_buffer != NULL) {
+    memcpy(frameBuffer+frameOffset, (void *)pdu_buffer, pdu_buffer_size);
+    frameOffset += pdu_buffer_size;
+  }
+
+  if ( opt_type ==  OPT_WIRESHARK )
+    /* Send out the data over the UDP socket */
+    bytesSent = sendto(g_socksd, frameBuffer, frameOffset, 0,
+                       (const struct sockaddr *)&g_serv_addr, sizeof(g_serv_addr));
+  else
+    bytesSent = PCAP_WritePDU(frameBuffer, frameOffset);
 
   if (bytesSent != frameOffset) {
     LOG_W(OPT, "trace_pdu expected %d bytes, got %ld (errno=%d)\n",
@@ -413,20 +476,23 @@ static void SendFrame(guint8 radioType, guint8 direction, guint8 rntiType,
 extern RAN_CONTEXT_t RC;
 #include <openair1/PHY/phy_extern_ue.h>
 /* Remote serveraddress (where Wireshark is running) */
-void trace_pdu_implementation(int direction, uint8_t *pdu_buffer, unsigned int pdu_buffer_size,
+void trace_pdu_implementation(int nr, int direction, uint8_t *pdu_buffer, unsigned int pdu_buffer_size,
                               int ueid, int rntiType, int rnti, uint16_t sysFrameNumber, uint8_t subFrameNumber, int oob_event,
                               int oob_event_value) {
   int radioType=FDD_RADIO;
   LOG_D(OPT,"sending packet to wireshark: direction=%s, size: %d, ueid: %d, rnti: %x, frame/sf: %d.%d\n",
         direction?"DL":"UL", pdu_buffer_size, ueid, rnti, sysFrameNumber,subFrameNumber);
 
-  if (RC.eNB && RC.eNB[0][0]!=NULL)
-    radioType=RC.eNB[0][0]->frame_parms.frame_type== FDD ? FDD_RADIO:TDD_RADIO;
-  else if (PHY_vars_UE_g && PHY_vars_UE_g[0][0] != NULL)
-    radioType=PHY_vars_UE_g[0][0]->frame_parms.frame_type== FDD ? FDD_RADIO:TDD_RADIO;
-  else {
-    LOG_E(OPT,"not a eNB neither a UE!!! \n");
-    return;
+  if (nr) {
+    radioType=TDD_RADIO;
+  } else {
+    if (RC.eNB && RC.eNB[0][0]!=NULL) 
+      radioType=RC.eNB[0][0]->frame_parms.frame_type== FDD ? FDD_RADIO:TDD_RADIO;
+    else if (PHY_vars_UE_g && PHY_vars_UE_g[0][0] != NULL)
+      radioType=PHY_vars_UE_g[0][0]->frame_parms.frame_type== FDD ? FDD_RADIO:TDD_RADIO;
+    else {
+      LOG_E(OPT,"not a 4G eNB neither a 4G UE!!! \n");
+    }
   }
 
   switch (opt_type) {
@@ -448,9 +514,17 @@ void trace_pdu_implementation(int direction, uint8_t *pdu_buffer, unsigned int p
       break;
   }
 
+  if (nr)
+  SendFrameNR( radioType,
+             (direction == DIRECTION_DOWNLINK) ? DIRECTION_DOWNLINK : DIRECTION_UPLINK,
+	       rntiType, rnti, ueid, sysFrameNumber, subFrameNumber,
+             1, 0, 1,  //guint8 isPredefinedData, guint8 retx, guint8 crcStatus
+             oob_event,oob_event_value,
+             pdu_buffer, pdu_buffer_size);
+  else 
   SendFrame( radioType,
              (direction == DIRECTION_DOWNLINK) ? DIRECTION_DOWNLINK : DIRECTION_UPLINK,
-             rntiType, rnti, ueid, (sysFrameNumber<<4) + subFrameNumber,
+             rntiType, rnti, ueid, sysFrameNumber, subFrameNumber,
              1, 0, 1,  //guint8 isPredefinedData, guint8 retx, guint8 crcStatus
              oob_event,oob_event_value,
              pdu_buffer, pdu_buffer_size);
diff --git a/openair2/UTIL/OPT/wireshark_headers.h b/openair2/UTIL/OPT/wireshark_headers.h
new file mode 100644
index 0000000000000000000000000000000000000000..27d8753ffe8c9e676a211399babb80f3d554a5ef
--- /dev/null
+++ b/openair2/UTIL/OPT/wireshark_headers.h
@@ -0,0 +1,895 @@
+/* packet-mac-lte.h
+ *
+ * Martin Mathieson
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * Copyright (C) 2009 Martin Mathieson. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+ /* 
+ this is wireshark, commit: commit eda834b6e29c36e05a63a6056afa98390ff79357 
+ Date:   Wed Aug 22 14:36:20 2018 +0200
+ modified to be used in OpenAir to create the LTE MAC/RLC encapsulated in UDP as per Wireshark feature 
+ */
+
+#ifndef __UTIL_OPT_PACKET_MAC_LTE__H__
+#define __UTIL_OPT_PACKET_MAC_LTE__H__
+
+/** data structure to hold time values with nanosecond resolution*/
+typedef struct {
+	time_t	secs;
+	int	nsecs;
+} nstime_t;
+
+
+/* radioType */
+#define FDD_RADIO 1
+#define TDD_RADIO 2
+
+/* Direction */
+#define DIRECTION_UPLINK   0
+#define DIRECTION_DOWNLINK 1
+
+/* rntiType */
+#define WS_NO_RNTI     0
+#define WS_P_RNTI      1
+#define WS_RA_RNTI     2
+#define WS_C_RNTI      3
+#define WS_SI_RNTI     4
+#define WS_SPS_RNTI    5
+#define WS_M_RNTI      6
+#define WS_SL_BCH_RNTI 7
+#define WS_SL_RNTI     8
+#define WS_SC_RNTI     9
+#define WS_G_RNTI      10
+
+#define WS_CS_RNTI     5
+
+typedef enum mac_lte_oob_event {
+    ltemac_send_preamble,
+    ltemac_send_sr,
+    ltemac_sr_failure
+} mac_lte_oob_event;
+
+typedef enum mac_lte_dl_retx {
+    dl_retx_no,
+    dl_retx_yes,
+    dl_retx_unknown
+} mac_lte_dl_retx;
+
+typedef enum mac_lte_crc_status {
+    crc_fail = 0,
+    crc_success = 1,
+    crc_high_code_rate = 2,
+    crc_pdsch_lost = 3,
+    crc_duplicate_nonzero_rv = 4,
+    crc_false_dci = 5
+} mac_lte_crc_status;
+
+/* N.B. for SCellIndex-r13 extends to 31 */
+typedef enum mac_lte_carrier_id {
+    carrier_id_primary,
+    carrier_id_secondary_1,
+    carrier_id_secondary_2,
+    carrier_id_secondary_3,
+    carrier_id_secondary_4,
+    carrier_id_secondary_5,
+    carrier_id_secondary_6,
+    carrier_id_secondary_7
+} mac_lte_carrier_id;
+
+typedef enum mac_lte_ce_mode {
+    no_ce_mode = 0,
+    ce_mode_a = 1,
+    ce_mode_b = 2
+} mac_lte_ce_mode;
+
+typedef enum mac_lte_nb_mode {
+    no_nb_mode = 0,
+    nb_mode = 1
+} mac_lte_nb_mode;
+
+/* Context info attached to each LTE MAC frame */
+typedef struct mac_lte_info
+{
+    /* Needed for decode */
+    guint8          radioType;
+    guint8          direction;
+    guint8          rntiType;
+
+    /* Extra info to display */
+    guint16         rnti;
+    guint16         ueid;
+
+    /* Timing info */
+    guint16         sysframeNumber;
+    guint16         subframeNumber;
+    gboolean        sfnSfInfoPresent;
+
+    /* Optional field. More interesting for TDD (FDD is always -4 subframeNumber) */
+    gboolean        subframeNumberOfGrantPresent;
+    guint16         subframeNumberOfGrant;
+
+    /* Flag set only if doing PHY-level data test - i.e. there may not be a
+       well-formed MAC PDU so just show as raw data */
+    gboolean        isPredefinedData;
+
+    /* Length of DL PDU or UL grant size in bytes */
+    guint16         length;
+
+    /* 0=newTx, 1=first-retx, etc */
+    guint8          reTxCount;
+    guint8          isPHICHNACK; /* FALSE=PDCCH retx grant, TRUE=PHICH NACK */
+
+    /* UL only.  Indicates if the R10 extendedBSR-Sizes parameter is set */
+    gboolean        isExtendedBSRSizes;
+
+    /* UL only.  Indicates if the R10 simultaneousPUCCH-PUSCH parameter is set for PCell */
+    gboolean        isSimultPUCCHPUSCHPCell;
+
+    /* UL only.  Indicates if the R10 extendedBSR-Sizes parameter is set for PSCell */
+    gboolean        isSimultPUCCHPUSCHPSCell;
+
+    /* Status of CRC check. For UE it is DL only. For eNodeB it is UL
+       only. For an analyzer, it is present for both DL and UL. */
+    gboolean        crcStatusValid;
+    mac_lte_crc_status crcStatus;
+
+    /* Carrier ID */
+    mac_lte_carrier_id   carrierId;
+
+    /* DL only.  Is this known to be a retransmission? */
+    mac_lte_dl_retx dl_retx;
+
+    /* DL only. CE mode to be used for RAR decoding */
+    mac_lte_ce_mode ceMode;
+
+    /* DL and UL. NB-IoT mode of the UE */
+    mac_lte_nb_mode nbMode;
+
+    /* UL only, for now used for CE mode A RAR decoding */
+    guint8          nUlRb;
+
+    /* More Physical layer info (see direction above for which side of union to use) */
+    union {
+        struct mac_lte_ul_phy_info
+        {
+            guint8 present;  /* Remaining UL fields are present and should be displayed */
+            guint8 modulation_type;
+            guint8 tbs_index;
+            guint8 resource_block_length;
+            guint8 resource_block_start;
+            guint8 harq_id;
+            gboolean ndi;
+        } ul_info;
+        struct mac_lte_dl_phy_info
+        {
+            guint8 present; /* Remaining DL fields are present and should be displayed */
+            guint8 dci_format;
+            guint8 resource_allocation_type;
+            guint8 aggregation_level;
+            guint8 mcs_index;
+            guint8 redundancy_version_index;
+            guint8 resource_block_length;
+            guint8 harq_id;
+            gboolean ndi;
+            guint8   transport_block;  /* 0..1 */
+        } dl_info;
+    } detailed_phy_info;
+
+    /* Relating to out-of-band events */
+    /* N.B. dissector will only look to these fields if length is 0... */
+    mac_lte_oob_event  oob_event;
+    guint8             rapid;
+    guint8             rach_attempt_number;
+    #define MAX_SRs 20
+    guint16            number_of_srs;
+    guint16            oob_ueid[MAX_SRs];
+    guint16            oob_rnti[MAX_SRs];
+} mac_lte_info;
+
+ /* 0 to 10 and 32 to 38 */
+#define MAC_LTE_DATA_LCID_COUNT_MAX 18
+#define MAC_LTE_START_STRING "mac-lte"
+
+/* Fixed fields.  This is followed by the following 3 mandatory fields:
+   - radioType (1 byte)
+   - direction (1 byte)
+   - rntiType (1 byte)
+   (where the allowed values are defined above */
+
+/* Optional fields. Attaching this info to frames will allow you
+   to show you display/filter/plot/add-custom-columns on these fields, so should
+   be added if available.
+   The format is to have the tag, followed by the value (there is no length field,
+   it's implicit from the tag) */
+
+#define MAC_LTE_RNTI_TAG            0x02
+/* 2 bytes, network order */
+
+#define MAC_LTE_UEID_TAG            0x03
+/* 2 bytes, network order */
+
+#define MAC_LTE_FRAME_SUBFRAME_TAG  0x04
+/* 2 bytes, network order, SFN is stored in 12 MSB and SF in 4 LSB */
+
+#define MAC_LTE_PREDEFINED_DATA_TAG 0x05
+/* 1 byte */
+
+#define MAC_LTE_RETX_TAG            0x06
+/* 1 byte */
+
+#define MAC_LTE_CRC_STATUS_TAG      0x07
+/* 1 byte */
+
+#define MAC_LTE_EXT_BSR_SIZES_TAG   0x08
+/* 0 byte */
+
+#define MAC_LTE_SEND_PREAMBLE_TAG   0x09
+/* 2 bytes, RAPID value (1 byte) followed by RACH attempt number (1 byte) */
+
+#define MAC_LTE_CARRIER_ID_TAG      0x0A
+/* 1 byte */
+
+#define MAC_LTE_PHY_TAG             0x0B
+/* variable length, length (1 byte) then depending on direction
+   in UL: modulation type (1 byte), TBS index (1 byte), RB length (1 byte),
+          RB start (1 byte), HARQ id (1 byte), NDI (1 byte)
+   in DL: DCI format (1 byte), resource allocation type (1 byte), aggregation level (1 byte),
+          MCS index (1 byte), redundancy version (1 byte), resource block length (1 byte),
+          HARQ id (1 byte), NDI (1 byte), TB (1 byte), DL reTx (1 byte) */
+
+#define MAC_LTE_SIMULT_PUCCH_PUSCH_PCELL_TAG  0x0C
+/* 0 byte */
+
+#define MAC_LTE_SIMULT_PUCCH_PUSCH_PSCELL_TAG 0x0D
+/* 0 byte */
+
+#define MAC_LTE_CE_MODE_TAG         0x0E
+/* 1 byte containing mac_lte_ce_mode enum value */
+
+#define MAC_LTE_NB_MODE_TAG         0x0F
+/* 1 byte containing mac_lte_nb_mode enum value */
+
+#define MAC_LTE_N_UL_RB_TAG         0x10
+/* 1 byte containing the number of UL resource blocks: 6, 15, 25, 50, 75 or 100 */
+
+#define MAC_LTE_SR_TAG              0x11
+/* 2 bytes for the number of items, followed by that number of ueid, rnti (2 bytes each) */
+
+
+/* MAC PDU. Following this tag comes the actual MAC PDU (there is no length, the PDU
+   continues until the end of the frame) */
+#define MAC_LTE_PAYLOAD_TAG 0x01
+
+/* rlcMode */
+#define RLC_TM_MODE 1
+#define RLC_UM_MODE 2
+#define RLC_AM_MODE 4
+#define RLC_PREDEF  8
+
+/* priority ? */
+
+/* channelType */
+#define CHANNEL_TYPE_CCCH 1
+#define CHANNEL_TYPE_BCCH_BCH 2
+#define CHANNEL_TYPE_PCCH 3
+#define CHANNEL_TYPE_SRB 4
+#define CHANNEL_TYPE_DRB 5
+#define CHANNEL_TYPE_BCCH_DL_SCH 6
+#define CHANNEL_TYPE_MCCH 7
+#define CHANNEL_TYPE_MTCH 8
+
+/* sequenceNumberLength */
+#define UM_SN_LENGTH_5_BITS 5
+#define UM_SN_LENGTH_10_BITS 10
+#define AM_SN_LENGTH_10_BITS 10
+#define AM_SN_LENGTH_16_BITS 16
+
+
+typedef enum rlc_lte_nb_mode {
+    rlc_no_nb_mode = 0,
+    rlc_nb_mode = 1
+} rlc_lte_nb_mode;
+
+
+/* Info attached to each LTE RLC frame */
+typedef struct rlc_lte_info
+{
+    guint8          rlcMode;
+    guint8          direction;
+    guint8          priority;
+    guint8          sequenceNumberLength;
+    guint16         ueid;
+    guint16         channelType;
+    guint16         channelId; /* for SRB: 1=SRB1, 2=SRB2, 3=SRB1bis; for DRB: DRB ID */
+    guint16         pduLength;
+    gboolean        extendedLiField;
+    rlc_lte_nb_mode nbMode;
+} rlc_lte_info;
+
+
+typedef struct rlc_lte_tap_info {
+    /* Info from context */
+    guint8          rlcMode;
+    guint8          direction;
+    guint8          priority;
+    guint16         ueid;
+    guint16         channelType;
+    guint16         channelId;
+    guint16         pduLength;
+    guint8          sequenceNumberLength;
+
+    nstime_t        rlc_lte_time;
+    guint8          loggedInMACFrame;
+    guint16         sequenceNumber;
+    guint8          isResegmented;
+    guint8          isControlPDU;
+    guint16         ACKNo;
+    #define MAX_NACKs 128
+    guint16         noOfNACKs;
+    guint16         NACKs[MAX_NACKs];
+
+    guint16         missingSNs;
+} rlc_lte_tap_info;
+
+
+/* Signature.  Rather than try to define a port for this, or make the
+   port number a preference, frames will start with this string (with no
+   terminating NULL */
+#define RLC_LTE_START_STRING "rlc-lte"
+
+/* Fixed field.  This is followed by the following 1 mandatory field:
+   - rlcMode (1 byte)
+   (where the allowed values are defined above */
+
+/* Conditional field. This field is mandatory in case of RLC Unacknowledged mode.
+   In case of RLC Acknowledged mode, the field is optional (assume 10 bits by default).
+   The format is to have the tag, followed by the value (there is no length field,
+   it's implicit from the tag). The allowed values are defined above. */
+
+#define RLC_LTE_SN_LENGTH_TAG    0x02
+/* 1 byte */
+
+/* Optional fields. Attaching this info to frames will allow you
+   to show you display/filter/plot/add-custom-columns on these fields, so should
+   be added if available.
+   The format is to have the tag, followed by the value (there is no length field,
+   it's implicit from the tag) */
+
+#define RLC_LTE_DIRECTION_TAG       0x03
+/* 1 byte */
+
+#define RLC_LTE_PRIORITY_TAG        0x04
+/* 1 byte */
+
+#define RLC_LTE_UEID_TAG            0x05
+/* 2 bytes, network order */
+
+#define RLC_LTE_CHANNEL_TYPE_TAG    0x06
+/* 2 bytes, network order */
+
+#define RLC_LTE_CHANNEL_ID_TAG      0x07
+/* 2 bytes, network order */
+
+#define RLC_LTE_EXT_LI_FIELD_TAG    0x08
+/* 0 byte, tag presence indicates that AM DRB PDU is using an extended LI field of 15 bits */
+
+#define RLC_LTE_NB_MODE_TAG         0x09
+/* 1 byte containing rlc_lte_nb_mode enum value */
+
+/* RLC PDU. Following this tag comes the actual RLC PDU (there is no length, the PDU
+   continues until the end of the frame) */
+#define RLC_LTE_PAYLOAD_TAG         0x01
+
+enum pdcp_plane
+{
+    SIGNALING_PLANE = 1,
+    USER_PLANE = 2
+};
+
+typedef enum LogicalChannelType
+{
+    Channel_DCCH=1,
+    Channel_BCCH=2,
+    Channel_CCCH=3,
+    Channel_PCCH=4,
+    Channel_DCCH_NB=5,
+    Channel_BCCH_NB=6,
+    Channel_CCCH_NB=7,
+    Channel_PCCH_NB=8
+} LogicalChannelType;
+
+typedef enum
+{
+    BCH_TRANSPORT=1,
+    DLSCH_TRANSPORT=2
+} BCCHTransportType;
+
+#define PDCP_SN_LENGTH_5_BITS  5
+#define PDCP_SN_LENGTH_7_BITS  7
+#define PDCP_SN_LENGTH_12_BITS 12
+#define PDCP_SN_LENGTH_15_BITS 15
+#define PDCP_SN_LENGTH_18_BITS 18
+
+enum lte_security_integrity_algorithm_e { eia0, eia1, eia2, eia3 };
+enum lte_security_ciphering_algorithm_e { eea0, eea1, eea2, eea3 };
+
+typedef struct pdcp_lte_security_info_t
+{
+    guint32                                 configuration_frame;
+    gboolean                                seen_next_ul_pdu;  /* i.e. have we seen SecurityModeResponse */
+    enum lte_security_integrity_algorithm_e integrity;
+    enum lte_security_ciphering_algorithm_e ciphering;
+
+    /* Store previous settings so can revert if get SecurityModeFailure */
+    guint32                                 previous_configuration_frame;
+    enum lte_security_integrity_algorithm_e previous_integrity;
+    enum lte_security_ciphering_algorithm_e previous_ciphering;
+} pdcp_lte_security_info_t;
+
+
+/***********************************************************************/
+/* UDP framing format                                                  */
+/* -----------------------                                             */
+/* Several people have asked about dissecting PDCP by framing          */
+/* PDUs over IP.  A suggested format over UDP has been defined         */
+/* and implemented by this dissector, using the definitions            */
+/* below. A link to an example program showing you how to encode       */
+/* these headers and send LTE PDCP PDUs on a UDP socket is             */
+/* provided at https://gitlab.com/wireshark/wireshark/-/wikis/PDCP-LTE */
+/*                                                                     */
+/* A heuristic dissecter (enabled by a preference) will                */
+/* recognise a signature at the beginning of these frames.             */
+/* Until someone is using this format, suggestions for changes         */
+/* are welcome.                                                        */
+/***********************************************************************/
+
+
+/* Signature.  Rather than try to define a port for this, or make the
+   port number a preference, frames will start with this string (with no
+   terminating NULL */
+#define PDCP_LTE_START_STRING "pdcp-lte"
+
+/* Fixed fields.  This is followed by the following 3 mandatory fields:
+   - no_header_pdu (1 byte)
+   - plane (1 byte)
+   - rohc_compression ( byte)
+   (where the allowed values are defined above) */
+
+/* Conditional field. This field is mandatory in case of User Plane PDCP PDU.
+   The format is to have the tag, followed by the value (there is no length field,
+   it's implicit from the tag). The allowed values are defined above. */
+
+#define PDCP_LTE_SEQNUM_LENGTH_TAG          0x02
+/* 1 byte */
+
+/* Optional fields. Attaching this info to frames will allow you
+   to show you display/filter/plot/add-custom-columns on these fields, so should
+   be added if available.
+   The format is to have the tag, followed by the value (there is no length field,
+   it's implicit from the tag) */
+
+#define PDCP_LTE_DIRECTION_TAG              0x03
+/* 1 byte */
+
+#define PDCP_LTE_LOG_CHAN_TYPE_TAG          0x04
+/* 1 byte */
+
+#define PDCP_LTE_BCCH_TRANSPORT_TYPE_TAG    0x05
+/* 1 byte */
+
+#define PDCP_LTE_ROHC_IP_VERSION_TAG        0x06
+/* 2 bytes, network order */
+
+#define PDCP_LTE_ROHC_CID_INC_INFO_TAG      0x07
+/* 1 byte */
+
+#define PDCP_LTE_ROHC_LARGE_CID_PRES_TAG    0x08
+/* 1 byte */
+
+#define PDCP_LTE_ROHC_MODE_TAG              0x09
+/* 1 byte */
+
+#define PDCP_LTE_ROHC_RND_TAG               0x0A
+/* 1 byte */
+
+#define PDCP_LTE_ROHC_UDP_CHECKSUM_PRES_TAG 0x0B
+/* 1 byte */
+
+#define PDCP_LTE_ROHC_PROFILE_TAG           0x0C
+/* 2 bytes, network order */
+
+#define PDCP_LTE_CHANNEL_ID_TAG             0x0D
+/* 2 bytes, network order */
+
+#define PDCP_LTE_UEID_TAG                   0x0E
+/* 2 bytes, network order */
+
+/* PDCP PDU. Following this tag comes the actual PDCP PDU (there is no length, the PDU
+   continues until the end of the frame) */
+#define PDCP_LTE_PAYLOAD_TAG                0x01
+
+
+
+/* Called by RRC, or other configuration protocols */
+
+/* Function to configure ciphering & integrity algorithms */
+void set_pdcp_lte_security_algorithms(guint16 ueid, pdcp_lte_security_info_t *security_info);
+
+/* Function to indicate securityModeCommand did not complete */
+void set_pdcp_lte_security_algorithms_failed(guint16 ueid);
+
+
+/* Called by external dissectors */
+void set_pdcp_lte_rrc_ciphering_key(guint16 ueid, const char *key);
+void set_pdcp_lte_rrc_integrity_key(guint16 ueid, const char *key);
+void set_pdcp_lte_up_ciphering_key(guint16 ueid, const char *key);
+
+
+
+/* Context info attached to each NR MAC frame */
+typedef struct mac_nr_info
+{
+    /* Needed for decode */
+    guint8          radioType;
+    guint8          direction;
+    guint8          rntiType;
+
+    /* Extra info to display */
+    guint16         rnti;
+    guint16         ueid;
+    guint8          harqid;
+
+    /* Will these be included in the ME PHR report? */
+    guint8          phr_type2_othercell;
+
+    /* Timing info */
+    gboolean        sfnSlotInfoPresent;
+    guint16         sysframeNumber;
+    guint16         slotNumber;
+
+    /* Length of DL PDU or UL grant size in bytes */
+    guint16         length;
+
+} mac_nr_info;
+
+
+/*****************************************************************/
+/* UDP framing format                                            */
+/* -----------------------                                       */
+/* Several people have asked about dissecting MAC by framing     */
+/* PDUs over IP.  A suggested format over UDP has been created   */
+/* and implemented by this dissector, using the definitions      */
+/* below.                                                        */
+/*                                                               */
+/* A heuristic dissector (enabled by a preference) will          */
+/* recognise a signature at the beginning of these frames.       */
+/*****************************************************************/
+
+
+/* Signature.  Rather than try to define a port for this, or make the
+   port number a preference, frames will start with this string (with no
+   terminating NULL */
+#define MAC_NR_START_STRING "mac-nr"
+
+/* Fixed fields.  This is followed by the following 3 mandatory fields:
+   - radioType (1 byte)
+   - direction (1 byte)
+   - rntiType (1 byte)
+   (where the allowed values are defined above */
+
+/* Optional fields. Attaching this info to frames will allow you
+   to show you display/filter/plot/add-custom-columns on these fields, so should
+   be added if available.
+   The format is to have the tag, followed by the value (there is no length field,
+   it's implicit from the tag) */
+
+#define MAC_NR_RNTI_TAG                0x02
+/* 2 bytes, network order */
+
+#define MAC_NR_UEID_TAG                0x03
+/* 2 bytes, network order */
+
+#define MAC_NR_FRAME_SUBFRAME_TAG      0x04
+/* 2 bytes, deprecated, do not use it */
+
+#define MAC_NR_PHR_TYPE2_OTHERCELL_TAG 0x05
+/* 1 byte, TRUE/FALSE */
+
+#define MAC_NR_HARQID                  0x06
+/* 1 byte */
+
+#define MAC_NR_FRAME_SLOT_TAG          0x07
+/* 4 bytes, network order, SFN is stored in the 2 first bytes and slot number in the 2 last bytes */
+
+/* MAC PDU. Following this tag comes the actual MAC PDU (there is no length, the PDU
+   continues until the end of the frame) */
+#define MAC_NR_PAYLOAD_TAG             0x01
+
+
+/* Type to store parameters for configuring LCID->RLC channel settings for DRB */
+/* Some are optional, and may not be seen (e.g. on reestablishment) */
+typedef struct nr_drb_mac_rlc_mapping_t
+{
+    gboolean   active;
+    guint16    ueid;                /* Mandatory */
+    guint8     drbid;               /* Mandatory */
+
+    gboolean   lcid_present;
+    guint8     lcid;                /* Part of LogicalChannelConfig - optional */
+    gboolean   rlcMode_present;
+    guint8     rlcMode;             /* Part of RLC config - optional */
+
+    guint8     tempDirection;       /* So know direction of next SN length... */
+
+    gboolean   rlcUlSnLength_present;
+    guint8     rlcUlSnLength;        /* Part of RLC config - optional */
+    gboolean   rlcDlSnLength_present;
+    guint8     rlcDlSnLength;        /* Part of RLC config - optional */
+} nr_drb_mac_rlc_mapping_t;
+
+/* rlcMode */
+#define RLC_TM_MODE 1
+#define RLC_UM_MODE 2
+#define RLC_AM_MODE 4
+
+/* bearerType */
+#define BEARER_TYPE_CCCH 1
+#define BEARER_TYPE_BCCH_BCH 2
+#define BEARER_TYPE_PCCH 3
+#define BEARER_TYPE_SRB 4
+#define BEARER_TYPE_DRB 5
+#define BEARER_TYPE_BCCH_DL_SCH 6
+
+/* sequenceNumberLength */
+#define TM_SN_LENGTH_0_BITS  0
+#define UM_SN_LENGTH_6_BITS  6
+#define UM_SN_LENGTH_12_BITS 12
+#define AM_SN_LENGTH_12_BITS 12
+#define AM_SN_LENGTH_18_BITS 18
+
+/* Info attached to each NR RLC frame */
+typedef struct rlc_nr_info
+{
+    guint8          rlcMode;
+    guint8          direction;
+    guint8          sequenceNumberLength;
+    guint8          bearerType;
+    guint8          bearerId;
+    guint16         ueid;
+    guint16         pduLength;
+} rlc_nr_info;
+
+typedef struct nr_drb_rlc_pdcp_mapping_t
+{
+    gboolean   active;
+    guint16    ueid;                /* Mandatory */
+    guint8     drbid;               /* Mandatory */
+
+    gboolean   pdcpUlSnLength_present;
+    guint8     pdcpUlSnLength;        /* Part of PDCP config - optional */
+    gboolean   pdcpDlSnLength_present;
+    guint8     pdcpDlSnLength;        /* Part of PDCP config - optional */
+    gboolean   pdcpUlSdap;
+    gboolean   pdcpDlSdap;
+    gboolean   pdcpIntegrityProtection;
+    gboolean   pdcpCipheringDisabled;
+
+} nr_drb_rlc_pdcp_mapping_t;
+
+/* TODO: could probably merge this struct with above */
+typedef struct pdcp_ue_parameters {
+    guint32   id;
+    guint8    pdcp_sn_bits_ul;
+    guint8    pdcp_sn_bits_dl;
+    gboolean  pdcp_sdap_ul;
+    gboolean  pdcp_sdap_dl;
+    gboolean  pdcp_integrity;
+    gboolean  pdcp_ciphering_disabled;
+} pdcp_bearer_parameters;
+
+/*****************************************************************/
+/* UDP framing format                                            */
+/* -----------------------                                       */
+/* Several people have asked about dissecting RLC by framing     */
+/* PDUs over IP. A suggested format over UDP has been defined    */
+/* and implemented by this dissector, using the definitions      */
+/* below.                                                        */
+/*                                                               */
+/* A heuristic dissector (enabled by a preference) will          */
+/* recognise a signature at the beginning of these frames.       */
+/*****************************************************************/
+
+
+/* Signature.  Rather than try to define a port for this, or make the
+   port number a preference, frames will start with this string (with no
+   terminating NULL */
+#define RLC_NR_START_STRING "rlc-nr"
+
+/* Fixed field. This is followed by the following 2 mandatory field:
+   - rlcMode (1 byte)
+   - sequenceNumberLength (1 byte)
+   (where the allowed values are defined above) */
+
+/* Optional fields. Attaching this info to frames will allow you
+   to show you display/filter/plot/add-custom-columns on these fields, so should
+   be added if available.
+   The format is to have the tag, followed by the value (there is no length field,
+   it's implicit from the tag) */
+
+#define RLC_NR_DIRECTION_TAG       0x02
+/* 1 byte */
+
+#define RLC_NR_UEID_TAG            0x03
+/* 2 bytes, network order */
+
+#define RLC_NR_BEARER_TYPE_TAG     0x04
+/* 1 byte */
+
+#define RLC_NR_BEARER_ID_TAG       0x05
+/* 1 byte */
+
+/* RLC PDU. Following this tag comes the actual RLC PDU (there is no length, the PDU
+   continues until the end of the frame) */
+#define RLC_NR_PAYLOAD_TAG         0x01
+
+enum pdcp_nr_plane
+{
+    NR_SIGNALING_PLANE = 1,
+    NR_USER_PLANE = 2
+};
+
+typedef enum NRBearerType
+{
+    Bearer_DCCH=1,
+    Bearer_BCCH_BCH=2,
+    Bearer_BCCH_DL_SCH=3,
+    Bearer_CCCH=4,
+    Bearer_PCCH=5,
+} NRBearerType;
+
+
+#define PDCP_NR_SN_LENGTH_12_BITS 12
+#define PDCP_NR_SN_LENGTH_18_BITS 18
+
+#define PDCP_NR_UL_SDAP_HEADER_PRESENT 0x01
+#define PDCP_NR_DL_SDAP_HEADER_PRESENT 0x02
+
+enum nr_security_integrity_algorithm_e { nia0, nia1, nia2, nia3 };
+enum nr_security_ciphering_algorithm_e { nea0, nea1, nea2, nea3, nea_disabled=999};
+
+typedef struct pdcp_nr_security_info_t
+{
+    guint32                                configuration_frame;
+    gboolean                               seen_next_ul_pdu;  /* i.e. have we seen SecurityModeResponse */
+    enum nr_security_integrity_algorithm_e integrity;
+    enum nr_security_ciphering_algorithm_e ciphering;
+
+    /* Store previous settings so can revert if get SecurityModeFailure */
+    guint32                                previous_configuration_frame;
+    enum nr_security_integrity_algorithm_e previous_integrity;
+    enum nr_security_ciphering_algorithm_e previous_ciphering;
+} pdcp_nr_security_info_t;
+
+
+/*****************************************************************/
+/* UDP framing format                                            */
+/* -----------------------                                       */
+/* Several people have asked about dissecting PDCP by framing    */
+/* PDUs over IP.  A suggested format over UDP has been defined   */
+/* and implemented by this dissector, using the definitions      */
+/* below.                                                        */
+/*                                                               */
+/* A heuristic dissector (enabled by a preference) will          */
+/* recognise a signature at the beginning of these frames.       */
+/* Until someone is using this format, suggestions for changes   */
+/* are welcome.                                                  */
+/*****************************************************************/
+
+
+/* Signature.  Rather than try to define a port for this, or make the
+   port number a preference, frames will start with this string (with no
+   terminating NULL */
+#define PDCP_NR_START_STRING "pdcp-nr"
+
+/* Fixed fields:
+   - plane (1 byte) */
+
+/* Conditional field. This field is mandatory in case of User Plane PDCP PDU.
+   The format is to have the tag, followed by the value (there is no length field,
+   it's implicit from the tag). The allowed values are defined above. */
+
+#define PDCP_NR_SEQNUM_LENGTH_TAG          0x02
+/* 1 byte */
+
+/* Optional fields. Attaching this info should be added if available.
+   The format is to have the tag, followed by the value (there is no length field,
+   it's implicit from the tag) */
+
+#define PDCP_NR_DIRECTION_TAG              0x03
+/* 1 byte */
+
+#define PDCP_NR_BEARER_TYPE_TAG            0x04
+/* 1 byte */
+
+#define PDCP_NR_BEARER_ID_TAG              0x05
+/* 1 byte */
+
+#define PDCP_NR_UEID_TAG                   0x06
+/* 2 bytes, network order */
+
+#define PDCP_NR_ROHC_COMPRESSION_TAG       0x07
+/* 0 byte */
+
+/* N.B. The following ROHC values only have significance if rohc_compression
+   is in use for the current channel */
+
+#define PDCP_NR_ROHC_IP_VERSION_TAG        0x08
+/* 1 byte */
+
+#define PDCP_NR_ROHC_CID_INC_INFO_TAG      0x09
+/* 0 byte */
+
+#define PDCP_NR_ROHC_LARGE_CID_PRES_TAG    0x0A
+/* 0 byte */
+
+#define PDCP_NR_ROHC_MODE_TAG              0x0B
+/* 1 byte */
+
+#define PDCP_NR_ROHC_RND_TAG               0x0C
+/* 0 byte */
+
+#define PDCP_NR_ROHC_UDP_CHECKSUM_PRES_TAG 0x0D
+/* 0 byte */
+
+#define PDCP_NR_ROHC_PROFILE_TAG           0x0E
+/* 2 bytes, network order */
+
+#define PDCP_NR_MACI_PRES_TAG              0x0F
+/* 0 byte */
+
+#define PDCP_NR_SDAP_HEADER_TAG            0x10
+/* 1 byte, bitmask with PDCP_NR_UL_SDAP_HEADER_PRESENT and/or PDCP_NR_DL_SDAP_HEADER_PRESENT */
+
+#define PDCP_NR_CIPHER_DISABLED_TAG        0x11
+/* 0 byte */
+
+/* PDCP PDU. Following this tag comes the actual PDCP PDU (there is no length, the PDU
+   continues until the end of the frame) */
+#define PDCP_NR_PAYLOAD_TAG                0x01
+
+
+/* Called by RRC, or other configuration protocols */
+
+/* Function to configure ciphering & integrity algorithms */
+void set_pdcp_nr_security_algorithms(guint16 ueid, pdcp_nr_security_info_t *security_info);
+
+/* Function to indicate securityModeCommand did not complete */
+void set_pdcp_nr_security_algorithms_failed(guint16 ueid);
+
+
+/* Called by external dissectors */
+void set_pdcp_nr_rrc_ciphering_key(guint16 ueid, const char *key);
+void set_pdcp_nr_rrc_integrity_key(guint16 ueid, const char *key);
+void set_pdcp_nr_up_ciphering_key(guint16 ueid, const char *key);
+void set_pdcp_nr_up_integrity_key(guint16 ueid, const char *key);
+
+/*
+ * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
+ *
+ * Local variables:
+ * c-basic-offset: 4
+ * tab-width: 8
+ * indent-tabs-mode: nil
+ * End:
+ *
+ * vi: set shiftwidth=4 tabstop=8 expandtab:
+ * :indentSize=4:tabSize=8:noTabs=true:
+ */
+#endif
diff --git a/openair2/X2AP/x2ap_eNB.c b/openair2/X2AP/x2ap_eNB.c
index 0474d417df4af2890ae4fcde23678b53d5efdc20..38e6149ccd2ef103f8425720c53816ca3a546cd4 100644
--- a/openair2/X2AP/x2ap_eNB.c
+++ b/openair2/X2AP/x2ap_eNB.c
@@ -115,7 +115,12 @@ void x2ap_eNB_handle_sctp_association_resp(instance_t instance, sctp_new_associa
     if (x2ap_enb_data_p != NULL) {
       /* some sanity check - to be refined at some point */
       if (sctp_new_association_resp->sctp_state != SCTP_STATE_ESTABLISHED) {
-        X2AP_ERROR("x2ap_enb_data_p not NULL and sctp state not SCTP_STATE_ESTABLISHED, what to do?\n");
+        X2AP_ERROR("x2ap_enb_data_p not NULL and sctp state not SCTP_STATE_ESTABLISHED?\n");
+        if (sctp_new_association_resp->sctp_state == SCTP_STATE_SHUTDOWN){
+          RB_REMOVE(x2ap_enb_map, &instance_p->x2ap_enb_head, x2ap_enb_data_p);
+          return;
+        }
+
         exit(1);
       }
 
diff --git a/openair3/NAS/COMMON/IES/FGSMobileIdentity.c b/openair3/NAS/COMMON/IES/FGSMobileIdentity.c
index e3204b4c0c7816fee36eb029067162612b783b1f..5f920105f9b1307ff28d3761853dfbc13893b7c0 100644
--- a/openair3/NAS/COMMON/IES/FGSMobileIdentity.c
+++ b/openair3/NAS/COMMON/IES/FGSMobileIdentity.c
@@ -194,23 +194,23 @@ static int encode_guti_5gs_mobile_identity(Guti5GSMobileIdentity_t *guti, uint8_
 static int encode_suci_5gs_mobile_identity(Suci5GSMobileIdentity_t *suci, uint8_t *buffer)
 {
   uint32_t encoded = 0;
-  *(buffer + encoded) = 0x00 | (suci->supiformat << 4) | (suci->typeofidentity);
+  *(buffer + encoded) = (suci->supiformat << 4) | (suci->typeofidentity);
   encoded++;
-  *(buffer + encoded) = 0x00 | ((suci->mccdigit2 & 0xf) << 4) |
+  *(buffer + encoded) = ((suci->mccdigit2 & 0xf) << 4) |
                         (suci->mccdigit1 & 0xf);
   encoded++;
-  *(buffer + encoded) = 0x00 | ((suci->mncdigit3 & 0xf) << 4) |
+  *(buffer + encoded) = ((suci->mncdigit3 & 0xf) << 4) |
                         (suci->mccdigit3 & 0xf);
   encoded++;
-  *(buffer + encoded) = 0x00 | ((suci->mncdigit2 & 0xf) << 4) |
+  *(buffer + encoded) = ((suci->mncdigit2 & 0xf) << 4) |
                         (suci->mncdigit1 & 0xf);
   encoded++;
 
-  *(buffer + encoded) = 0x00 | ((suci->routingindicatordigit2 & 0xf) << 4) |
+  *(buffer + encoded) = ((suci->routingindicatordigit2 & 0xf) << 4) |
                         (suci->routingindicatordigit1 & 0xf);
   encoded++;
 
-  *(buffer + encoded) = 0x00 | ((suci->routingindicatordigit4 & 0xf) << 4) |
+  *(buffer + encoded) = ((suci->routingindicatordigit4 & 0xf) << 4) |
                         (suci->routingindicatordigit3 & 0xf);
   encoded++;
 
@@ -220,8 +220,15 @@ static int encode_suci_5gs_mobile_identity(Suci5GSMobileIdentity_t *suci, uint8_
   *(buffer + encoded) = suci->homenetworkpki;
   encoded++;
 
-  IES_ENCODE_U32(buffer, encoded, suci->schemeoutput);
+  char *ptr=suci->schemeoutput;
+  while ( ptr < suci->schemeoutput+strlen(suci->schemeoutput) ) {
+    buffer[encoded]=((*(ptr+1)-'0')<<4) | (*(ptr) -'0');
+    encoded++;
+    ptr+=2;
+  }
 
+  if (strlen(suci->schemeoutput)%2 == 1)
+    buffer[encoded++]=((*(ptr-1)-'0')) | 0xF0;
   return encoded;
 }
 
diff --git a/openair3/NAS/COMMON/IES/FGSMobileIdentity.h b/openair3/NAS/COMMON/IES/FGSMobileIdentity.h
index a673a86dd1be7eea096edd0eaa603989d7e50951..7968bc33006c255f10fec598edacb78976050e58 100644
--- a/openair3/NAS/COMMON/IES/FGSMobileIdentity.h
+++ b/openair3/NAS/COMMON/IES/FGSMobileIdentity.h
@@ -64,7 +64,7 @@ typedef struct {
   uint8_t  spare6:1;
   uint8_t  protectionschemeId:4;
   uint8_t  homenetworkpki;
-  uint32_t schemeoutput;
+  char schemeoutput[32];
 } Suci5GSMobileIdentity_t;
 
 typedef struct {
diff --git a/openair3/NAS/COMMON/NR_NAS_defs.h b/openair3/NAS/COMMON/NR_NAS_defs.h
index 906c0cf504a9d61059c509fc3c758e6605b81907..54ac8c037e9f3b672870ee6489dfb1e3e980ea5e 100644
--- a/openair3/NAS/COMMON/NR_NAS_defs.h
+++ b/openair3/NAS/COMMON/NR_NAS_defs.h
@@ -387,5 +387,6 @@ void processNAS(void *msg, NRUEcontext_t *UE);
 int identityRequest(void **msg, NRUEcontext_t *UE);
 int authenticationRequest(void **msg, NRUEcontext_t *UE);
 int securityModeCommand(void **msg, NRUEcontext_t *UE);
+void servingNetworkName(uint8_t *msg, char * imsiStr, int nmc_size);
 
 #endif
diff --git a/openair3/NAS/NR_UE/nr_nas_msg_sim.c b/openair3/NAS/NR_UE/nr_nas_msg_sim.c
index 55e21390bfe2f49f2e4e2de9276cc571a914a409..7308f677a18a271b41e98f98eb48b25067377bda 100644
--- a/openair3/NAS/NR_UE/nr_nas_msg_sim.c
+++ b/openair3/NAS/NR_UE/nr_nas_msg_sim.c
@@ -38,24 +38,15 @@
 #include "aka_functions.h"
 #include "secu_defs.h"
 #include "PduSessionEstablishRequest.h"
-# include "intertask_interface.h"
-
-/*char netName[] = "5G:mnc093.mcc208.3gppnetwork.org";
-char imsi[] = "2089300007487";
-// USIM_API_K: 5122250214c33e723a5dd523fc145fc0
-uint8_t k[16] = {0x51, 0x22, 0x25, 0x02, 0x14,0xc3, 0x3e, 0x72, 0x3a, 0x5d, 0xd5, 0x23, 0xfc, 0x14, 0x5f, 0xc0};
-// OPC: 981d464c7c52eb6e5036234984ad0bcf
-const uint8_t opc[16] = {0x98, 0x1d, 0x46, 0x4c,0x7c,0x52,0xeb, 0x6e, 0x50, 0x36, 0x23, 0x49, 0x84, 0xad, 0x0b, 0xcf};*/
-
-char netName[] = "5G:mnc099.mcc208.3gppnetwork.org";
-char imsi[] = "2089900007487"; //"208990100001100";
-// USIM_API_K: fe c8 6b a6 eb 70 7e d0 89 05 75 7b 1b b4 4b 8f 
-uint8_t k[16] = {0xfe, 0xc8, 0x6b, 0xa6, 0xeb, 0x70, 0x7e, 0xd0, 0x89, 0x05, 0x75, 0x7b, 0x1b, 0xb4, 0x4b, 0x8f};
-// OPC: c4 24 49 36 3b ba d0 2b 66 d1 6b c9 75 d7 7c c1
-const uint8_t opc[16] = {0xc4, 0x24, 0x49, 0x36, 0x3b, 0xba, 0xd0, 0x2b, 0x66, 0xd1, 0x6b, 0xc9, 0x75, 0xd7, 0x7c, 0xc1};
+#include "intertask_interface.h"
+#include "openair2/RRC/NAS/nas_config.h"
+#include <openair3/UICC/usim_interface.h>
+#include <openair3/NAS/COMMON/NR_NAS_defs.h>
+#include <openair1/PHY/phy_extern_nr_ue.h>
 
 uint8_t  *registration_request_buf;
 uint32_t  registration_request_len;
+extern char *baseNetAddress;
 
 static int nas_protected_security_header_encode(
   char                                       *buffer,
@@ -160,11 +151,11 @@ int mm_msg_encode(MM_msg *mm_msg, uint8_t *buffer, uint32_t len) {
   LOG_FUNC_RETURN (header_result + encode_result);
 }
 
-void transferRES(uint8_t ck[16], uint8_t ik[16], uint8_t *input, uint8_t rand[16], uint8_t *output) {
-  uint8_t S[100];
+void transferRES(uint8_t ck[16], uint8_t ik[16], uint8_t *input, uint8_t rand[16], uint8_t *output, uicc_t* uicc) {
+  uint8_t S[100]={0};
   S[0] = 0x6B;
-  int netNamesize = strlen(netName);
-  memcpy(&S[1], netName, netNamesize);
+  servingNetworkName (S+1, uicc->imsiStr, uicc->nmc_size);
+  int netNamesize = strlen((char*)S+1);
   S[1 + netNamesize] = (netNamesize & 0xff00) >> 8;
   S[2 + netNamesize] = (netNamesize & 0x00ff);
   for (int i = 0; i < 16; i++)
@@ -201,14 +192,15 @@ void transferRES(uint8_t ck[16], uint8_t ik[16], uint8_t *input, uint8_t rand[16
     output[i] = out[16 + i];
 }
 
-void derive_kausf(uint8_t ck[16], uint8_t ik[16], uint8_t sqn[6], uint8_t kausf[32]) {
-  uint8_t S[100];
+void derive_kausf(uint8_t ck[16], uint8_t ik[16], uint8_t sqn[6], uint8_t kausf[32], uicc_t *uicc) {
+  uint8_t S[100]={0};
   uint8_t key[32];
-  int netNamesize = strlen(netName);
+
   memcpy(&key[0], ck, 16);
   memcpy(&key[16], ik, 16);  //KEY
   S[0] = 0x6A;
-  memcpy(&S[1], netName, netNamesize);
+  servingNetworkName (S+1, uicc->imsiStr, uicc->nmc_size);
+  int netNamesize = strlen((char*)S+1);
   S[1 + netNamesize] = (uint8_t)((netNamesize & 0xff00) >> 8);
   S[2 + netNamesize] = (uint8_t)(netNamesize & 0x00ff);
   for (int i = 0; i < 6; i++) {
@@ -219,21 +211,21 @@ void derive_kausf(uint8_t ck[16], uint8_t ik[16], uint8_t sqn[6], uint8_t kausf[
   kdf(key, 32, S, 11 + netNamesize, kausf, 32);
 }
 
-void derive_kseaf(uint8_t kausf[32], uint8_t kseaf[32]) {
-  uint8_t S[100];
-  int netNamesize = strlen(netName);
+void derive_kseaf(uint8_t kausf[32], uint8_t kseaf[32], uicc_t *uicc) {
+  uint8_t S[100]={0};
   S[0] = 0x6C;  //FC
-  memcpy(&S[1], netName, netNamesize);
+  servingNetworkName (S+1, uicc->imsiStr, uicc->nmc_size);
+  int netNamesize = strlen((char*)S+1);
   S[1 + netNamesize] = (uint8_t)((netNamesize & 0xff00) >> 8);
   S[2 + netNamesize] = (uint8_t)(netNamesize & 0x00ff);
   kdf(kausf, 32, S, 3 + netNamesize, kseaf, 32);
 }
 
-void derive_kamf(uint8_t *kseaf, uint8_t *kamf, uint16_t abba) {
-  int imsiLen = strlen(imsi);
+void derive_kamf(uint8_t *kseaf, uint8_t *kamf, uint16_t abba, uicc_t* uicc) {
+  int imsiLen = strlen(uicc->imsiStr);
   uint8_t S[100];
   S[0] = 0x6D;  //FC = 0x6D
-  memcpy(&S[1], imsi, imsiLen);
+  memcpy(&S[1], uicc->imsiStr, imsiLen );
   S[1 + imsiLen] = (uint8_t)((imsiLen & 0xff00) >> 8);
   S[2 + imsiLen] = (uint8_t)(imsiLen & 0x00ff);
   S[3 + imsiLen] = abba & 0x00ff;
@@ -259,11 +251,11 @@ void derive_knas(algorithm_type_dist_t nas_alg_type, uint8_t nas_alg_id, uint8_t
     knas_int[i] = out[16 + i];
 }
 
-void generateRegistrationRequest(as_nas_info_t *initialNasMsg) {
+void generateRegistrationRequest(as_nas_info_t *initialNasMsg, int Mod_id) {
   int size = sizeof(mm_msg_header_t);
-  fgs_nas_message_t nas_msg;
-  memset(&nas_msg, 0, sizeof(fgs_nas_message_t));
+  fgs_nas_message_t nas_msg={0};
   MM_msg *mm_msg;
+  uicc_t * uicc=checkUicc(Mod_id);
 
   mm_msg = &nas_msg.plain.mm_msg;
   // set header
@@ -288,26 +280,31 @@ void generateRegistrationRequest(as_nas_info_t *initialNasMsg) {
     mm_msg->registration_request.fgsmobileidentity.guti.amfpointer = 0;
     mm_msg->registration_request.fgsmobileidentity.guti.amfsetid = 1016;
     mm_msg->registration_request.fgsmobileidentity.guti.tmsi = 10;
-    mm_msg->registration_request.fgsmobileidentity.guti.mncdigit1 = 9;
-    mm_msg->registration_request.fgsmobileidentity.guti.mncdigit2 = 9;
-    mm_msg->registration_request.fgsmobileidentity.guti.mncdigit3 = 0xf;
-    mm_msg->registration_request.fgsmobileidentity.guti.mccdigit1 = 2;
-    mm_msg->registration_request.fgsmobileidentity.guti.mccdigit2 = 0;
-    mm_msg->registration_request.fgsmobileidentity.guti.mccdigit3 = 8;
+    mm_msg->registration_request.fgsmobileidentity.guti.mncdigit1 =
+      uicc->nmc_size==2 ? uicc->imsiStr[3]-'0' :  uicc->imsiStr[4]-'0';
+    mm_msg->registration_request.fgsmobileidentity.guti.mncdigit2 =
+      uicc->nmc_size==2 ? uicc->imsiStr[4]-'0' :  uicc->imsiStr[5]-'0';
+    mm_msg->registration_request.fgsmobileidentity.guti.mncdigit3 =
+      uicc->nmc_size==2 ? 0xf : uicc->imsiStr[3]-'0';
+    mm_msg->registration_request.fgsmobileidentity.guti.mccdigit1 = uicc->imsiStr[0]-'0';
+    mm_msg->registration_request.fgsmobileidentity.guti.mccdigit2 = uicc->imsiStr[1]-'0';
+    mm_msg->registration_request.fgsmobileidentity.guti.mccdigit3 = uicc->imsiStr[2]-'0';
 
     size += 13;
 
   } else {
     mm_msg->registration_request.fgsmobileidentity.suci.typeofidentity = FGS_MOBILE_IDENTITY_SUCI;
-    mm_msg->registration_request.fgsmobileidentity.suci.mncdigit1 = 9;
-    mm_msg->registration_request.fgsmobileidentity.suci.mncdigit2 = 9;
-    mm_msg->registration_request.fgsmobileidentity.suci.mncdigit3 = 0xf;
-    mm_msg->registration_request.fgsmobileidentity.suci.mccdigit1 = 2;
-    mm_msg->registration_request.fgsmobileidentity.suci.mccdigit2 = 0;
-    mm_msg->registration_request.fgsmobileidentity.suci.mccdigit3 = 8;
-    mm_msg->registration_request.fgsmobileidentity.suci.schemeoutput = 0x4778;
-
-    size += 14;
+    mm_msg->registration_request.fgsmobileidentity.suci.mncdigit1 =
+     uicc->nmc_size==2 ? uicc->imsiStr[3]-'0' :  uicc->imsiStr[4]-'0';
+    mm_msg->registration_request.fgsmobileidentity.suci.mncdigit2 =
+      uicc->nmc_size==2 ? uicc->imsiStr[4]-'0' :  uicc->imsiStr[5]-'0';
+    mm_msg->registration_request.fgsmobileidentity.suci.mncdigit3 =
+      uicc->nmc_size==2 ? 0xf : uicc->imsiStr[3]-'0';
+    mm_msg->registration_request.fgsmobileidentity.suci.mccdigit1 = uicc->imsiStr[0]-'0';
+    mm_msg->registration_request.fgsmobileidentity.suci.mccdigit2 = uicc->imsiStr[1]-'0';
+    mm_msg->registration_request.fgsmobileidentity.suci.mccdigit3 = uicc->imsiStr[2]-'0';
+    memcpy(mm_msg->registration_request.fgsmobileidentity.suci.schemeoutput, uicc->imsiStr+3+uicc->nmc_size, strlen(uicc->imsiStr) - (3+uicc->nmc_size));
+    size += sizeof(Suci5GSMobileIdentity_t);
   }
 
   mm_msg->registration_request.presencemask |= REGISTRATION_REQUEST_5GMM_CAPABILITY_PRESENT;
@@ -334,7 +331,7 @@ void generateRegistrationRequest(as_nas_info_t *initialNasMsg) {
 
 }
 
-void generateIdentityResponse(as_nas_info_t *initialNasMsg, uint8_t identitytype) {
+void generateIdentityResponse(as_nas_info_t *initialNasMsg, uint8_t identitytype, uicc_t* uicc) {
   int size = sizeof(mm_msg_header_t);
   fgs_nas_message_t nas_msg;
   memset(&nas_msg, 0, sizeof(fgs_nas_message_t));
@@ -356,15 +353,17 @@ void generateIdentityResponse(as_nas_info_t *initialNasMsg, uint8_t identitytype
   size += 1;
   if(identitytype == FGS_MOBILE_IDENTITY_SUCI){
     mm_msg->fgs_identity_response.fgsmobileidentity.suci.typeofidentity = FGS_MOBILE_IDENTITY_SUCI;
-    mm_msg->fgs_identity_response.fgsmobileidentity.suci.mncdigit1 = 9;
-    mm_msg->fgs_identity_response.fgsmobileidentity.suci.mncdigit2 = 9;
-    mm_msg->fgs_identity_response.fgsmobileidentity.suci.mncdigit3 = 0xf;
-    mm_msg->fgs_identity_response.fgsmobileidentity.suci.mccdigit1 = 2;
-    mm_msg->fgs_identity_response.fgsmobileidentity.suci.mccdigit2 = 0;
-    mm_msg->fgs_identity_response.fgsmobileidentity.suci.mccdigit3 = 8;
-    mm_msg->fgs_identity_response.fgsmobileidentity.suci.schemeoutput = 0x4778;
-
-    size += 14;
+    mm_msg->fgs_identity_response.fgsmobileidentity.suci.mncdigit1 =
+      uicc->nmc_size==2 ? uicc->imsiStr[3]-'0' :  uicc->imsiStr[4]-'0';
+    mm_msg->fgs_identity_response.fgsmobileidentity.suci.mncdigit2 =
+      uicc->nmc_size==2 ? uicc->imsiStr[4]-'0' :  uicc->imsiStr[5]-'0';
+    mm_msg->fgs_identity_response.fgsmobileidentity.suci.mncdigit3 =
+      uicc->nmc_size==2? 0xF : uicc->imsiStr[3]-'0';
+    mm_msg->fgs_identity_response.fgsmobileidentity.suci.mccdigit1 = uicc->imsiStr[0]-'0';
+    mm_msg->fgs_identity_response.fgsmobileidentity.suci.mccdigit2 = uicc->imsiStr[1]-'0';
+    mm_msg->fgs_identity_response.fgsmobileidentity.suci.mccdigit3 = uicc->imsiStr[2]-'0';
+    memcpy(mm_msg->registration_request.fgsmobileidentity.suci.schemeoutput, uicc->imsiStr+3+uicc->nmc_size, strlen(uicc->imsiStr) - (3+uicc->nmc_size));
+    size += sizeof(Suci5GSMobileIdentity_t);
   }
 
   // encode the message
@@ -375,7 +374,7 @@ void generateIdentityResponse(as_nas_info_t *initialNasMsg, uint8_t identitytype
 }
 
 OctetString knas_int;
-void generateAuthenticationResp(as_nas_info_t *initialNasMsg, uint8_t *buf){
+static void generateAuthenticationResp(as_nas_info_t *initialNasMsg, uint8_t *buf, uicc_t *uicc){
 
   uint8_t ak[6];
 
@@ -393,9 +392,9 @@ void generateAuthenticationResp(as_nas_info_t *initialNasMsg, uint8_t *buf){
 
   uint8_t resTemp[16];
   uint8_t ck[16], ik[16], output[16];
-  f2345(k, rand, resTemp, ck, ik, ak, opc);
+  f2345(uicc->key, rand, resTemp, ck, ik, ak, uicc->opc);
 
-  transferRES(ck, ik, resTemp, rand, output);
+  transferRES(ck, ik, resTemp, rand, output, uicc);
 
   // get knas_int
   knas_int.length = 16;
@@ -404,9 +403,9 @@ void generateAuthenticationResp(as_nas_info_t *initialNasMsg, uint8_t *buf){
     sqn[index] = buf[26+index];
   }
 
-  derive_kausf(ck, ik, sqn, kausf);
-  derive_kseaf(kausf, kseaf);
-  derive_kamf(kseaf, kamf, 0x0000);
+  derive_kausf(ck, ik, sqn, kausf, uicc);
+  derive_kseaf(kausf, kseaf, uicc);
+  derive_kamf(kseaf, kamf, 0x0000, uicc);
   derive_knas(0x02, 2, kamf, knas_int.value);
 
   printf("kausf:");
@@ -613,6 +612,19 @@ void generateRegistrationComplete(as_nas_info_t *initialNasMsg, SORTransparentCo
   }
 }
 
+void decodeDownlinkNASTransport(as_nas_info_t *initialNasMsg, uint8_t * pdu_buffer){
+  uint8_t msg_type = *(pdu_buffer + 16);
+  if(msg_type == FGS_PDU_SESSION_ESTABLISHMENT_ACC){
+    sprintf(baseNetAddress, "%d.%d", *(pdu_buffer + 39),*(pdu_buffer + 40));
+    int third_octet = *(pdu_buffer + 41);
+    int fourth_octet = *(pdu_buffer + 42);
+    LOG_I(NAS, "Received PDU Session Establishment Accept\n");
+    nas_config(1,third_octet,fourth_octet,"ue");
+  } else {
+    LOG_E(NAS, "Received unexpected message in DLinformationTransfer %d\n", msg_type);
+  }
+}
+
 void generatePduSessionEstablishRequest(as_nas_info_t *initialNasMsg){
   //wait send RegistrationComplete
   usleep(100*150);
@@ -700,6 +712,7 @@ void generatePduSessionEstablishRequest(as_nas_info_t *initialNasMsg){
   }
 }
 
+
 void *nas_nrue_task(void *args_p)
 {
   MessageDef           *msg_p;
@@ -719,6 +732,8 @@ void *nas_nrue_task(void *args_p)
     if (msg_p != NULL) {
       instance = msg_p->ittiMsgHeader.originInstance;
       Mod_id = instance ;
+      uicc_t *uicc=checkUicc(Mod_id);
+
       if (instance == INSTANCE_DEFAULT) {
         printf("%s:%d: FATAL: instance is INSTANCE_DEFAULT, should not happen.\n",
                __FILE__, __LINE__);
@@ -815,6 +830,16 @@ void *nas_nrue_task(void *args_p)
             LOG_I(NAS, "Send NAS_UPLINK_DATA_REQ message(PduSessionEstablishRequest)\n");
           }
         }
+        else if((pdu_buffer + 16) != NULL){
+          msg_type = *(pdu_buffer + 16);
+          if(msg_type == FGS_PDU_SESSION_ESTABLISHMENT_ACC){
+            sprintf(baseNetAddress, "%d.%d", *(pdu_buffer + 39),*(pdu_buffer + 40));
+            int third_octet = *(pdu_buffer + 41);
+            int fourth_octet = *(pdu_buffer + 42);
+            LOG_I(NAS, "Received PDU Session Establishment Accept\n");
+            nas_config(1,third_octet,fourth_octet,"ue");
+          }
+        }
 
         break;
       }
@@ -838,8 +863,7 @@ void *nas_nrue_task(void *args_p)
                                                                             Mod_id,
                                                                             NAS_DOWNLINK_DATA_IND(msg_p).nasMsg.length,
                                                                             NAS_DOWNLINK_DATA_IND(msg_p).nasMsg.data);
-        as_nas_info_t initialNasMsg;
-        memset(&initialNasMsg, 0, sizeof(as_nas_info_t));
+        as_nas_info_t initialNasMsg={0};
 
         pdu_buffer = NAS_DOWNLINK_DATA_IND(msg_p).nasMsg.data;
         if((pdu_buffer + 1) != NULL){
@@ -856,14 +880,18 @@ void *nas_nrue_task(void *args_p)
 
         switch(msg_type){
           case FGS_IDENTITY_REQUEST:
-              generateIdentityResponse(&initialNasMsg,*(pdu_buffer+3));
+	            generateIdentityResponse(&initialNasMsg,*(pdu_buffer+3), uicc);
               break;
           case FGS_AUTHENTICATION_REQUEST:
-              generateAuthenticationResp(&initialNasMsg, pdu_buffer);
+	            generateAuthenticationResp(&initialNasMsg, pdu_buffer, uicc);
               break;
           case FGS_SECURITY_MODE_COMMAND:
             generateSecurityModeComplete(&initialNasMsg);
             break;
+          case FGS_DOWNLINK_NAS_TRANSPORT:
+            decodeDownlinkNASTransport(&initialNasMsg, pdu_buffer);
+            break;
+
           default:
               LOG_W(NR_RRC,"unknow message type %d\n",msg_type);
               break;
diff --git a/openair3/NAS/NR_UE/nr_nas_msg_sim.h b/openair3/NAS/NR_UE/nr_nas_msg_sim.h
index 2f123a6f04822605d18b5d721947c164c9c80460..348c27ecc89d44d1a4d6fd2bd250819f4203d401 100644
--- a/openair3/NAS/NR_UE/nr_nas_msg_sim.h
+++ b/openair3/NAS/NR_UE/nr_nas_msg_sim.h
@@ -56,9 +56,11 @@
 #define FGS_SECURITY_MODE_COMMAND                          0b01011101 /* 93 = 0x5d */
 #define FGS_SECURITY_MODE_COMPLETE                         0b01011110 /* 94 = 0x5e */
 #define FGS_UPLINK_NAS_TRANSPORT                           0b01100111 /* 103= 0x67 */
+#define FGS_DOWNLINK_NAS_TRANSPORT                         0b01101000 /* 104= 0x68 */
 
 // message type for 5GS session management
 #define FGS_PDU_SESSION_ESTABLISHMENT_REQ                  0b11000001 /* 193= 0xc1 */
+#define FGS_PDU_SESSION_ESTABLISHMENT_ACC                  0b11000010 /* 194= 0xc2 */
 
 #define INITIAL_REGISTRATION                               0b001
 
@@ -114,9 +116,7 @@ typedef union {
   fgs_nas_message_plain_t plain;
 } fgs_nas_message_t;
 
-void generateRegistrationRequest(as_nas_info_t *initialNasMsg);
-void generateIdentityResponse(as_nas_info_t *initialNasMsg, uint8_t identitytype);
-void generateAuthenticationResp(as_nas_info_t *initialNasMsg, uint8_t *buf);
+void generateRegistrationRequest(as_nas_info_t *initialNasMsg, int Mod_id);
 void generateSecurityModeComplete(as_nas_info_t *initialNasMsg);
 void generateRegistrationComplete(as_nas_info_t *initialNasMsg, SORTransparentContainer *sortransparentcontainer);
 void generatePduSessionEstablishRequest(as_nas_info_t *initialNasMsg);
diff --git a/openair3/NGAP/ngap_common.h b/openair3/NGAP/ngap_common.h
index 6803adb0dda43fface7944d7d9ac93dd106df38f..283dd2bffa58ae41aca733b9a955053f04bb0bf1 100644
--- a/openair3/NGAP/ngap_common.h
+++ b/openair3/NGAP/ngap_common.h
@@ -142,7 +142,11 @@ extern int asn1_xer_print;
       } \
     } \
     if (ie == NULL ) { \
-      NGAP_ERROR("NGAP_FIND_PROTOCOLIE_BY_ID: %s %d: ie is NULL\n",__FILE__,__LINE__);\
+      if (mandatory) {\
+      NGAP_ERROR("NGAP_FIND_PROTOCOLIE_BY_ID: %s %d: ie is NULL (searching for ie: %ld)\n",__FILE__,__LINE__, IE_ID);\
+      abort();\
+      }\
+      else NGAP_INFO("NGAP_FIND_PROTOCOLIE_BY_ID: %s %d: ie is NULL (searching for ie: %ld)\n",__FILE__,__LINE__, IE_ID);\
     } \
   } while(0)
 /** \brief Function callback prototype.
diff --git a/openair3/NGAP/ngap_gNB_handlers.c b/openair3/NGAP/ngap_gNB_handlers.c
index e398f8fa3e1c39d0e5ac5a9d18ce57c766c794ef..401695473cfc044c16baa9912e977b16711f2a56 100644
--- a/openair3/NGAP/ngap_gNB_handlers.c
+++ b/openair3/NGAP/ngap_gNB_handlers.c
@@ -657,6 +657,7 @@ int ngap_gNB_handle_error_indication(uint32_t         assoc_id,
           case NGAP_CauseRadioNetwork_up_integrity_protection_not_possible:
             NGAP_WARN("Received NG Error indication NGAP_CauseRadioNetwork_up_integrity_protection_not_possible\n");
             break;
+
           case NGAP_CauseRadioNetwork_up_confidentiality_protection_not_possible:
             NGAP_WARN("Received NG Error indication NGAP_CauseRadioNetwork_up_confidentiality_protection_not_possible\n");
             break;
@@ -1030,6 +1031,12 @@ int ngap_gNB_handle_initial_context_request(uint32_t   assoc_id,
                 
                 /* Set the QOS informations */
                 NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).pdusession_param[i].qos[qosIdx].qfi = (uint8_t)qosFlowItem_p->qosFlowIdentifier;
+                if(qosFlowItem_p->qosFlowLevelQosParameters.qosCharacteristics.present == NGAP_QosCharacteristics_PR_nonDynamic5QI){
+                  if(qosFlowItem_p->qosFlowLevelQosParameters.qosCharacteristics.choice.nonDynamic5QI != NULL){
+                    NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).pdusession_param[i].qos[qosIdx].fiveQI =
+                        (uint64_t)qosFlowItem_p->qosFlowLevelQosParameters.qosCharacteristics.choice.nonDynamic5QI->fiveQI;
+                  }
+                }
               
                 NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).pdusession_param[i].qos[qosIdx].allocation_retention_priority.priority_level =
                   qosFlowItem_p->qosFlowLevelQosParameters.allocationAndRetentionPriority.priorityLevelARP;
@@ -1063,13 +1070,14 @@ int ngap_gNB_handle_initial_context_request(uint32_t   assoc_id,
   
   //if (ie != NULL) { /* checked by macro but cppcheck doesn't see it */
     NGAP_AllowedNSSAI_Item_t *allow_nssai_item_p = NULL;
-  
-    NGAP_WARN("AllowedNSSAI.list.count %d\n", ie != NULL ? ie->value.choice.AllowedNSSAI.list.count : 2);
+
     //NGAP_DEBUG("AllowedNSSAI.list.count %d\n", ie->value.choice.AllowedNSSAI.list.count);
     //DevAssert(ie->value.choice.AllowedNSSAI.list.count > 0);
     //DevAssert(ie->value.choice.AllowedNSSAI.list.count <= NGAP_maxnoofAllowedS_NSSAIs);
 
     if (ie == NULL) {
+        NGAP_WARN("AllowedNSSAI not present, forging 2 NSSAI\n");
+
     	NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).nb_allowed_nssais = 2;
 
     	NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).allowed_nssai[0].sST = 01;
@@ -1086,7 +1094,7 @@ int ngap_gNB_handle_initial_context_request(uint32_t   assoc_id,
     	NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).allowed_nssai[1].sD[1] = 00;//22;
     	NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).allowed_nssai[1].sD[2] = 01;//33;
     } else {
-
+    NGAP_INFO("AllowedNSSAI.list.count %d\n", ie->value.choice.AllowedNSSAI.list.count);
     NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).nb_allowed_nssais = ie->value.choice.AllowedNSSAI.list.count;
     
     for(i = 0; i < ie->value.choice.AllowedNSSAI.list.count; i++) {
diff --git a/openair3/NGAP/ngap_gNB_nas_procedures.c b/openair3/NGAP/ngap_gNB_nas_procedures.c
index 6b6164358837893ab60649259c40541eeb9c4ece..8efab98dfa60d7f77ba5e7ed18806eb2d1a68cc8 100644
--- a/openair3/NGAP/ngap_gNB_nas_procedures.c
+++ b/openair3/NGAP/ngap_gNB_nas_procedures.c
@@ -656,6 +656,7 @@ int ngap_gNB_initial_ctxt_resp(
   NGAP_InitialContextSetupResponse_t    *out;
   NGAP_InitialContextSetupResponseIEs_t *ie;
   uint8_t  *buffer = NULL;
+  uint8_t pdusessionTransfer_buffer[1000];
   uint32_t length;
   int      i;
   asn_encode_to_new_buffer_result_t res = { NULL, {0, NULL, NULL} };
@@ -729,7 +730,8 @@ int ngap_gNB_initial_ctxt_resp(
       pdusessionTransfer_p = (NGAP_PDUSessionResourceSetupResponseTransfer_t *)calloc(1, sizeof(NGAP_PDUSessionResourceSetupResponseTransfer_t));
 
       pdusessionTransfer_p->dLQosFlowPerTNLInformation.uPTransportLayerInformation.present = NGAP_UPTransportLayerInformation_PR_gTPTunnel;
-     
+    
+      pdusessionTransfer_p->dLQosFlowPerTNLInformation.uPTransportLayerInformation.choice.gTPTunnel = (NGAP_GTPTunnel_t *)calloc(1, sizeof(NGAP_GTPTunnel_t)); 
       GTP_TEID_TO_ASN1(initial_ctxt_resp_p->pdusessions[i].gtp_teid, &pdusessionTransfer_p->dLQosFlowPerTNLInformation.uPTransportLayerInformation.choice.gTPTunnel->gTP_TEID);
 
       pdusessionTransfer_p->dLQosFlowPerTNLInformation.uPTransportLayerInformation.choice.gTPTunnel->transportLayerAddress.buf = malloc(initial_ctxt_resp_p->pdusessions[i].gNB_addr.length);
@@ -757,17 +759,30 @@ int ngap_gNB_initial_ctxt_resp(
         ass_qos_item_p->qosFlowIdentifier = initial_ctxt_resp_p->pdusessions[i].associated_qos_flows[j].qfi;
 
         /* qosFlowMappingIndication */
-        if(initial_ctxt_resp_p->pdusessions[i].associated_qos_flows[j].qos_flow_mapping_ind != QOSFLOW_MAPPING_INDICATION_NON) {
-          ass_qos_item_p->qosFlowMappingIndication = malloc(sizeof(*ass_qos_item_p->qosFlowMappingIndication));
-          *ass_qos_item_p->qosFlowMappingIndication = initial_ctxt_resp_p->pdusessions[i].associated_qos_flows[j].qos_flow_mapping_ind;
-        }
+        //if(initial_ctxt_resp_p->pdusessions[i].associated_qos_flows[j].qos_flow_mapping_ind != QOSFLOW_MAPPING_INDICATION_NON) {
+        //  ass_qos_item_p->qosFlowMappingIndication = malloc(sizeof(*ass_qos_item_p->qosFlowMappingIndication));
+        //  *ass_qos_item_p->qosFlowMappingIndication = initial_ctxt_resp_p->pdusessions[i].associated_qos_flows[j].qos_flow_mapping_ind;
+        // }
         ASN_SEQUENCE_ADD(&pdusessionTransfer_p->dLQosFlowPerTNLInformation.associatedQosFlowList.list, ass_qos_item_p);
       }
                
       memset(&res, 0, sizeof(res));
-      res = asn_encode_to_new_buffer(NULL, ATS_ALIGNED_CANONICAL_PER, &asn_DEF_NGAP_PDUSessionResourceSetupResponseTransfer, pdusessionTransfer_p);
-      item->pDUSessionResourceSetupResponseTransfer.buf = res.buffer;
-      item->pDUSessionResourceSetupResponseTransfer.size = res.result.encoded;
+      //res = asn_encode_to_new_buffer(NULL, ATS_ALIGNED_CANONICAL_PER, &asn_DEF_NGAP_PDUSessionResourceSetupResponseTransfer, pdusessionTransfer_p);
+      //item->pDUSessionResourceSetupResponseTransfer.buf = res.buffer;
+      //item->pDUSessionResourceSetupResponseTransfer.size = res.result.encoded;
+
+      if (asn1_xer_print) {
+        xer_fprint(stdout, &asn_DEF_NGAP_PDUSessionResourceSetupResponseTransfer, pdusessionTransfer_p);
+      }
+
+      memset(pdusessionTransfer_buffer, 0, 1000);
+      asn_enc_rval_t  enc_rval = aper_encode_to_buffer(&asn_DEF_NGAP_PDUSessionResourceSetupResponseTransfer, 
+          NULL, 
+          pdusessionTransfer_p, 
+          pdusessionTransfer_buffer,1000);
+      AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n", enc_rval.failed_type->name, enc_rval.encoded);
+      item->pDUSessionResourceSetupResponseTransfer.buf = pdusessionTransfer_buffer; 
+      item->pDUSessionResourceSetupResponseTransfer.size = enc_rval.encoded;
 
       ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NGAP_PDUSessionResourceSetupResponseTransfer, pdusessionTransfer_p);
     
@@ -846,6 +861,10 @@ int ngap_gNB_initial_ctxt_resp(
     ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
   }
 
+  if (asn1_xer_print) {
+    xer_fprint(stdout, &asn_DEF_NGAP_NGAP_PDU, &pdu);
+  }
+
   if (ngap_gNB_encode_pdu(&pdu, &buffer, &length) < 0) {
     NGAP_ERROR("Failed to encode InitialContextSetupResponse\n");
     /* Encode procedure has failed... */
diff --git a/openair3/SCTP/sctp_eNB_task.c b/openair3/SCTP/sctp_eNB_task.c
index af49c5c350d9cde5d6db36ffb31c78cb9749ca48..a14d4b9780c487b8f1cf01d3b510de2bc486041a 100644
--- a/openair3/SCTP/sctp_eNB_task.c
+++ b/openair3/SCTP/sctp_eNB_task.c
@@ -985,6 +985,7 @@ sctp_eNB_read_from_socket(
         if (SCTP_SHUTDOWN_EVENT == snp->sn_header.sn_type) {
             itti_unsubscribe_event_fd(TASK_SCTP, sctp_cnx->sd);
 
+            SCTP_WARN("Received SCTP SHUTDOWN EVENT\n");
             close(sctp_cnx->sd);
 
             sctp_itti_send_association_resp(
@@ -1026,7 +1027,14 @@ sctp_eNB_read_from_socket(
             break;
 
             default:
-                SCTP_WARN("unhandled: SCTP_ASSOC_CHANGE to %d\n", sctp_assoc_changed->sac_state);
+                if ( sctp_assoc_changed->sac_state == SCTP_SHUTDOWN_COMP) 
+                    SCTP_WARN("SCTP_ASSOC_CHANGE to SSCTP_SHUTDOWN_COMP\n");
+                if ( sctp_assoc_changed->sac_state == SCTP_RESTART) 
+                    SCTP_WARN("SCTP_ASSOC_CHANGE to SCTP_RESTART\n");
+                if ( sctp_assoc_changed->sac_state == SCTP_CANT_STR_ASSOC) 
+                    SCTP_ERROR("SCTP_ASSOC_CHANGE to SCTP_CANT_STR_ASSOC\n");
+                if ( sctp_assoc_changed->sac_state == SCTP_COMM_LOST) 
+                    SCTP_ERROR("SCTP_ASSOC_CHANGE to SCTP_COMM_LOST\n");
                 break;
             }
         }
diff --git a/openair3/UICC/usim_interface.c b/openair3/UICC/usim_interface.c
index 15a4e2e540e3b894b998d2c5628200d4ac05f74d..0973d7508204a3ab0f8536bf9225256ef1e3bbca 100644
--- a/openair3/UICC/usim_interface.c
+++ b/openair3/UICC/usim_interface.c
@@ -20,9 +20,11 @@
 * For more information about the OpenAirInterface (OAI) Software Alliance:
 *      contact@openairinterface.org
 */
+#include <ctype.h>
 
 #include <openair3/UICC/usim_interface.h>
 #include <openair3/NAS/COMMON/milenage.h>
+extern uint16_t NB_UE_INST;
 
 #define UICC_SECTION    "uicc"
 #define UICC_CONFIG_HELP_OPTIONS     " list of comma separated options to interface a simulated (real UICC to be developped). Available options: \n"\
@@ -34,18 +36,20 @@
 /*   optname                     helpstr                     paramflags           XXXptr                               defXXXval                          type         numelt  */
 /*-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
 #define UICC_PARAMS_DESC {\
-    {"imsi",             "USIM IMSI\n",          0,         strptr:&(uicc->imsiStr),              defstrval:"",           TYPE_STRING,    0 },\
+    {"imsi",             "USIM IMSI\n",          0,         strptr:&(uicc->imsiStr),              defstrval:"2089900007487",           TYPE_STRING,    0 },\
     {"nmc_size"          "number of digits in NMC", 0,      iptr:&(uicc->nmc_size),               defintval:2,            TYPE_INT,       0 },\
-    {"key",              "USIM Ki\n",            0,         strptr:&(uicc->keyStr),               defstrval:"",           TYPE_STRING,    0 },\
-    {"opc",              "USIM OPc\n",           0,         strptr:&(uicc->opcStr),               defstrval:"",           TYPE_STRING,    0 },\
+    {"key",              "USIM Ki\n",            0,         strptr:&(uicc->keyStr),               defstrval:"fec86ba6eb707ed08905757b1bb44b8f", TYPE_STRING,    0 },\
+    {"opc",              "USIM OPc\n",           0,         strptr:&(uicc->opcStr),               defstrval:"c42449363bbad02b66d16bc975d77cc1", TYPE_STRING,    0 },\
     {"amf",              "USIM amf\n",           0,         strptr:&(uicc->amfStr),               defstrval:"8000",       TYPE_STRING,    0 },\
     {"sqn",              "USIM sqn\n",           0,         strptr:&(uicc->sqnStr),               defstrval:"000000",     TYPE_STRING,    0 },\
   };
 
+static uicc_t** uiccArray=NULL;
+
 const char *hexTable="0123456789abcdef";
 static inline uint8_t mkDigit(unsigned char in) {
   for (int i=0; i<16; i++)
-    if (in==hexTable[i])
+    if (tolower(in)==hexTable[i])
       return i;
   LOG_E(SIM,"Impossible hexa input: %c\n",in);
   return 0;
@@ -65,7 +69,7 @@ uicc_t *init_uicc(char *sectionName) {
   // we can read the IMSI from the USIM
   // key, OPc, sqn, amf don't need to be read from the true USIM 
   int ret = config_get( uicc_params,sizeof(uicc_params)/sizeof(paramdef_t),sectionName);
-  AssertFatal(ret >= 0, "configuration couldn't be performed");
+  AssertFatal(ret >= 0, "configuration couldn't be performed for uicc name: %s", sectionName);
   LOG_I(SIM, "UICC simulation: IMSI=%s, Ki=%s, OPc=%s\n", uicc->imsiStr, uicc->keyStr, uicc->opcStr);
   to_hex(uicc->keyStr,uicc->key, sizeof(uicc->key) );
   to_hex(uicc->opcStr,uicc->opc, sizeof(uicc->opc) );
@@ -90,3 +94,15 @@ void uicc_milenage_generate(uint8_t *autn, uicc_t *uicc) {
   log_dump(SIM,autn,sizeof(autn), LOG_DUMP_CHAR,"milenage output autn:");
 }
 
+uicc_t * checkUicc(int Mod_id) {
+  AssertFatal(Mod_id < NB_UE_INST, "Mod_id must be less than NB_UE_INST. Mod_id:%d NB_UE_INST:%d", Mod_id,NB_UE_INST);
+  if(uiccArray==NULL){
+    uiccArray=(uicc_t **)calloc(1,sizeof(uicc_t*)*NB_UE_INST);
+  }
+  if (!uiccArray[Mod_id]) {
+    char uiccName[64];
+    sprintf(uiccName,"uicc%d",  Mod_id);
+    uiccArray[Mod_id]=(void*)init_uicc(uiccName);
+  }
+  return (uicc_t*) uiccArray[Mod_id];  
+}
diff --git a/openair3/UICC/usim_interface.h b/openair3/UICC/usim_interface.h
index e8f241c1e815403905a8a551237f6382ccb1a65e..44c27c772ed32ada79fda8dc37bb9535f07226cd 100644
--- a/openair3/UICC/usim_interface.h
+++ b/openair3/UICC/usim_interface.h
@@ -66,6 +66,8 @@ typedef struct {
 /*
  * Read the configuration file, section name variable to be able to manage several UICC
  */
+uicc_t *checkUicc(int Mod_id);
 uicc_t *init_uicc(char *sectionName);
 void uicc_milenage_generate(uint8_t * autn, uicc_t *uicc);
+uicc_t * checkUicc(int Mod_id);
 #endif
diff --git a/openair3/ocp-gtpu/gtp_itf.cpp b/openair3/ocp-gtpu/gtp_itf.cpp
index 82a1d782ec5dc364a214763b95e6bffc58efdcd9..e12a4d66a85d3d9b0724159f2f6dbafcc5a89d83 100644
--- a/openair3/ocp-gtpu/gtp_itf.cpp
+++ b/openair3/ocp-gtpu/gtp_itf.cpp
@@ -275,12 +275,15 @@ static void gtpv1uEndTunnel(instance_t instance, gtpv1u_enb_tunnel_data_req_t *r
   to.sin_family      = AF_INET;
   to.sin_port        = htons(tmp.outgoing_port);
   to.sin_addr.s_addr = tmp.outgoing_ip_addr;
+
+  char ip4[INET_ADDRSTRLEN];
+  //char ip6[INET6_ADDRSTRLEN];
   LOG_D(GTPU,"sending end packet to %s\n", inet_ntoa(to.sin_addr) );
 
   if (sendto(compatInst(instance), (void *)&msgHdr, sizeof(msgHdr), 0,(struct sockaddr *)&to, sizeof(to) ) !=  sizeof(msgHdr)) {
     LOG_E(GTPU,
-          "[SD %ld] Failed to send data to " IPV4_ADDR " on port %d, buffer size %lu\n",
-          compatInst(instance), IPV4_ADDR_FORMAT(tmp.outgoing_ip_addr), tmp.outgoing_port, sizeof(msgHdr));
+          "[SD %ld] Failed to send data to %s on port %d, buffer size %lu\n",
+          compatInst(instance), inet_ntop(AF_INET, &tmp.outgoing_ip_addr, ip4, INET_ADDRSTRLEN), tmp.outgoing_port, sizeof(msgHdr));
   }
 }
 
@@ -547,6 +550,7 @@ int gtpv1u_update_ngu_tunnel(
   const gtpv1u_gnb_create_tunnel_req_t *const  create_tunnel_req_pP,
   const rnti_t prior_rnti
 ) {
+  AssertFatal( false, "to be developped\n");
   return GTPNOK;
 }
 
@@ -718,7 +722,7 @@ static int Gtpv1uHandleGpdu(int h,
   int offset=8;
 
   if( msgHdr->E ||  msgHdr->S ||msgHdr->PN)
-    offset+=4;
+    offset+=8;
 
   // This context is not good for gtp
   // frame, ... has no meaning
diff --git a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp
index fd4a830a02bbce970bc140784ef9e332d95a1eca..877f60799049d0d7a3f963fe24c9cec81d5a3809 100644
--- a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp
+++ b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp
@@ -385,14 +385,14 @@ static int trx_usrp_write(openair0_device *device,
 #if defined(__x86_64) || defined(__i386__)
   #ifdef __AVX2__
       nsamps2 = (nsamps+7)>>3;
-      __m256i buff_tx[8][nsamps2];
+      __m256i buff_tx[cc<2?2:cc][nsamps2];
   #else
     nsamps2 = (nsamps+3)>>2;
-    __m128i buff_tx[8][nsamps2];
+    __m128i buff_tx[cc<2?2:cc][nsamps2];
   #endif
 #elif defined(__arm__)
     nsamps2 = (nsamps+3)>>2;
-    int16x8_t buff_tx[8][nsamps2];
+    int16x8_t buff_tx[cc<2?2:cc][nsamps2];
 #else
 #error Unsupported CPU architecture, USRP device cannot be built
 #endif
@@ -523,14 +523,14 @@ void *trx_usrp_write_thread(void * arg){
     #if defined(__x86_64) || defined(__i386__)
       #ifdef __AVX2__
         nsamps2 = (nsamps+7)>>3;
-        __m256i buff_tx[8][nsamps2];
+        __m256i buff_tx[cc<2?2:cc][nsamps2];
       #else
         nsamps2 = (nsamps+3)>>2;
-        __m128i buff_tx[8][nsamps2];
+        __m128i buff_tx[cc<2?2:cc][nsamps2];
       #endif
     #elif defined(__arm__)
       nsamps2 = (nsamps+3)>>2;
-      int16x8_t buff_tx[8][nsamps2];
+      int16x8_t buff_tx[cc<2?2:cc][nsamps2];
     #else
     #error Unsupported CPU architecture, USRP device cannot be built
     #endif
@@ -582,7 +582,6 @@ void *trx_usrp_write_thread(void * arg){
     VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_USRP_SEND_RETURN, ret );
     VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE_THREAD, 0 );
 
-    if(0) break;
   }
 
   return NULL;
@@ -625,14 +624,14 @@ static int trx_usrp_read(openair0_device *device, openair0_timestamp *ptimestamp
 #if defined(__x86_64) || defined(__i386__)
 #ifdef __AVX2__
   nsamps2 = (nsamps+7)>>3;
-  __m256i buff_tmp[4][nsamps2];
+  __m256i buff_tmp[cc<2 ? 2 : cc][nsamps2];
 #else
   nsamps2 = (nsamps+3)>>2;
-  __m128i buff_tmp[4][nsamps2];
+  __m128i buff_tmp[cc<2 ? 2 : cc][nsamps2];
 #endif
 #elif defined(__arm__)
   nsamps2 = (nsamps+3)>>2;
-  int16x8_t buff_tmp[4][nsamps2];
+  int16x8_t buff_tmp[cc<2 ? 2 : cc][nsamps2];
 #endif
 
   int rxshift;
@@ -645,44 +644,33 @@ static int trx_usrp_read(openair0_device *device, openair0_timestamp *ptimestamp
         rxshift=2;
         break;
      default:
-	AssertFatal(1==0,"Shouldn't be here\n");
-  }	
-  if (cc>1) {
-      // receive multiple channels (e.g. RF A and RF B)
-      std::vector<void *> buff_ptrs;
-
-     samples_received=0;
+       AssertFatal(1==0,"Shouldn't be here\n");
+  }
 
-      while (samples_received != nsamps) {
-        for (int i=0; i<cc; i++) buff_ptrs.push_back(buff_tmp[i]+samples_received);
-        samples_received += s->rx_stream->recv(buff_ptrs,nsamps-samples_received, s->rx_md);
+    samples_received=0;
+    while (samples_received != nsamps) {
 
+      if (cc>1) {
+      // receive multiple channels (e.g. RF A and RF B)
+        std::vector<void *> buff_ptrs;
 
-         if  ((s->wait_for_first_pps == 0) && (s->rx_md.error_code!=uhd::rx_metadata_t::ERROR_CODE_NONE))
-          break;
+        for (int i=0; i<cc; i++) buff_ptrs.push_back(buff_tmp[i]+samples_received);
 
-        if ((s->wait_for_first_pps == 1) && (samples_received != nsamps)) {
-          printf("sleep...\n"); //usleep(100);
-        }
-      }
-      if (samples_received == nsamps) s->wait_for_first_pps=0;
-   } else {
+        samples_received += s->rx_stream->recv(buff_ptrs, nsamps, s->rx_md);
+      } else {
       // receive a single channel (e.g. from connector RF A)
-      samples_received=0;
 
-      while (samples_received != nsamps) {
         samples_received += s->rx_stream->recv((void*)((int32_t*)buff_tmp[0]+samples_received),
                                                nsamps-samples_received, s->rx_md);
+      }
+      if  ((s->wait_for_first_pps == 0) && (s->rx_md.error_code!=uhd::rx_metadata_t::ERROR_CODE_NONE))
+        break;
 
-        if  ((s->wait_for_first_pps == 0) && (s->rx_md.error_code!=uhd::rx_metadata_t::ERROR_CODE_NONE))
-          break;
-
-        if ((s->wait_for_first_pps == 1) && (samples_received != nsamps)) {
-          printf("sleep...\n"); //usleep(100);
-        }
+      if ((s->wait_for_first_pps == 1) && (samples_received != nsamps)) {
+        printf("sleep...\n"); //usleep(100);
       }
-      if (samples_received == nsamps) s->wait_for_first_pps=0;
     }
+    if (samples_received == nsamps) s->wait_for_first_pps=0;
 
     // bring RX data into 12 LSBs for softmodem RX
     for (int i=0; i<cc; i++) {
@@ -1271,7 +1259,7 @@ extern "C" {
                    gain - gain_range.stop());
                gain=gain_range.stop();
       }
-          
+
       s->usrp->set_rx_gain(gain,i);
       LOG_I(HW,"RX Gain %d %f (%f) => %f (max %f)\n",i,
             openair0_cfg[0].rx_gain[i],openair0_cfg[0].rx_gain_offset[i],
@@ -1313,12 +1301,12 @@ extern "C" {
 
   LOG_I(HW,"rx_max_num_samps %zu\n",
         s->usrp->get_rx_stream(stream_args_rx)->get_max_num_samps());
-  
+
   for (int i = 0; i<openair0_cfg[0].rx_num_channels; i++) {
     LOG_I(HW,"setting rx channel %d\n",i);
     stream_args_rx.channels.push_back(i);
   }
-  
+
   s->rx_stream = s->usrp->get_rx_stream(stream_args_rx);
   uhd::stream_args_t stream_args_tx("sc16", "sc16");
 
diff --git a/targets/ARCH/rfsimulator/simulator.c b/targets/ARCH/rfsimulator/simulator.c
index 3bd4285cffc12f59d8190ccad89d7abf6d26bdc3..354709faa1c3fe87c3f9834bc3ae56ce05722c2a 100644
--- a/targets/ARCH/rfsimulator/simulator.c
+++ b/targets/ARCH/rfsimulator/simulator.c
@@ -618,8 +618,8 @@ static bool flushInput(rfsimulator_state_t *t, int timeout, int nsamps_for_initi
 }
 
 static int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimestamp, void **samplesVoid, int nsamps, int nbAnt) {
-  if (nbAnt != 1) {
-    LOG_W(HW, "rfsimulator: only 1 antenna tested\n");
+  if (nbAnt > 4) {
+    LOG_W(HW, "rfsimulator: only 4 antenna tested\n");
   }
 
   rfsimulator_state_t *t = device->priv;
@@ -736,14 +736,19 @@ 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
+
           sample_t *out=(sample_t *)samplesVoid[a];
           int nbAnt_tx = ptr->th.nbAnt;//number of Tx antennas
 
           //LOG_I(HW, "nbAnt_tx %d\n",nbAnt_tx);
           for (int i=0; i < nsamps; i++) {//loop over nsamps
             for (int a_tx=0; a_tx<nbAnt_tx; a_tx++) { //sum up signals from nbAnt_tx antennas
-              out[i].r+=ptr->circularBuf[((t->nextTimestamp+i)*nbAnt_tx+a_tx)%CirSize].r;
-              out[i].i+=ptr->circularBuf[((t->nextTimestamp+i)*nbAnt_tx+a_tx)%CirSize].i;
+              out[i].r += (short)(ptr->circularBuf[((t->nextTimestamp+i)*nbAnt_tx+a_tx)%CirSize].r*H_awgn_mimo[a][a_tx]);
+              out[i].i += (short)(ptr->circularBuf[((t->nextTimestamp+i)*nbAnt_tx+a_tx)%CirSize].i*H_awgn_mimo[a][a_tx]);
             } // end for a_tx
           } // end for i (number of samps)
         } // end of no channel modeling
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 00c92d75a224f124aa43268f6701cbb49cd3f5b8..ac1f36c8b753bafe14321adc0ceeec865f851f3d 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
@@ -1,4 +1,4 @@
-Active_gNBs = ( "gNB-Eurecom-DU");
+Active_gNBs = ( "gNB-Eurecom-5GNRBox");
 # Asn1_verbosity, choice in: none, info, annoying
 Asn1_verbosity = "none";
 
@@ -7,7 +7,7 @@ gNBs =
  {
     ////////// Identification parameters:
     gNB_ID    =  0xe00;
-    gNB_name  =  "gNB-Eurecom-DU";
+    gNB_name  =  "gNB-Eurecom-5GNRBox";
 
     // Tracking area code, 0x0000 and 0xfffe are reserved values
     tracking_area_code  =  1;
@@ -142,7 +142,7 @@ gNBs =
 
         initialULBWPk2_1                      = 6;  # used for mixed slot
         initialULBWPmappingType_1             = 1;
-        initialULBWPstartSymbolAndLength_1    = 69; # this is SS=0 L=12
+        initialULBWPstartSymbolAndLength_1    = 52; # this is SS=10 L=4
 
         initialULBWPk2_2                      = 7;  # used for Msg.3 during RA
         initialULBWPmappingType_2             = 1;
@@ -225,11 +225,12 @@ gNBs =
 );
 
 MACRLCs = (
-	{
-	num_cc = 1;
-	tr_s_preference = "local_L1";
-	tr_n_preference = "local_RRC";
-        }
+    {
+        num_cc = 1;
+        tr_s_preference = "local_L1";
+        tr_n_preference = "local_RRC";
+        ulsch_max_slots_inactivity = 100;
+    }
 );
 
 L1s = (
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 bd0678e344c5e37d7fb9ed4a711ff053af8c0bff..1bada161a1b26b3644b4ca414877604e420da50c 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
@@ -1,4 +1,4 @@
-Active_gNBs = ( "gNB-Eurecom-DU");
+Active_gNBs = ( "gNB-Eurecom-5GNRBox");
 # Asn1_verbosity, choice in: none, info, annoying
 Asn1_verbosity = "none";
 
@@ -7,7 +7,7 @@ gNBs =
  {
     ////////// Identification parameters:
     gNB_ID    =  0xe00;
-    gNB_name  =  "gNB-Eurecom-DU";
+    gNB_name  =  "gNB-Eurecom-5GNRBox";
 
     // Tracking area code, 0x0000 and 0xfffe are reserved values
     tracking_area_code  =  1;
@@ -142,7 +142,7 @@ gNBs =
 
         initialULBWPk2_1                      = 6;  # used for mixed slot
         initialULBWPmappingType_1             = 1;
-        initialULBWPstartSymbolAndLength_1    = 69; # this is SS=0 L=12
+        initialULBWPstartSymbolAndLength_1    = 52; # this is SS=10 L=4
 
         initialULBWPk2_2                      = 7;  # used for Msg.3 during RA
         initialULBWPmappingType_2             = 1;
@@ -225,11 +225,12 @@ gNBs =
 );
 
 MACRLCs = (
-	{
-	num_cc = 1;
-	tr_s_preference = "local_L1";
-	tr_n_preference = "local_RRC";
-        }
+    {
+        num_cc = 1;
+        tr_s_preference = "local_L1";
+        tr_n_preference = "local_RRC";
+        ulsch_max_slots_inactivity = 100;
+    }
 );
 
 L1s = (
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
new file mode 100644
index 0000000000000000000000000000000000000000..9402e354fe8741bdbd02b303b77bb9a465fbf8a9
--- /dev/null
+++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.sabox.conf
@@ -0,0 +1,326 @@
+Active_gNBs = ( "gNB-Eurecom-5GNRBox");
+# Asn1_verbosity, choice in: none, info, annoying
+Asn1_verbosity = "none";
+
+gNBs =
+(
+ {
+    ////////// Identification parameters:
+    gNB_ID    =  0xe00;
+
+    cell_type =  "CELL_MACRO_GNB";
+    gNB_name  =  "gNB-Eurecom-5GNRBox";
+
+    // Tracking area code, 0x0000 and 0xfffe are reserved values
+    tracking_area_code  =  1;
+    plmn_list = ({
+                  mcc = 450;
+                  mnc = 05;
+                  mnc_length = 2;
+                  snssaiList = (	
+                    {	     
+                      sst = 1;
+                      sd  = 0xd143a5; // 0 false, else true
+                    }
+                  );
+
+                  });
+ 
+    tr_s_preference     = "local_mac"
+
+    ////////// Physical parameters:
+
+    ssb_SubcarrierOffset                                      = 0;
+    pdsch_AntennaPorts                                        = 1;
+    pusch_AntennaPorts                                        = 1;
+
+     pdcch_ConfigSIB1 = (
+      {
+        controlResourceSetZero = 12;
+        searchSpaceZero = 0;
+      }
+      );
+
+    servingCellConfigCommon = (
+    {
+ #spCellConfigCommon
+
+      physCellId                                                    = 0;
+
+#  downlinkConfigCommon
+    #frequencyInfoDL
+      # this is 3600 MHz + 43 PRBs@30kHz SCS (same as initial BWP)
+      absoluteFrequencySSB                                             = 641280;
+      dl_frequencyBand                                                 = 78;
+      # this is 3600 MHz
+      dl_absoluteFrequencyPointA                                       = 640008;
+      #scs-SpecificCarrierList
+        dl_offstToCarrier                                              = 0;
+# subcarrierSpacing
+# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
+        dl_subcarrierSpacing                                           = 1;
+        dl_carrierBandwidth                                            = 106;
+     #initialDownlinkBWP
+      #genericParameters
+        # this is RBstart=27,L=48 (275*(L-1))+RBstart
+        initialDLBWPlocationAndBandwidth                               = 12952; # 6366 12925 12956 28875 12952
+# subcarrierSpacing
+# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
+        initialDLBWPsubcarrierSpacing                                   = 1;
+      #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
+      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                            = 12952;
+# subcarrierSpacing
+# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
+        initialULBWPsubcarrierSpacing                               = 1;
+      #rach-ConfigCommon
+        #rach-ConfigGeneric
+          prach_ConfigurationIndex                                  = 98;
+#prach_msg1_FDM
+#0 = one, 1=two, 2=four, 3=eight
+          prach_msg1_FDM                                            = 0;
+          prach_msg1_FrequencyStart                                 = 0;
+          zeroCorrelationZoneConfig                                 = 13;
+          preambleReceivedTargetPower                               = -96;
+#preamblTransMax (0...10) = (3,4,5,6,7,8,10,20,50,100,200)
+          preambleTransMax                                          = 6;
+#powerRampingStep
+# 0=dB0,1=dB2,2=dB4,3=dB6
+        powerRampingStep                                            = 1;
+#ra_ReponseWindow
+#1,2,4,8,10,20,40,80
+        ra_ResponseWindow                                           = 4;
+#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR
+#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen
+        ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR                = 4;
+#oneHalf (0..15) 4,8,12,16,...60,64
+        ssb_perRACH_OccasionAndCB_PreamblesPerSSB                   = 14;
+#ra_ContentionResolutionTimer
+#(0..7) 8,16,24,32,40,48,56,64
+        ra_ContentionResolutionTimer                                = 7;
+        rsrp_ThresholdSSB                                           = 19;
+#prach-RootSequenceIndex_PR
+#1 = 839, 2 = 139
+        prach_RootSequenceIndex_PR                                  = 2;
+        prach_RootSequenceIndex                                     = 1;
+        # SCS for msg1, can only be 15 for 30 kHz < 6 GHz, takes precendence over the one derived from prach-ConfigIndex
+        #
+        msg1_SubcarrierSpacing                                      = 1,
+# restrictedSetConfig
+# 0=unrestricted, 1=restricted type A, 2=restricted type B
+        restrictedSetConfig                                         = 0,
+
+      # 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;
+
+# 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;
+    };
+
+
+    ////////// MME parameters:
+    amf_ip_address      = ( { ipv4       = "192.168.5.233";
+                              ipv6       = "192:168:30::17";
+                              active     = "yes";
+                              preference = "ipv4";
+                            }
+                          );
+
+    ///X2
+    enable_x2 = "no";
+    t_reloc_prep      = 1000;      /* unit: millisecond */
+    tx2_reloc_overall = 2000;      /* unit: millisecond */
+    t_dc_prep         = 1000;      /* unit: millisecond */
+    t_dc_overall      = 2000;      /* unit: millisecond */
+    target_enb_x2_ip_address      = (
+                                     { ipv4       = "CI_FR1_CTL_ENB_IP_ADDR";
+                                       ipv6       = "192:168:30::17";
+                                       preference = "ipv4";
+                                     }
+                                    );
+
+    NETWORK_INTERFACES :
+    {
+        GNB_INTERFACE_NAME_FOR_NG_AMF            = "eth0";
+        GNB_IPV4_ADDRESS_FOR_NG_AMF              = "192.168.5.200/24";
+        GNB_INTERFACE_NAME_FOR_NGU               = "eth0";
+        GNB_IPV4_ADDRESS_FOR_NGU                 = "192.168.5.200/24";
+        GNB_PORT_FOR_S1U                         = 2152; # Spec 2152
+        GNB_IPV4_ADDRESS_FOR_X2C                 = "192.168.5.200/24";
+        GNB_PORT_FOR_X2C                         = 36422; # Spec 36422
+    };
+
+  }
+);
+
+MACRLCs = (
+	{
+	num_cc = 1;
+	tr_s_preference = "local_L1";
+	tr_n_preference = "local_RRC";
+        }
+);
+
+L1s = (
+    {
+	num_cc = 1;
+	tr_n_preference = "local_mac";
+	pusch_proc_threads = 8;
+    }
+);
+
+RUs = (
+    {
+       local_rf       = "yes"
+         nb_tx          = 1
+         nb_rx          = 1
+         att_tx         = 0
+         att_rx         = 0;
+         bands          = [7];
+         max_pdschReferenceSignalPower = -27;
+         max_rxgain                    = 114;
+         eNB_instances  = [0];
+         #beamforming 1x4 matrix:
+         bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000];
+         clock_src = "internal";
+    }
+);
+
+THREAD_STRUCT = (
+  {
+    #three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT"
+    parallel_config    = "PARALLEL_SINGLE_THREAD";
+    #two option for worker "WORKER_DISABLE" or "WORKER_ENABLE"
+    worker_config      = "WORKER_ENABLE";
+  }
+);
+
+rfsimulator :
+{
+    serveraddr = "server";
+    serverport = "4043";
+    options = (); #("saviq"); or/and "chanmod"
+    modelname = "AWGN";
+    IQfile = "/tmp/rfsimulator.iqs";
+};
+
+     log_config :
+     {
+       global_log_level                      ="info";
+       global_log_verbosity                  ="medium";
+       hw_log_level                          ="info";
+       hw_log_verbosity                      ="medium";
+       phy_log_level                         ="info";
+       phy_log_verbosity                     ="medium";
+       mac_log_level                         ="info";
+       mac_log_verbosity                     ="high";
+       rlc_log_level                         ="info";
+       rlc_log_verbosity                     ="medium";
+       pdcp_log_level                        ="info";
+       pdcp_log_verbosity                    ="medium";
+       rrc_log_level                         ="info";
+       rrc_log_verbosity                     ="medium";
+       ngap_log_level                         ="debug";
+       ngap_log_verbosity                     ="medium";
+    };
+